Tag: libraries

Libraries for SVG Drawing Animations

In 2013, Jake Archibald introduced this cool trick of animating an SVG path to look like it’s drawing itself. It’s 2020 now, and the trick is still popular. I’ve seen it on a lot of websites I’ve visited recently. I, too, feature an animated SVG loader on my website using one of the libraries I’ll introduce below.

In a previous article, Chris Coyier wrote about how SVG path animations work under the hood, using the CSS stroke-dasharray and stroke-dashoffset properties. In this article, I want to introduce you to four JavaScript libraries that can be used to create SVG path drawing animations with fewer lines of code, like this cool example. Why a library? Because they’re ideal for complex animations involving two or more SVGs with multiple paths.

To get started, l’ll first secure an SVG to demo. Let’s use this castle from svgrepo. The castle SVG downloads as an SVG image. But, since we’re dealing with path animation, what we need is the code format of the SVG. To get this, I’ll import the file into Figma and use the “Copy as SVG” feature (Right Click → Copy/Paste → Copy as SVG) to grab the SVG code.

To successfully animate an SVG path, the SVG shape should have a fill of none and each individual SVG path must have a stroke (we’ll set it to #B2441D) and a stroke-width (set to 2px).

The animation effect we want to create is to first draw the outline (or stroke) of the SVG and then fill in the different colors. In total, there are six different fill colors used throughout the SVG, so we’ll remove the fill color from each path and give paths of the same color the same class name.

  • #695A69: color-1
  • #B2441D: color-2
  • #DFDOC6: color-3
  • #C8B2A8: color-4
  • #DE582A: color-5
  • #AO8A8A: color-6

After all the modifications, here’s what the SVG code looks like:

 <svg id="svg-castle" width="480" height="480" viewBox="0 0 480 480" fill="none" xmlns="http://www.w3.org/2000/svg">   <path d="M231.111 183.761V150.371C231.111 149.553 231.774 148.889 232.592 148.889H24  7.407C248.225 148.889 248.889 149.552 248.889 150.371V183.761L258.342 206.667H271.111  V135.556H240H208.889V206.667H221.658L231.111 183.761Z" stroke="#B2441D" stroke-width="2px" class="color-6" />   <path d="M311.111 420H288.889V455.556V468.889H311.111V455.556V420Z" stroke="#B2441D"   stroke-width="2px" class="color-1" />   <path d="M191.111 420H168.889V455.556V468.889H191.111V455.556V420Z" stroke="#B2441D" stroke-width="2px" class="color-1" />   <path d="M168.889 220V228.889V237.778H222.222V228.889H212.487L221.658 206.667H208.88   9H169.524L177.778 220H168.889Z" stroke="#B2441D" stroke-width="2px" class="color-2"/ >   <!-- etc. --> </svg>

That’s all the SVG preparation we need. Let’s look at how to achieve the desired animation with the different libraries.

Library 1: Vivus

Vivus is a lightweight JavaScript class (with no dependencies) that allows you to animate SVGs like they’re being drawn. The library is available using any of these options. To keep things simple, we’ll use a CDN link:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js" integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ==" crossorigin="anonymous"></script>

Next, let’s create a new Vivus instance. It takes three arguments:

  1. The ID of the target element (the SVG)
  2. An options object with a dozen possible values
  3. A callback function that runs at the end of the animation

Looking back at our SVG code, the SVG ID is svg-castle.

new Vivus('svg-castle', {    duration: 200, type:'oneByOne' });

Now, let’s write a callback function that fills the paths with the different colors we’ve defined:

function fillPath(classname, color) {   const paths = document.querySelectorAll(`#svg-castle .$ {classname}`);   for (path of paths){     path.style.fill = `$ {color}`;   } }

The fillPath function selects all paths in the svg-castle element with the supplied classname, loops through and fills each path with the specified color. Remember in a previous step, we removed the fill from each path and gave each path a same fill class (color-1, color-2, etc.).

Next up, we call the fillPath function for the six different classnames and their corresponding colors:

function after() {   fillPath('color-1', '#695a69');   fillPath('color-2', '#b2441d');   fillPath('color-3', '#dfd0c6');   fillPath('color-4', '#c8b2a8');   fillPath('color-5', '#de582a');   fillPath('color-6', '#a08a8a') }

That’s the callback function passed to the Vivus instance. See Pen for full implementation.

Library 2: Walkway.js

Walkway is a light-weight SVG animation library for path, line and polygon elements. To start using it, we can either add the library using npm, yarn, or with a CDN link like we did with Vivus. We’ll go with the CDN link once again:

<script src="https://cdn.jsdelivr.net/npm/walkway.js/src/walkway.min.js"></script>

With Walkway, we create a new Walkway instance, passing an options object as an argument. Then, we call the draw method on the new instance and pass in an optional callback function which will be run at the end of the draw animation. Again, very much like Vivus.

We’ve already written the after callback function in the previous example, so the rest should be a piece of cake:

const svg = new Walkway({   selector: '#svg-castle',   duration: 3000, });  svg.draw(after);

Library 3: Lazy Line Painter

Lazy Line Painter is a modern JavaScript library for SVG path animation. It requires minimal code to setup. However, if a GUI is more of your thing, you can use the Lazy Line Composer which is a free online editor for SVG path animation from the same makers. The SVG will be exported as an animated SVG file that can be used directly anywhere.

The basic setup for Lazy Line Painter is similar to what we’ve already done in the other examples. First, get the library using either npm or a CDN link. Just like the previous examples, we’ll use a CDN link:

<script src="https://cdn.jsdelivr.net/npm/lazy-line-painter@1.9.4/lib/lazy-line-painter-1.9.4.min.js"></script>

Then, we initialize a new LazyLinePainter instance, which accepts two parameters — a selector (the ID of the target SVG element) and a config object. Let’s call the paint method on the new instance:

// select the svg by id let svg = document.querySelector('#svg-castle')  // define config options let options = {   strokeDash: '2, 2', } // initialize new LazyLinePainter instance let myAnimation = new LazyLinePainter(svg, options)  // call the paint method myAnimation.paint()

A full list of config options are available in the library docs. Unlike the previous libraries, we don’t pass a callback function to the paint method. Instead, we’ll listen for the complete:all event handler on the animation and then pass in the callback function.

myAnimation.on('complete:all', (event) => {after()});

We can also control when the paint method runs using event listeners like we’ve have done in the following codepen demo. Click on the castle to re-run the animation.

Library 4: Framer Motion

Framer Motion is a bit different from other libraries we’ve covered. It’s a production-ready open-source animation library for React components with tons of possible animation types. And, yes, this is from the same team behind the popular Framer prototyping tool.

First up, we’ll install the library with npm in the terminal:

npm install framer-motion

For SVG path drawing animations, Framer Motion provides a motion.path component that takes four props:

<motion.path   d={pathDefinition}   initial={{ pathLength: 1, pathOffset: 0 }}   animate={{ pathLength: 0, pathOffset: 1 }}   transition={{ duration: 2 }} />

To use it, we’ll simply convert our SVG paths to motion.path, like this:

import React from 'react'; import { motion } from "framer-motion"; const AnimatedCastle = () => {   return (     <svg id="svg-castle" width="480" height="480" viewBox="0 0 480 480" fill="non            e" xmlns="http://www.w3.org/2000/svg">       <motion.path d="M311.111 420H288.889V455.556V468.889H311.111V455.556V420Z"              stroke="#B2441D" stroke-width="2" className="color-1"        initial={{ pathLength: 1,fill:"none", opacity:0, }}        animate={{ pathLength: 0,fill:"695A69", opacity:1 }}        transition={{ duration: 2 }}       />       <motion.path d="M191.111 420H168.889V455.556V468.889H191.111V455.556V420Z"                stroke="#B2441D" stroke-width="2" className="color-2"         initial={{ pathLength: 1, fill:"none", opacity:0, }}         animate={{ pathLength: 0, fill:"#b2441d", opacity:1}}         transition={{ duration: 3 }}       />                 <!-- etc. -->     </svg>   ) }

This has to be done for each SVG path. See this demo for full implementation:

There’s a caveat though: the castle SVG has over 60 paths, which is a lot. Going through them was quite daunting for me, and I found the process to be repetitive and prone to errors. For that reason, I don’t recommend Framer Motion but I would say that it is well suited for SVGs within React components with no more than five paths. For anything more than that, go with any of the previous libraries we covered.


That’s a look at four JavaScript libraries we can use to get hand-drawn SVG effects.

Why didn’t we cover a CSS-only solution? While it’s possible to do, it involves a lot of code repetition. For example, it means finding the total length of each path using JavaScript or with this cool trick that sets each path length to 1, and then sets the stroke-dasharrray and stroke-dashoffset of each path to its path length.

After that, we still need to define keyframes to animate the stroke-dashoffset to zero. Then, those keyframe animations will be added to each path and with an animation-delay to offset things a bit. We also have to write six different keyframe rules to fill the paths with their respective colors. Considering that the castle has over 60 individual paths, that’s over 100 lines of CSS! Not exactly the most efficient or straightforward approach.

The post Libraries for SVG Drawing Animations appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, ,

Import Non-ESM libraries in ES Modules, with Client-Side Vanilla JS

We’re living through a weird era where there are tons of JavaScript libraries that were meant to be used as <script> tags that expose available globals. AND there are tons of JavaScript libraries that are meant to be used through module loaders. AND there are tons of JavaScript libraries that assume you will use them via npm. AND there are tons of libraries built for ES6 imports. If you write a JavaScript library and are shooting for maximum usage, you’d make it work in all those ways, even though that’s obnoxious legwork.

I love Lea’s ideas here on taking libraries that were never really meant to be ES6 import-ed, but doing it anyway.

For example:

window.module = {}; import("https://cdn.jsdelivr.net/gh/reworkcss/css@latest/lib/parse/index.js").then(_ => {   console.log(module.exports); });

And a function if you needed to be safer about that, like a little abstraction:

Check out the article for another clever little trick.

Direct Link to ArticlePermalink

The post Import Non-ESM libraries in ES Modules, with Client-Side Vanilla JS appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, , , , ,

A Bit on Web Component Libraries

A run of Web Components news crossed my desk recently so I thought I’d group it up here.

To my mind, one of the best use cases for Web Components is pattern libraries. Instead of doing, say, <ul class="nav nav-tabs"> like you would do in Bootstrap or <div class="tabs"> like you would in Bulma, you would use a custom element, like <designsystem-tabs>.

The new Shoelace library uses the sl namespace for their components. It’s a whole pattern library entirely in Web Components. So the tabs there are <sl-tab-group> elements.

Why is that good? Well, for one thing, it brings a component model to the party. That means, if you’re working on a component, it has a template and a stylesheet that are co-located. Peeking under the hood of Shoelace, you can see this is all based on Stencil.

Another reason it’s good is that it means components can (and they do) use the Shadow DOM. This offers a form of isolation that comes right from the web platform. For CSS folks like us, that means the styling for a tab in the tab component is done with a .tab class (hey, wow, cool) but it is isolated in that component. Even with that generic of a name, I can’t accidentally mess with some other component on the page that uses that generic class, nor is some other outside CSS going to mess with the guts here. The Shadow DOM is a sort of wall of safety that prevents styles from leaking out or seeping in.

I just saw the FAST framework¹ too, which is also a set of components. It has tabs that are defined as <fast-tabs>. That reminds me of another thing I like about the Web Components as a pattern library approach: if feels like it’s API-driven, even starting with the name of the component itself, which is literally what you use in the HTML. The attributes on that element can be entirely made up. It seems the emerging standard is that you don’t even have to data-* prefix the attributes that you also make up to control the component. So, if I were to make a tabs component, it might be <chris-tabs active-tab="lunch" variation="rounded">.

Perhaps the biggest player using Web Components for a pattern library is Ionic. Their tabs are <ion-tabs>, and you can use them without involving any other framework (although they do support Angular, React, and Vue in addition to their own Stencil). Ionic has made lots of strides with this Web Components stuff, most recently supporting Shadow Parts. Here’s Brandy Carney explaining the encapsulation again:

Shadow DOM is useful for preventing styles from leaking out of components and unintentionally applying to other elements. For example, we assign a .button class to our ion-button component. If an Ionic Framework user were to set the class .button on one of their own elements, it would inherit the Ionic button styles in past versions of the framework. Since ion-button is now a Shadow Web Component, this is no longer a problem.

However, due to this encapsulation, styles aren’t able to bleed into inner elements of a Shadow component either. This means that if a Shadow component renders elements inside of its shadow tree, a user isn’t able to target the inner element with their CSS.

The encapsulation is a good thing, but indeed it does make styling “harder” (on purpose). There is an important CSS concept to know: CSS custom properties penetrate the Shadow DOM. However, it was decided — and I think rightly so — that “variablizing” every single thing in a design system is not a smart way forward. Instead, they give each bit of HTML inside the Shadow DOM a part, like <div part="icon">, which then gives gives the ability to “reach in from the outside” with CSS, like custom-component::part(icon) { }.

I think part-based styling hooks are mostly fine, and a smart way forward for pattern libraries like this, but I admit some part of it bugs me. The selectors don’t work how you’d expect. For example, you can’t conditionally select things. You also can’t select children or use the cascade. In other words, it’s just one-off, or like you’re reaching straight through a membrane with your hand. You can reach forward and either grab the thing or not, but you can’t do anything else at all.

Speaking of things that bug people, Andrea Giammarchi has a good point about the recent state of Web Components:

Every single library getting started, including mine, suggest we should import the library in order to define what [sic] supposed to be a “portable Custom Element”.

Google always suggests LitElement. Microsoft wants you to use FASTElement. Stencil has their own Component. hyperHTML has their own Component. Nobody is just using “raw” Web Components. It’s weird! What strikes me as the worst part about that is that Web Components are supposed to be this “native platform” thing meaning that we shouldn’t need to buy into some particular technology in order to use them. When we do, we’re just as locked to that as we would be if we just used React or whatever.

Andrea has some ideas in that article, including the use of some new and smaller library. I think what I’d like to see is a pattern library that just doesn’t use any library at all.

  1. FAST calls itself a “interface system,” then a “UI framework” in consecutive sentences on the homepage. Shoelaces calls itself a “library” but I’m calling it a “pattern library.” I find “design system” to be the most commonly used term to describe the concept, but often used more broadly than a specific technology. FAST uses that term in the code itself for the wrapper element that controls the theme. I’d say the terminology around all this stuff is far from settled.

The post A Bit on Web Component Libraries appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.



JavaScript Libraries Are Almost Never Updated Once Installed

Some commentary from Zack Bloom on the Cloudflare Blog, looking at requests to CDNJS for versions of jQuery.

What we don’t see is a decline in our old versions which come close to the volume of growth of new versions when they’re released. In fact the release of 3.4.1, as popular as it quickly becomes, doesn’t change the trend of old version deprecation at all.

Sorta makes sense. We make CDNJS easy to use at CodePen, where people can quickly search for, find, and add libraries like jQuery to Pens. I very much doubt most users are rushing back to their old Pens to update versions when a new jQuery comes out.

And upgrading versions is hard and scary on large sites. I saw an Instagram from someone at Etsy (the photo is private) commemorating their upcoming upgrade off of jQuery 1.8.2, which is eight years old!

Direct Link to ArticlePermalink

The post JavaScript Libraries Are Almost Never Updated Once Installed appeared first on CSS-Tricks.


, , , , , ,

The Unseen Performance Costs of Modern CSS-in-JS Libraries

This article is full of a bunch of data from Aggelos Arvanitakis. But lemme just focus on his final bit of advice:

Investigate whether a zero-runtime CSS-in-JS library can work for your project. Sometimes we tend to prefer writing CSS in JS for the DX (developer experience) it offers, without a need to have access to an extended JS API. If you app doesn’t need support for theming and doesn’t make heavy and complex use of the css prop, then a zero-runtime CSS-in-JS library might be a good candidate.

“Zero-runtime” meaning you author your styles in a CSS-in-JS syntax, but what is produced is .css files like any other CSS preprocessor would produce. This shifts the tool into a totally different category. It’s a developer tool only, rather than a tool where the user of the website pays the price of using it.

The flagship zero-runtime CSS-in-JS library is Linaria. I think the syntax looks really nice.

import { css } from 'linaria'; import fonts from './fonts';  const header = css`   text-transform: uppercase;   font-family: $  {fonts.heading}; `;  <h1 className={header}>Hello world</h1>;

I’m also a fan of the just do scoping for me ability that CSS modules brings, which can be done zero-runtime style.

Direct Link to ArticlePermalink

The post The Unseen Performance Costs of Modern CSS-in-JS Libraries appeared first on CSS-Tricks.


, , , , ,

CSS Animation Libraries

There are an awful lot of libraries that want to help you animate things on the web. These aren’t really libraries that help you with the syntax or the technology of animations, but rather are grab-and-use as-is libraries. Want to apply a class like “animate-flip-up” and watch an element, uhhh, flip up? These are the kind of libraries to look at.

I wholeheartedly think you should both 1) learn how to animate things in CSS by learning the syntax yourself and 2) customize animations to tailor the feel to your site. Still, poking around libraries like this helps foster ideas, gets you started with code examples, and might form a foundation for your own projects.

