LearnTriggering CSS Animations with Sibling Selectors

Guil Hernandez
writes on July 3, 2013

Combinators describe the relationship between CSS selectors, and they’re commonly used to combine two or more selectors into a more specific selector. Examples of combinators are the greater-than sign (>), plus sign (+), and tilde symbol (~). If you’ve ever worked with descendant selectors, then you’ve already used combinators because the whitespace between the selectors is also considered a combinator.

There are three other types of selectors that use combinators: child selectors, adjacent sibling selectors, and general sibling selectors. When combined with one of the UI element states pseudo-classes, we can trigger events that would otherwise require jQuery, with simple CSS.

In this article, we’ll learn how to trigger CSS animations using the two sibling selectors.

Getting Started

I created a fun “Tortoise and the Hare” CSS animation using the following elements:

<input class="go" type="checkbox">
<img class="tortoise" src="images/tortoise.png" alt="The irate tortoise">
<img class="hare" src="images/hare.png" alt="The boastful hare">
<div class="road"></div>

I’ve already defined the keyframe animation sequences and attached them to their respective selectors: .tortoise, .hare, and .road. To view and learn more about the CSS used to create these animations, take a look at the style sheet.

Currently, the animations are immediately triggered by the browser because by default, CSS animations run as soon as the page loads. We want the animations to play only when triggered by a user action––like clicking a button.

Next, we’ll focus on the element states and sibling selectors needed to trigger our animations. But before we begin, let’s quickly go over how sibling selectors work.

Adjacent Sibling Selector

The adjacent sibling selector uses the plus sign (+) combinator to target an element’s immediate sibling.

The following will target only those paragraphs immediately following an h2:

h2 + p {
  color: red;
  font-weight: bold;
}

adj-sibling

General Sibling Selector

The general sibling selector uses the tilde symbol (~) as its combinator to target every specified sibling that follows an element. It’s very similar to the adjacent sibling selector. The difference is that the elements can appear anywhere after the first sibling.

For example, this will target every sibling paragraph that follows an h2:

h2 ~ p {
  color: red;
  font-weight: bold;
}

general-sibling

What will Trigger the Animations?

Since we’re not using any jQuery, we’ll need a state (or event) similar to jQuery’s .click() event to trigger our animations.

For this purpose, the :checked pseudo-class is useful because the :checked state of a checkbox can be altered by user action––it can be toggled on and off, and we’re able to target sibling elements based on whether or not the box is checked. Perfect!

I carefully styled the checkbox element to look and work like a button that toggles its text and background colors when clicked.

button

The button’s text and background gradients were added and styled as generated content using the :after pseudo-element. Check out how it was done.

Using the Adjacent Sibling Selector

We’ll need each animation to play on the :checked state––or when the button is clicked, so let’s create the selector to make this happen.

The checkbox has the class name “go”, so we’ll need to add the :checked pseudo-class to the .go selector:

.go:checked + .tortoise {
  -webkit-animation: go-tortoise 6s 1 1.3s ease-in-out forwards;
}

This selector binds the go-tortoise animation sequence to the adjacent tortoise image on :checkedView it in CodePen.

Since the hare and road elements are not immediate siblings of the checkbox, the browser is unable to target them with an adjacent sibling selector.

Using the General Sibling Selector

To target the hare image we’ll need to use a general sibling selector.

.go:checked ~ .hare {
  -webkit-animation: go-hare 6.4s 1  1.3s linear forwards,
                     hare-hop .6s 11 1.3s ease-in-out;
}

This selector binds the go-hare and hare-hop animation sequences to any sibling with the class hareView it in CodePen.

With the general sibling selector we’re able to trigger animations for any siblings that follow the checkbox, so we’ll create another selector that binds the move-road and rotate-road animations to the .road selector.

This will animate the background image and add a 3D perspective to the page.

.go:checked ~ .road {
  -webkit-animation: move-road 6s 1  1.3s ease-in-out forwards,
                     rotate-road 1s forwards;
}

We can even target pseudo-elements in the latest browsers. The following selector will trigger a delayed animation that tells us who the winner is.

.go:checked ~ .road:after {
  -webkit-animation: winner 1s 7s forwards;
}

View the final animation in CodePen

Conclusion

Support for sibling selectors looks good, as all majors browsers support them. The general sibling selector is also supported––although buggy––in IE7+ and the adjacent sibling selector works in IE8+. The :checked pseudo-class, however, lacks support in IE8 and below.

To learn more about CSS animations, check out my CSS Animations Deep Dive on Treehouse.

7 Responses to “Triggering CSS Animations with Sibling Selectors”

  1. Late to the game here, but here’s a forked version with all the code necessary:

    http://codepen.io/impressivewebs/pen/rfacC

    I have a tool that automatically creates all the necessary code, if you start from just Webkit:

    http://animationfillcode.com/

    So I was able to fix the code in a matter of seconds. 🙂

  2. Mike Badgley on July 22, 2013 at 2:43 pm said:

    What a clever idea. I love when something like this can be accomplished purely with CSS instead of having to rely on JS. Nice work.

  3. Omar Zeidan on July 4, 2013 at 6:52 pm said:

    Yes @matask:disqus , you`re right, it should work on all major browser, specially things like simple keyframes animation! but am sure it was just as a simple demo and just to let you know the idea.

    Whatever, just a little advice, ask, but GOOGLE it first, and try to know how, and why?
    That what makes you special.

    Love..

  4. Guest on July 4, 2013 at 6:48 pm said:

    Yes @matask:disqus, you`re right, it should work on all major browser, specially things like simple keyframes animation! but am sure it was just as a simple demo and just to let you know the idea.

    Whatever, just a little advice, ask, but GOOGLE it first, and try to know how, and why?
    That what makes you special.

    Love.

  5. Matas K on July 3, 2013 at 2:48 pm said:

    I don’t get it why stuff like this do not work on latest Firefox. It worked on Chrome and Opera though.

    • stopsatgreen on July 3, 2013 at 7:40 pm said:

      It doesn’t work on Firefox because he’s used only -webkit- properties. If those are removed, the animations work in *all* browsers. Choosing -webkit- properties has actively broken the animation in Firefox and IE.

Leave a Reply

You must be logged in to post a comment.

Want to learn more about CSS?

Learn how CSS allows you to apply visual styling to HTML elements with colors, fonts, layouts, and more.

Learn more