</>

Lightweight and meaningful UIs with CSS

Or how to simply animate user interfaces and avoid bloat in the process.


:root {
	--name:    'Nicolás Joel Engler';
	--job:     'Full-stack Designer';
	--company: 'Tienda Nube / Nuvem Shop';
	--twitter: '@NicolasJEngler';
	--email:   'hi@nicolasjengler.com.ar';
}
					

Animation nirvana
(without libraries)

  • Popmotion
  • Animate.css
  • Velocity.js
  • anime.js
  • mojs
  • wow.js
  • GSAP
  • Wicked CSS
  • Tuesday
  • CSS Shake

Animation nirvana
(without libraries)

https://codepen.io/nicolasjengler/pen/QrBKJV

Animation nirvana
(without libraries)


.popover-wrapper {
	position: relative;
}

.popover {
	position: absolute;
	transform: scale(0);
	opacity: 0;
	transform-origin: 50% 100%;
	transition: all .5s cubic-bezier(0.770, 0.000, 0.175, 1.000);
}

.popover-wrapper:hover .popover {
	transform: scale(1);
	opacity: 1;
}
					

Real-life movement

Real-life movement

Movement of objects in our world is rarely linear, most of them move with a certain variation in their motion and this happens because of different laws of physics, which is why objects in the web that move in a linear manner look odd or awkward.

https://codepen.io/nicolasjengler/pen/RyBZwW

Real-life movement

Transitions and animations can use timing functions, which basically are specifications for the speed curve of an animation. The speed curve is in charge of defining how an animation uses the defined time for the transition or animation. The following are possible timing functions:


.popover {
	transition-timing-function: linear;
	transition-timing-function: ease;
	transition-timing-function: ease-in;
	transition-timing-function: ease-out;
	transition-timing-function: ease-in-out;
	transition-timing-function: step-start;
	transition-timing-function: step-end;
	transition-timing-function: steps(int,start|end);
	transition-timing-function: cubic-bezier(n,n,n,n);
	transition-timing-function: initial;
	transition-timing-function: inherit;
}
					

Real-life movement

For the previous demo, the popover on the right moved and appeared a bit more awkward than the one on the left because their timing functions were the following:


.popover {
	transition: all .5s cubic-bezier(0.770, 0.000, 0.175, 1.000);
}

.popover.no-easing {
	transition: all .5s linear;
}
					

Real-life movement

What exactly is a cubic-bezier() function and how does it work? Well, the function defines a Cubic Bezier curve which consists of four points: x1, x2, y1, y2. x1 and y1 define a start for the curve, ending in a position defined by x2 and y2.

The Bezier curve is then in charge of managing the speed curve of a transition or animation in a more customizable manner compared to what we can do with keywords.

Real-life movement

Understanding how a Bezier Curve works for CSS without visualizing it can be really tricky. Lea Verou, a front-end developer, speaker and author, created a handy tool to test out different curves.

http://cubic-bezier.com/

Real-life movement

As you may have seen, besides the cubic-bezier() function, there's a possibility to use keywords like linear, ease, ease-in, or ease-out. These keywords work in the follwing way...

Real-life movement

linear == cubic-bezier(0,0,1,1)

Real-life movement

ease == cubic-bezier(.25,.1,.25,.1)

Real-life movement

ease-in == cubic-bezier(.42,0,1,1)

Real-life movement

ease-out == cubic-bezier(0,0,.58,1)

Real-life movement

ease-in-out == cubic-bezier(.42,0,.58,1)

Real-life movement

steps() can be used for a sort-of frame by frame animation.


.popover {
	transition: all .5s steps(5); // Handy for debugging
}
					
https://codepen.io/nicolasjengler/pen/aGjYYK

Real-life movement

There's also a possibility to stagger animations by using the transition/animation-delay property as a separate property, or adding a defined amount of time at the end of the transition/animation shorthand property.


.popover {
	transition: all .5s cubic-bezier(0.770, 0.000, 0.175, 1.000),
		    color .5s ease-in .5s,
		    letter-spacing .5s ease-in .3s;
	transform: scale(1);
	opacity: 1;
	letter-spacing: 1px;
	color: rgba(255,255,255,0);
}

.popover-wrapper:hover .popover {
	transform: scale(1);
	opacity: 1;
	letter-spacing: 0;
	color: white;
}
					

Real-life movement

https://codepen.io/nicolasjengler/pen/QrBKJV?editors=1100

Everyday use cases

A really simple way to have some other presets than the keywords we saw a couple of slides ago is to store some curve values in custom properties. My easings.scss file looks like this:


:root {
	/* Ease In */
	--ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
	--ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
	--ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
	--ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
	/* Ease Out */
	--ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
	--ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
	--ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
	--ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
	/* Ease In Out */
	--ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
	--ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
	--ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
	--ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
}
					

Vanilla-CSS possibilities

https://codepen.io/nicolasjengler/pen/LkzYQr

Vanilla-CSS possibilities

https://codepen.io/nicolasjengler/pen/GpjzQj

Vanilla-CSS possibilities

https://codepen.io/nicolasjengler/pen/XEorXM

Vanilla-CSS possibilities

https://codepen.io/nicolasjengler/pen/ZGqjGV

Thank you!