Let’s take a look at the landscape of them. Some libraries have different approaches: only take what you need classes, Sass mixins, light JavaScript libraries for adding/removing classes, etc. But they are all essentially “CSS animation libraries.” (Some of them are kinda funny having “CSS3” in the title, which kinda dates them. People just don’t say that anymore.)

While animations can both be fun and create useful interactions, it’s worth remembering that not all users want them when browsing the web. See Eric Bailey’s “Revisiting prefers-reduced-motion, the reduced motion media query” for information on how to accommodate users who prefer little or no motion.


You pick an animation you like and it gives you a class name you can use that calls a keyframe animation (you copy and paste both). The point is you just take what you need.

See the Pen
Animista Example
by Chris Coyier (@chriscoyier)
on CodePen.


One of the big original classic CSS animation libraries from Dan Eden.

See the Pen
Animate.css (Part 3)
by Hudson Taylor (@Hudson_Taylor11)
on CodePen.


Tachyons itself is an atomic CSS library with a ton of utility classes for essentially designing anything by adding classes to what you need. tachyons-animate extends those by adding “Single purpose classes to help you orchestrate CSS animations.” It can be used alone, but even the docs suggest it can be used in combination with other animation libraries since helper classes are generically useful.

See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


These animations, like rotations and pulses, that are specifically designed to run and repeat forever.

