Jump to main content

CSS :target

  • Published:
  • Category: CSS

:target Acquired…

The :target pseudo-class has been available for quite some time, but I’ve rarely seen anyone use it creatively aside from this one great example by @vasilis.

For many of the major browsers, they’ve supported :target for since their 1.x releases. Opera first introduced support for it in their 9.5 release, while Internet Explorer didn’t have support for it until version 9 (shocking right?)

Enough background… how’s it work?

To get the :target pseudo-class to work, you need to do the following:

First you must create an element that has a unique ID to it. This is the parent element that you will be manipulating using :target.

Next you’ll need a way to trigger the URI that contains a fragment Identifier (to match your ID). You’ll likely do this with an anchor element.

<a href="#example">Example Anchor</a>

<div id="example">
  <!-- stuff goes here -->

So, when a user clicks or presses the anchor set to #example, the following fragment identifier gets appended to the URI:


So what would I use this for?

There are lots of things that this pseudo-class would be handy for. Like instead of just jumping a user to a particular area, how about the whole area becomes a modal or the rest of the site’s content gets a lower opacity to drive extra focus to the desired area.

Depending on how intricate you want to get, you could potentially even revise large parts of the site’s design based on different :target styles.

For instance:

<body id="one">
  <div id="two">
    <div id="three">

A bit of &lt;div> soup there. But the reason being that, depending on which URI was currently in effect, the color scheme, background image, heck even the entire layout of the site could be altered.

And there's a reason not to use it...

Because the URI is how the :target styles gets triggered, if a user hits the back button of their browser, they’re not going to go back a page, but instead go back through the # fragments that were added to the URI.

If you know users are constantly using the back button to navigate to and from areas of your site, this likely wouldn’t be optimal for you.

It’ll be up to you whether you find any practical use for :target or not.

As for me, I’m going to use it to make silly CSS animation demos.

See the Pen :target cat by Scott (@scottohara) on CodePen.

Updated: June 2nd 2014

And just one more thing...

So I’ve already received some feedback to this article (thank you!) and one thing people were asking about was if I could go over the demo a bit more.

Sure thing!

The entire cat ‘illustration’ is contained within a single &lt;div> with it’s ID set to cat. I need that not for assigning CSS to, but rather for the &lt;a> to point to.

<div class="container" id="cat">

  <a href="#cat" class="words small">meow</a>
  <a href="#grow_up" class="words big">unmeow</a>

  <div class="head">
    <div class="head--inner-ears"></div>

    <div class="head--inner">
      <div class="head--nose-eyes"></div>
      <div class="head--whiskers"></div>

      <div class="head--mouth__outer">
        <div class="head--mouth__inner"></div>


  <div class="body">
    <div class="body--arm__left"></div>
    <div class="body--arm__right"></div>
    <div class="body--leg__left"></div>
    <div class="body--leg__right"></div>
    <div class="body--tail"></div>


It may look kinda ‘divy’ but I think I’ve used the least amount of mark-up possible to make the cat.

I’m heavily relying on ::before and ::after pseudo-elements for things like the eyes, some of the whiskers, parts of the arms and tail.

I used Sass while creating this demo, and heavily used silent classes that contained lots of CSS I would have otherwise had to write multiple times.

These animation mixins were super helpful in letting me write out my animation keyframes once and not having to worry about all the vendor prefixes.

  CSS Animation Mixins
  Derived from: gist.github.com/Integralist/3931680

$browsers: -moz-, -ms-, -webkit-, "";

  Setup for animation w/out keyframes
@mixin animation ($animation-values... ) {
  @each $b in $browsers {
    #{$b}animation: $animation-values;

  Setup for keyframes
@mixin keyframe($animation-name) {
  @-moz-keyframes #{$animation-name} {

  @-ms-keyframes #{$animation-name} {

  @-webkit-keyframes #{$animation-name} {

  @keyframes #{$animation-name} {

  Create CSS keyframe animations for
  all vendors in one go, e.g.:

.foo {
 @include animation(10s 5s name);

@include keyframe(name) {
  from {
    font-size: 1em;

  to {
    font-size: 5em;

For the rest of it all, I’m really just using simple shapes made of rectangles, triangles for the ears, squares and circles made via really high border-radius values.

Check out the source through the codepen demo.