Video

Want to see the full-length video right now for free?

Notes

Historically, developers and designers have reached for JavaScript to build certain presentational features such as animations and transitions. With modern CSS features, some of these capabilities can now be achieved with little to no JavaScript. Reducing the JavaScript employed by your application can result in improved performance and helps establish a cleaner division between behavior and presentation concerns in your applications and pages.

Animations

(This [Codepen][codepen] has the JavaScript and CSS Connie uses in the first examples in the video.)

Behavior driven by hovering over an element can implemented through CSS. The [CSS transition property][transition-property] is ideal for moving between two states. Here we can use it to specify how the browser will present the transition from a green background (unhovered) to a red background (hovered).

.box {
  border: 1px gray solid;
  height: 100px;
  margin-bottom: 1em;
  width: 100px;

  transition: all ease-in-out 0.5s;
}

.box.box-background {
  background-color: lime;

  &:hover {
    background-color: red;
  }
}

Note, with transition: all, we're specifying that we want all transitionable properties to be transitioned using the same pacing and timing. We can also specify the transition for a single property, e.g. transition opacity ease-in-out 1s and likewise we can have multiple transition declarations to target distinct properties as needed.

The ease-in-out is an easing function that specifies the rate of change across the total transition time (0.5 seconds). There are several [provided easing functions][easing], but you can also write your own. Here the parameters of any state transition are handled at the general .box class, and more specific classes merely need to specify the two end states, inheriting the transitioning definition.

Transitions can be defined with greater granularity if various states require different transition parameters. Here we set opacity to use the ease-in-out easing function over half a second, and transforms to use a linear (steady) transition over a full second.

.box {
  transition: opacity ease-in-out 0.5s,
              transform linear 1s;
}

[codepen]: http://codepen.io/conchan/pen/xOPZjB [transition-property]: https://developer.mozilla.org/en-US/docs/Web/CSS/transition [easing]: http://easings.net/

Using Some JavaScript

Using more CSS to implement your presentation doesn't mean that JavaScript doesn't play an important role in a well-factored design. In this example, we're using JavaScript to connect a click on a button to toggling the styling on an element.

var button = $(".button"),
    box = $(".box-size");

button.on("click", function() {
  box.toggleClass("is-bigger");
});

(We're using jQuery here for brevity, but you could do this with vanilla JavaScript.) Here the JavaScript is only used to connect the click action to a change, not to implement any of the presentation changes that gets triggered. The browser responds to the class addition or subtraction by applying the styles dictated by the class. Often this strategy can be more performant, as CSS transitions will leverage the browsing computer's GPU for certain kinds of expensive transitions and demand less of the computer than a jQuery-based approach that might involve more calculation.

Definining More Granular Transitions

CSS transitions allow the definition of the transition from one state to another, but they are limited to a single event, timing window, and easing function. CSS animations allow for the definition of keyframes that can specify multi-step transitions.

This style from Connie's profile site defines keyframes that implement the zooming out and sweeping away of the pages of her portfolio as the user moves from page to page.

.page-visible {
      animation: zoomIn 2s $ease-out-quad forwards;
      animation-delay: ($page-transition-duration / 2);
      transform: translate3d(calc(100% + #{$page-spacing}), 0, 0) scale(0.5);
      z-index: $z-reset;
}

@keyframes zoomIn {
  0% {
    transform: translate3d(calc(100% + #{$page-spacing}), 0, 0) scale($page-scaled-size);
  }

  50% {
    transform: translate3d(0, 0, 0) scale($page-scaled-size);
  }

  100% {
    transform: scale(1);
  }
}

Other avenues for CSS over JavaScript

Boston designer Cristina Silva's wrote a [blog post][you-dont-need-javascript-for-that] describing some other situations you might be able to swap out JavaScript for a more CSS-based solution:

  • tooltips
  • dropdown menus
  • toggling visibility

Accessibility Concerns

Favoring a CSS-based approach over a more JavaScript-heavy approach can provide benefits in browser performance and cleaner code, but there may be drawbacks in your implementation with regard to accessibility. For example, screen readers may read unintended content on the page that is hidden from sight but is present in the DOM.

Resources for Further Investigation

  • Cristina Silva's aptly-named post on our blog: [You Don't Need JavaScript for That][you-dont-need-javascript-for-that]
  • Sara Soueidan's [posts for the Adobe Dreamweaver blog on animations][adobe-dreamweaver-animations]
  • [@NamPNQ's repository with examples][nampnq-examples]

[you-dont-need-javascript-for-that]: https://robots.thoughtbot.com/you-don-t-need-javascript-for-that [adobe-dreamweaver-animations]: https://blogs.adobe.com/dreamweaver/author/sara-soueidan [nampnq-examples]: https://github.com/NamPNQ/You-Dont-Need-Javascript