See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.

Motion UI

A Sass library for creating flexible CSS transitions and animations.

See the Pen
Motion UI
by Chris Coyier (@chriscoyier)
on CodePen.


a [μ] microInteraction library built with CSS Animations and controlled by JavaScript Power

See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


Vivify is sort of like Animate.css in the sense that it contains a lot of the same types of animations. It does offer plenty of its own as well.

See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


A collection of CSS3 powered hover effects to be applied to links, buttons, logos, SVG, featured images and so on. Easily apply to your own elements, modify or just use for inspiration. Available in CSS, Sass, and LESS.

See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


See the Pen
All Animation
by Chris Coyier (@chriscoyier)
on CodePen.

Magic Animations CSS3

See the Pen
Magic Animations
by Chris Coyier (@chriscoyier)
on CodePen.

It’s Tuesday.

A quirky CSS Animation Library.

See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.

Motion CSS


See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


See the Pen
WickedCSS animations
by Chris Coyier (@chriscoyier)
on CodePen.


See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.


See the Pen
by Chris Coyier (@chriscoyier)
on CodePen.



See the Pen
by Eric Treacy (@etreacy)
on CodePen.

The post CSS Animation Libraries appeared first on CSS-Tricks.



Integrating Third-Party Animation Libraries to a Project

Creating CSS-based animations and transitions can be a challenge. They can be complex and time-consuming. Need to move forward with a project with little time to tweak the perfect transition? Consider a third-party CSS animation library with ready-to-go animations waiting to be used. Yet, you might be thinking: What are they? What do they offer? How do I use them?

