
The past few weeks I’ve encountered several styling challenges that I was able to accomplish with just a few lines of CSS, which made me very thankful for all of the developments CSS has had over the past few years. Container queries, the :has()
pseudo-class, and CSS layers immediately come to my mind. It’s a good reminder to keep up with new CSS features as they gain browser support. These are just a few new CSS features and real-world applications of them I’m excited to share.
Math Functions
A good number of math functions have been coming to CSS in the past few years. Here are a couple newer additions:
sign()
sign()
takes an expression and returns the sign of the result: 1, -1, or 0. The most clever usage of this property I’ve seen is this CSS scroll-driven animation by Bramus that also uses CSS scroll()
to interpolate the animation based on scroll velocity.
abs()
abs()
and mod()
do exactly what their mathematical terminology suggests. abs()
takes the absolute value of a number and mod()
takes the modulo or remainder of a division expression.
While I can see how powerful these math functions are, I’ll be honest—it’s not always clear to me how they can be used. I find it really helpful to see how other developers have applied them, like this radial menu Una Kravets made using CSS trigonometry functions.
Sibling Functions
sibling-count()
and sibling-index()
are two new functions that make styling elements in relation to their siblings much easier. sibling-count()
returns the total number of siblings an element’s parent has. sibling-index()
returns the element’s index among its siblings, starting from 1. Temani Afif created a surprisingly simple marquee animation using these two functions.
Interpolate-size and calc-size()
If you’ve ever needed to animate an element’s height or width from a fixed value to an intrinsic size like auto
, you’ve likely had to resort to workarounds such as animating max-height
or using Javascript. With the interpolate-size
property, CSS now supports animating from numerical values to intrinsic sizes.
interpolate-size
defaults to numeric-only
so as not to break older stylesheets that assume animating to/from intrinsic values isn’t possible. To enable interpolation for intrinsic sizes, set it to allow-keywords
.
calc-size()
is a related feature that effectively sets interpolate-size: allow-keywords
and also allows you to calculate sizes based on an element’s intrinsic dimensions. It accepts two parameters: the first parameter specifies an intrinsic size to use as the base for the calculation and the second parameter takes an expression for computing the new size.
width: interpolate-size(auto, size)
is essentially the same as width: auto
.
width: interpolate-size(auto, size + 3rem)
adds 3rem to its natural width
width: interpolate-size(min-content, size * 3)
sets the width to 3 times its min-content
width
if()
Inline conditional logic has been possible in CSS using ‘hacks’ with custom properties (Lea Verou has written extensively on the topic), but it’s finally recently received official support. if()
accepts style queries, media queries, and feature queries as conditions. It also takes the else
keyword for fallback conditions. This contrived example sets the background-color conditionally on the value of a custom property named --variant
:
div {
background-color: if(
style(--variant: primary): white;
style(--variant: secondary): transparent;
else: teal;
);
}
There is a lot more to look forward to, like anchor positioning and shape()
, but there are also many existing and widely-supported CSS features that are less visible and don’t get much usage. I try to stay current by perusing knowledge bases like MDN and css-tricks from time to time and following personal and curated blogs like css-irl.info and piccalil.li.
Modern CSS is really powerful—the next time you go to style something with Javascript, maybe double-check if there isn’t a solution or ‘hack’ with CSS.
Loved the article? Hated it? Didn’t even read it?
We’d love to hear from you.