CSS3 content slider with the :target pseudo-class

CSS3 introduced the dynamic :target pseudo-class a couple of years ago. This selector allows us to match an element when it's the target of an anchor previously set on a link. With the aim of CSS3 transitions we can add some additional effects to the targeted element once it's selected. A typical use case is a pure CSS3 content slider. Let's see the details.

We have the following HTML structure:

<div id="slider">
    <div class="slide" id="s1">Slide 1</div>
    <div class="slide" id="s2">Slide 2</div>
    <div class="slide" id="s3">Slide 3</div>
    <div class="slide" id="s4">Slide 4</div>
    <div class="slide" id="s5">Slide 5</div>
</div>
<div id="controls">
    <a href="#s1">1</a>
    <a href="#s2">2</a>
    <a href="#s3">3</a>
    <a href="#s4">4</a>
    <a href="#s5">5</a>
</div>

As you can see, each navigation link points to a different slide thanks to the anchor set on each slide. This means that each slide is the target of the corresponding navigation link.

If you see the above structure in a browser without styles, you'll probably notice that a default behavior is already present on the page: the browser scrolls the main window once a link is clicked.

Now we have to add some basic styles to our slider just to make it look as a slider:

#slider {
    width: 500px;
    height: 300px;
    margin: 2em auto;
    position: relative;
    border: 4px solid #bbb;
    overflow: hidden;
    box-shadow: 2px 2px 2px #ddd;
}

div.slide {
    width: 500px;
    height: 300px;
    text-align: center;
    position: absolute;
    top: 0;
    background: #ccc;
    line-height: 300px;
    font-size: 2em;
    -moz-transition: all 1s ease-in-out;
    -webkit-transition: all 1s ease-in-out;
    -o-transition: all 1s ease-in-out;
    -ms-transition: all 1s ease-in-out;
    transition: all 1s ease-in-out;
    opacity: 0;
}

#s1 {
    left: 0;
}

#s2 {
    left: 500px;
}

#s3 {
    left: 1500px;
}

#s4 {
    left: 2000px;
}

#s5 {
    left: 2500px;
}

#controls {
    margin: 1em 0;
    text-align: center;
}

#controls a {
    display: inline-block;
    width: 32px;
    height: 32px;
    margin-right: 5px;
    background: #000;
    color: #fff;
    text-decoration: none;
    border-radius: 50%;
    line-height: 32px;
}

We've registered a CSS3 transition on each slide. Now we have to activate it when the current slide is matched by the :target pseudo-class by changing its opacity and left offset:

div.slide:target {
    left: 0;
    opacity: 1;
    z-index: 10;
}

Targeting an element is a transient state, meaning that the attached styles will be reset every time a new target is selected. In fact, once a link is clicked our styles will be added only to the current slide. You can see the demo below.

Demo

Live demo

Back to top