Well, let’s find out.

A (sort of) brief history of :hover

Once there was a time that the concept of a hover state was a trivial example of what is offered today. In fact, the idea of having a reaction to the cursor passing on top of an element was more-or-less nonexistent. Different ways to provide this feature were proposed and implemented. This small feature, in a way, opened the door to the idea of CSS being capable of animations for elements on the page. Over time, the increasing complexity possible with these features have led to CSS animation libraries.

Macromedia’s Dreamweaver was introduced in December 1997 and offered what was a simple feature, an image swap on hover. This feature was implemented with a JavaScript function that would be embedded in the HTML by the editor. This function was named MM_swapImage() and has become a bit of web design folklore. It was an easy script to use, even outside of Dreamweaver, and it’s popularity has resulted in it still being in use even today. In my initial research for this article, I found a question pertaining to this function from 2018 on Adobe’s Dreamweaver (Adobe acquired Macromedia in 2005) help forum.

The JavaScript function would swap an image with another image through changing the src attribute based on mouseover and mouseout events. When implemented, it looked something like this:

<a href="#" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('ImageName','','newImage.jpg',1)">   <img src="originalImage.jpg" name="ImageName" width="100" height="100" border="0"> </a>

By today’s standards, it would be fairly easy to accomplish this with JavaScript and many of us could practically do this in our sleep. But consider that JavaScript was still this new scripting language at the time (created in 1995) and sometimes looked and behaved differently from browser to browser. Creating cross-browser JavaScript was not always an easy task and not everyone creating web pages even wrote JavaScript. (Though that has certainly changed.) Dreamweaver offered this functionality through a menu in the editor and the web designer didn’t even need to write the JavaScript. It was based around a set of “behaviors” that could be selected from a list of different options. These options could be filtered by a set of targeted browsers; 3.0 browsers, 4.0 browsers, IE 3.0, IE 4.0, Netscape 3.0, Netscape 4.0. Ah, the good old days.

A screenshot of a Netscape browser window.
Choosing Behaviors based on browser versions, circa 1997.
A screenshot from the Dreamweaver application that shows the options panel for toggling an element's behavior in HTML.
The Swap Image Behaviors panel in Macromedia Dreamweaver 1.2a

About a year after Dreamweaver was first released, the CSS2 specification from W3C mentioned :hover in a working draft dated January 1998. It was specifically mentioned in terms of anchor links, but the language suggests it could have possibly been applied to other elements. For most purposes it would seem this pseudo selector would be the beginning of an easy alternative to MM_swapImage(), since background-image was in the same draft. Although browser support was an issue as it took years before enough browsers properly supported CSS2 to make it a viable option for many web designers. There was finally a W3C recommendation of CSS2.1, this could be considered to be the basis of “modern” CSS as we know it, which was published in June 2011.

In the middle of all this, jQuery came along in 2006. Thankfully, jQuery went a long way in simplifying JavaScript among the different browsers. One thing of interest for our story, the first version of jQuery offered the animate() method. With this method, you could animate CSS properties on any element at any time; not just on hover. By its sheer popularity, this method exposed the need for a more robust CSS solution baked into the browser — a solution that wouldn’t require a JavaScript library that was not always very performant due to browser limitations.

The :hover pseudo-class only offered a hard swap from one state to another with no support for a smooth transition. Nor could it animate changes in elements outside of something as basic as hovering over an element. jQuery’s animate() method offered those features. It paved the way and there was no going back. As things go in the dynamic world of web development, a working draft for solving this was well underway before the recommendation of CSS2.1 was published. The first working draft for CSS Transitions Module Level 3 was first published by the W3C in March 2009. The first working draft for CSS Animations Module Level 3 was published at roughly the same time. Both of these CSS modules are still in a working draft status as of October 2018, but of course, we are already making heavy use of them

So, what first started as a JavaScript function provided by a third-party, just for a simple hover state, has led to transitions and animations in CSS that allow for elaborate and complex animations — complexity that many developers wouldn’t necessarily wish to consider as they need to move quickly on new projects. We have gone full circle; today many third-party CSS animation libraries have been created to offset this complexity.

Three different types of third-party animation libraries

We are in this new world capable of powerful, exciting, and complex animations in our web pages and apps. Several different ideas have come to the forefront on how to approach these new tasks. It’s not that one approach is better than any other; indeed, there is a good bit of overlap in each. The difference is more about how we implement and write code for them. Some are full-blown JavaScript-only libraries while others are CSS-only collections.

JavaScript libraries

Libraries that operate solely through JavaScript often offer capabilities beyond what common CSS animations provide. Usually, there is overlap as the libraries may actually use CSS features as part of their engine, but that would be abstracted away in favor of the API. Examples of such libraries are Greensock and Anime.js. You can see the extent of what they offer by looking at the demos they provide (Greensock has a nice collection over on CodePen). They’re mostly intended for highly complex animations, but can be useful for more basic animations as well.

JavaScript and CSS libraries

There are third-party libraries that primarily include CSS classes but provide some JavaScript for easy use of the classes in your projects. One library, Micron.js, provides both a JavaScript API and data attributes that can be used on elements. This type of library allows for easy use of pre-built animations that you can just select from. Another library, Motion UI, is intended to be used with a JavaScript framework. Although, it also works on a similar notion of a mixture of a JavaScript API, pre-built classes, and data attributes. These types of libraries provide pre-built animations and an easy way to wire them up.

CSS libraries

The third kind of library is CSS-only. Typically, this is just a CSS file that you load via a link tag in your HTML. You then apply and remove specific CSS classes to make use of the provided animations. Two examples of this type of library are Animate.css and Animista. That said, there are even major differences between these two particular libraries. Animate.css is a total CSS package while Animista provides a slick interface to choose the animations you want with provided code. These libraries are often easy to implement but you have to write code to make use of them. These are the type of libraries this article will focus on.

Three different types of CSS animations

Yes, there’s a pattern; the rule of threes is everywhere, after all.

In most cases, there are three types of animations to consider when making use of third-party libraries. Each type suits a different purpose and has different ways to make use of them.

Hover animations

An illustration of a black button on the left and an orange button with a mouse cursor over it as a hover effect.

These animations are intended to be involved in some sort of hover state. They’re often used with buttons, but another possibility is using them to highlight sections the cursor happens to be on. They can also be used for focus states.

Attention animations

An illustration of a webpage with gray boxes and a red alert at the top of the screen to show an instance of an element that seeks attention.

These animations are intended to be used on elements that are normally outside of the visual center of the person viewing the page. An animation is applied to a section of the display that needs attention. Such animations could be subtle in nature for things that need eventual attention but not dire in nature. They could also be highly distracting for when immediate attention is required.

Transition animations

An illustration of concentric circles stacked vertically going from gray to black in ascending order.

These animations are often intended to have an element replace another in the view, but can be used for one element as well. These will usually include an animation for “leaving” the view and mirror animation for “entering” the view. Think of fading out and fading in. This is commonly needed in single page apps as one section of data would transition to another set of data, for example.

So, let’s go over examples of each of these type of animations and how one might use them.

Let’s hover it up!

Some libraries may already be set for hover effects, while some have hover states as their main purpose. One such library is Hover.css, which is a drop-in solution that provides a nice range of hover effects applied via class names. Sometimes, though, we want to make use of an animation in a library that doesn’t directly support the :hover pseudo-class because that might conflict with global styles.

For this example, I shall use the tada animation that Animate.css provides. It’s intended more as an attention seeker, but it will nicely suffice for this example. If you were to look through the CSS of the library, you’ll find that there’s no :hover pseudo-class to be found. So, we’ll have to make it work in that manner on our own.

The tada class by itself is simply this:

.tada {   animation-name: tada; }

A low-lift approach to make this react to a hover state is to make our own local copy of the class, but extend it just a bit. Normally, Animate.css is a drop-in solution, so we won’t necessarily have the option to edit the original CSS file; although you could have your own local copy of the file if you wish. Therefore, we only create the code we require to be different and let the library handle the rest.

.tada-hover:hover {   animation-name: tada; }

We probably shouldn’t override the original class name in case we actually want to use it elsewhere. So, instead, we make a variation that we can place the :hover pseudo-class on the selector. Now we just use the library’s required animated class along with our custom tada-hover class to an element and it will play that animation on hover.

If you wouldn’t want to create a custom class in this way, but prefer a JavaScript solution instead, there’s a relatively easy way to handle that. Oddly enough, it’s a similar method to the MM_imageSwap() method from Dreamweaver we discussed earlier.

// Let's select elements with ID #js_example var js_example = document.querySelector('#js_example');  // When elements with ID #js_example are hovered... js_example.addEventListener('mouseover', function () {   // ...let's add two classes to the element: animated and tada...   this.classList.add('animated', 'tada'); }); // ...then remove those classes when the mouse is not on the element. js_example.addEventListener('mouseout', function () {   this.classList.remove('animated', 'tada'); });

There are actually multiple ways to handle this, depending on the context. Here, we create some event listeners to wait for the mouse-over and mouse-out events. These listeners then apply and remove the library’s animated and tada classes as needed. As you can see, extending a third-party library just a bit to suit our needs can be accomplished in relatively easy fashion.

Can I please have your attention?

Another type of animation that third-party libraries can assist with are attention seekers. These animations are useful for when you wish to draw attention to an element or section of the page. Some examples of this could be notifications or unfilled required form inputs. These animations can be subtle or direct. Subtle for when something needs eventual attention but does not need to be resolved immediately. Direct for when something needs resolution now.

Some libraries have such animations as part of the whole package, while some are built specifically for this purpose. Both Animate.css and Animista have attention seeking animations, but they are not the main purpose for those libraries. An example of a library built for this purpose would be CSShake. Which library to use depends on the needs of the project and how much time you wish to invest in implementing them. For example, CSShake is ready to go with little trouble on your part — simply apply classes as needed. Although, if you were already using a library such as Animate.css, then you’re likely not going to want to introduce a second library (for performance, reliance on dependencies, and such).

So, a library such as Animate.css can be used but needs a little more setup. The library’s GitHub page has examples of how to go about doing this. Depending on the needs of a project, implementing these animations as attention seekers is rather straightforward.

For a subtle type of animation, we could have one that just repeats a set number of times and stops. This usually involves adding the library’s classes, applying an animation iteration property to CSS, and waiting for the animation end event to clear the library’s classes.

Here’s a simple example that follows the same pattern we looked at earlier for hover states:

var pulse = document.querySelector('#pulse');  function playPulse () {   pulse.classList.add('animated', 'pulse'); }  pulse.addEventListener('animationend', function () {   pulse.classList.remove('animated', 'pulse'); });  playPulse();

The library classes are applied when the playPulse function is called. There’s an event listener for the animationend event that will remove the library’s classes. Normally, this would only play once, but you might want to repeat multiple times before stopping. Animate.css doesn’t provide a class for this, but it’s easy enough to apply a CSS property for our element to handle this.

#pulse {   animation-iteration-count: 3; /* Stop after three times */ }

This way, the animation will play three times before stopping. If we needed to stop the animation sooner, we can manually remove the library classes outside of the animationend function. The library’s documentation actually provides an example of a reusable function for applying the classes that removes them after the animation; very similar to the above code. It would even be rather easy to extend it to apply the iteration count to the element.

For a more direct approach, let’s say an infinite animation that won’t stop until after some sort of user interaction takes place. Let’s pretend that clicking the element is what starts the animation and clicking again stops it. Keep in mind that however you wish to start and stop the animation is up to you.

var bounce = document.querySelector('#bounce');  bounce.addEventListener('click', function () {   if (!bounce.classList.contains('animated')) {     bounce.classList.add('animated', 'bounce', 'infinite');   } else {     bounce.classList.remove('animated', 'bounce', 'infinite');   } });

Simple enough. Clicking the element tests if the library’s “animated” class has been applied. If it has not, we apply the library classes so it starts the animation. If it has the classes, we remove them to stop the animation. Notice that infinite class on the end of the classList. Thankfully, Animate.css provides this for us out-of-the-box. If your library of choice doesn’t offer such a class, then this is what you need in your CSS:

#bounce {   animation-iteration-count: infinite; }

Here’s a demo showing how this code behaves:

See the Pen
3rd Party Animation Libraries: Attention Seekers
by Travis Almand (@talmand)
on CodePen.

Moving stuff out of the way

When researching for this article, I found that transitions (not to be confused with CSS transitions) are easily the most common type of animations in the third-party libraries. These are simple animations that are built to allow an element to enter or leave the page. A very common pattern seen in modern Single Page Applications is to have one element leave the page while another replaces it by entering the page. Think of the first element fading out and the second fading in. This could be replacing old data with new data, moving to the next panel in a sequence, or moving from one page to another with a router. Both Sarah Drasner and Georgy Marchuk have excellent examples of these types of transitions.

For the most part, animation libraries will not provide the means to remove and add elements during the transition animations. The libraries that provide additional JavaScript may actually have this functionality, but since most do not, we’ll discuss how to handle this functionality now.

Inserting a single element

For this example, we’ll again use Animate.css as our library. In this case, I’ll be using the fadeInDown animation.

Now, please keep in mind there are many ways to handle inserting an element into the DOM and I don’t wish to cover them here. I’ll just be showing how to leverage an animation to make the insertion nicer and more natural than the element simply popping into view. For Animate.css (and likely many other libraries), inserting an element with the animation is quite easy.

let insertElement = document.createElement('div'); insertElement.innerText = 'this div is inserted'; insertElement.classList.add('animated', 'fadeInDown');  insertElement.addEventListener('animationend', function () {   this.classList.remove('animated', 'fadeInDown'); });  document.body.append(insertElement);

However you decide to create the element doesn’t much matter; you just need to be sure the needed classes are already applied before inserting the element. Then it’ll nicely animate into place. I also included an event listener for the animationend event that removes the classes. As usual, there are several ways to go about doing this and this is likely the most direct way to handle it. The reason for removing the classes is to make it easier to reverse the process if we wish. We wouldn’t want the entering animation competing with a leaving animation.

Removing a single element

Removing a single element is sort of similar to inserting an element. The element already exists, so we just apply the desired animation classes. Then at the animationend event we remove the element from the DOM. In this example, we’ll use the fadeOutDown animation from Animate.css because it works nicely with the fadeInDown animation.

let removeElement = document.querySelector('#removeElement');  removeElement.addEventListener('animationend', function () {   this.remove(); });  removeElement.classList.add('animated', 'fadeOutDown');

As you can see, we target the element, add the classes, and remove the element at the end of the animation.

An issue with all this is that with inserting and removing elements this way will cause the other elements on the page to jump around to adjust. You’ll have to account for that in some way, most likely with CSS and the layout of the page to keep a constant space for the elements.

Get out of my way, I’m coming through!

Now we are going to swap two elements, one leaving while another enters. There are several ways of handling this, but I’ll provide an example that’s essentially combining the previous two examples.

See the Pen
3rd Party Animation Libraries: Transitioning Two Elements
by Travis Almand (@talmand)
on CodePen.

I’ll go over the JavaScript in parts to explain how it works. First, we cache a reference to a button and the container for the two elements. Then, we create two boxes that’ll be swapped inside the container.

let button = document.querySelector('button'); let container = document.querySelector('.container'); let box1 = document.createElement('div'); let box2 = document.createElement('div');

I have a generic function for removing the animation classes for each animationEnd event.

let removeClasses = function () {   box1.classList.remove('animated', 'fadeOutRight', 'fadeInLeft');   box2.classList.remove('animated', 'fadeOutRight', 'fadeInLeft'); }

The next function is the bulk of the swapping functionality. First, we determine the current box being displayed. Based on that, we can deduce the leaving and entering elements. The leaving element gets the event listener that called the switchElements function removed first so we don’t find ourselves in an animation loop. Then, we remove the leaving element from the container since its animation has finished. Next, we add the animation classes to the entering element and append it to the container so it’ll animate into place.

let switchElements = function () {   let currentElement = document.querySelector('.container .box');   let leaveElement = currentElement.classList.contains('box1') ? box1 : box2;   let enterElement = leaveElement === box1 ? box2 : box1;      leaveElement.removeEventListener('animationend', switchElements);   leaveElement.remove();   enterElement.classList.add('animated', 'fadeInLeft');   container.append(enterElement); }

We need to do some general setup for the two boxes. Plus, we append the first box to the container.

box1.classList.add('box', 'box1'); box1.addEventListener('animationend', removeClasses); box2.classList.add('box', 'box2'); box2.addEventListener('animationend', removeClasses);  container.appendChild(box1);

Finally, we have a click event listener for our button that does the toggling. How these sequences of events are started is technically up to you. For this example, I decided on a simple button click. I figure out which box is currently being displayed, which will be leaving, to apply the appropriate classes to make it animate out. Then I apply an event listener for the animationEnd event that calls the switchElements function shown above that handles the actual swap.

button.addEventListener('click', function () {   let currentElement = document.querySelector('.container .box');      if (currentElement.classList.contains('box1')) {     box1.classList.add('animated', 'fadeOutRight');     box1.addEventListener('animationend', switchElements);   } else {     box2.classList.add('animated', 'fadeOutRight');     box2.addEventListener('animationend', switchElements);   } }

One obvious issue with this example is that it is extremely hard-coded for this one situation. Although, it can be easily extended and adjusted for different situations. So, the example is useful in terms of understanding one way of handling such a task. Thankfully, some animation libraries, like MotionUI, provide some JavaScript to help with element transitions. Another thing to consider is that some JavaScript frameworks, such as VueJS have functionality to assist with animating element transitions.

I have also created another example that provides a more flexible system. It consists of a container that stores references to leave and enter animations with data attributes. The container holds two elements that will switch places on command. The way this example is built is that the animations are easily changed in the data attributes via JavaScript. I also have two containers in the demo; one using Animate.css and the other using Animista for animations. It’s a large example, so I won’t examine code here; but it is heavily commented, so take a look if it is of interest.

See the Pen
3rd Party Animation Libraries: Custom Transition Example
by Travis Almand (@talmand)
on CodePen.

Take a moment to consider…

Does everyone actually want to see all these animations? Some people could consider our animations over-the-top and unnecessary, but for some, they can actually cause problems. Some time ago, WebKit introduced the prefers-reduced-motion media query to assist with possible Vestibular Spectrum Disorder issues. Eric Bailey also posted a nice introduction to the media query, as well as a follow-up with considerations for best practices. Definitely read these.

So, does your animation library of choice support the prefers-reduced-motion? If the documentation doesn’t say that it does, then you may have to assume it does not. Although, it is rather easy to check the code of the library to see if there is anything for the media query. For instance, Animate.css has it in the _base.scss partial file.

@media (print), (prefers-reduced-motion) {   .animated {     animation: unset !important;     transition: none !important;   } }

This bit of code also provides an excellent example of how to do this for yourself if the library doesn’t support it. If the library has a common class it uses — like Animate.css uses “animated” — then you can just target that class. If it does not support such a class then you’ll have to target the actual animation class or create your own custom class for that purpose.

.scale-up-center {   animation: scale-up-center 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both; }  @keyframes scale-up-center {   0% { transform: scale(0.5); }   100% { transform: scale(1); } }  @media (print), (prefers-reduced-motion) {   .scale-up-center {     animation: unset !important;     transition: none !important;   } }

As you can see, I just used the example as provided by Animate.css and targeted the animation class from Animista. Keep in mind that you’ll have to repeat this for every animation class you choose to use from the library. Although, in Eric’s follow-up piece, he suggests treating all animations as progressive enhancement and that could be one way to both reduce code and make a more accessible user experience.

Let a framework do the heavy lifting for you

In many ways, the various frameworks such as React and Vue can make using third-party CSS animation easier than with vanilla JavaScript, mainly because you don’t have to wire up the class swaps or animationend events manually. You can leverage the functionality the frameworks already provide. The beauty of using frameworks is that they also provide several different ways of handling these animations depending on the needs of the project. The examples below is only a small example of options.

Hover effects

For hover effects, I would suggest setting them up with CSS (as I suggested above) as the better way to go. If you really need a JavaScript solution in a framework, such as Vue, it would be something like this:

<button @mouseover="over($ event, 'tada')" @mouseleave="leave($ event, 'tada')">   tada </button>
methods: {   over: function(e, type) {     e.target.classList.add('animated', type);   },   leave: function (e, type) {     e.target.classList.remove('animated', type);   } }

Not really that much different than the vanilla JavaScript solution above. Also, as before, there are many ways of handling this.

Attention seekers

Setting up the attention seekers is actually even easier. In this case, we’re just applying the classes we require, again, using Vue as an example:

<div :class="{animated: isPulse, pulse: isPulse}">pulse</div>  <div :class="[{animated: isBounce, bounce: isBounce}, 'infinite']">bounce</div>

In the pulse example, whenever the boolean isPulse is true, the two classes are applied. In the bounce example, whenever the boolean isBounce is true the animated and bounce classes are applied. The infinite class is applied regardless so we can have our never-ending bounce until the isBounce boolean goes back to false.


Thankfully, Vue’s transition component provides an easy way to use third-party animation classes with custom transition classes. Other libraries, such as React, could offer similar features or add-ons. To make use of the animation classes in Vue, we just implement them in the transition component.

<transition   enter-active-class="animated fadeInDown"   leave-active-class="animated fadeOutDown"   mode="out-in" >   <div v-if="toggle" key="if">if example</div>   <div v-else key="else">else example</div> </transition>

Using Animate.css, we merely apply the necessary classes. For enter-active, we apply the required animated class along with fadeInDown. For leave-active, we apply the required animated class along with fadeOutDown. During the transition sequence, these classes are inserted at the appropriate times. Vue handles the inserting and removing of the classes for us.

For a more complex example of using third-party animation libraries in a JavaScript framework, explore this project:

See the Pen
by Travis Almand (@talmand)
on CodePen.

Join the party!

This is a small taste of the possibilities that await your project as there are many, many third-party CSS animation libraries out there to explore. Some are thorough, eccentric, specific, obnoxious, or just straight-forward. There are libraries for complex JavaScript animations such as Greensock or Anime.js. There are even libraries that will target the characters in an element.

Hopefully all this will inspire you to play with these libraries on the way to creating your own CSS animations.

The post Integrating Third-Party Animation Libraries to a Project appeared first on CSS-Tricks.


, , , ,

Making SVG icon libraries for React apps

Nicolas Gallagher:

At Twitter I used the approach described here to publish the company’s SVG icon library in several different formats: optimized SVGs, plain JavaScript modules, React DOM components, and React Native components.

There is no One True Way© to make an SVG icon system. The only thing that SVG icon systems have in common is that, somehow, some way, SVG is used to show that icon. I gotta find some time to write up a post that goes into all the possibilities there.

One thing different systems tend to share is some kind of build process to turn a folder full of SVG files into a more programmatically digestible format. For example, gulp-svg-sprite takes your folder of SVGs and creates a SVG sprite (chunk of <symbol>s) to use in that type of SVG icon system. Grunticon processes your folder of SVGs into a CSS file, and is capable of enhancing them into inline SVG. Gallagher’s script creates React components out of them, and like he said, that’s great for delivery to different targets as well as performance optimization, like code splitting.

This speaks to the versatility of SVG. It’s just markup, so it’s easy to work with.

Direct Link to ArticlePermalink

The post Making SVG icon libraries for React apps appeared first on CSS-Tricks.


, , , ,