CSS Today: Powerful Features You Might Not Know About
BRACKETS by TRIAD
Software engineering for companies, startups, business growth, marketing & sales
CSS is constantly evolving — it recently got a new logo, and we at BRACKETS by Triad realized there have been so many new features released over the past year that haven't received much attention. We’re talking about stuff like finally being able to center a div without losing your mind, dealing with dark mode more easily, animating hidden elements, or using CSS to solve math problems. It’s like we can do more with less hassle now, so let’s check out some of these newer CSS features that showed up recently.
One-liner for centering
Yes, it finally happened. You no longer need to google how to center div each time you forget one of the multiple possible solutions. Since March of 2024, most modern browsers support align-content: center for block layouts as well. That means you can now easily center the children elements using one line, without the need for flexbox or grid layouts.
New CSS transition capabilities
Animating initially hidden elements has long been a challenging task in CSS. Two new CSS properties now provide an elegant solution to this age-old problem, allowing smooth animations for previously hidden elements across all major browsers.
The @starting-style rule lets you define initial styles for the element’s animation. When combined with transition-behavior: allow-discrete, you can now create animations for display: none or other discrete properties. This is particularly useful for elements like dialogs or popovers, which are hidden by default.
display: none and display: block styles are applied automatically for popover, so we don’t need to specify these in the example bellow, but for the sake of the demo, I included those styles as well.
Managing dark mode styles with ease
Writing styles for both light and dark mode was a little tedious since you had to use a @media (prefers-color-scheme: <color-scheme>) query for different color schemes. However, nowadays you can simply use the light-dark function as a shorthand for both light and dark color scheme queries. This way you can apply both styles using just one line, which might clean up some of the code, making it more readable in the end as well.
Styling (in)valid inputs
This feature isn’t exactly new but I only discovered it recently. Like some of you, I also sometimes use :valid and :invalid CSS selectors to style the form inputs based on their validation state. For basic forms, it works just fine. However, the issue with this approach is that the styles are applied instantly, without user interaction. Because of this, I often rely on JavaScript to conditionally apply styles only after the user modifies the input.
But worry no more — the :user-valid and :user-invalid selectors solve this problem with pure CSS. The styles are triggered automatically after the user moves focus away from the input or submits the form without prior interaction.
Adjusting the fallback font size
I guess everyone is familiar with the following issue: you are tasked to work on a cool website with some custom fonts, but you cannot find a good fallback font. When the custom font is not loaded for some reason, you realize that the website looks very different with the fallback font applied. And there was no way to solve this… until this year.
The font-size-adjust property solves this exact issue by allowing you to adjust your fallback font to better match the font of choice. Regardless of the font used, the text should appear more similar in size improving the CLS as well. It might take some tries to find the proper value to use but the result might be worth it as seen in the example below.
For all options, and how to properly calculate the values, please take a look at the MDN documentation.
Reducing page load using content-visibility
Since September of 2024, the content-visibility property is supported by all three major browser engines. What does it do you ask? It lazy-renders targeted elements to speed up the initial render of a website. For complicated websites with very deep or long HTML, this can help improve the time to render thus increasing the rendering performance.
When using content-visibility, be aware of potential side effects. As you scroll, targeted elements are rendered on-the-fly which can cause the page's scrolling height to change dynamically. This may result in a jittery scroll bar experience.
However, you can mitigate this issue using the contain-intrinsic-size property. This acts as a placeholder height, maintaining a smooth scrolling experience until the actual DOM is fully rendered. You can take a look at the example below for a better understanding.
CSS type-checking
You read that right — we can do a type-checking in CSS now. Everyone already knows CSS custom properties. They can be declared either in the :root or scoped within any selector. However, this way the browser doesn’t know what type the property is so you can reassign it freely to any other unit, and because of that, you are not able to animate it either.
You can now use @propertyrule which solves this issue by defining the property type and you can specify a default value as well. More importantly, using this approach, you can also very easily animate the property by defining custom @keyframes as seen on the codepen below.
If you try to reassign the property to a value with different type, it just simply won’t work and the aplied CSS rule will be ignored by the browser.
Math functions in CSS
CSS now comes equipped with a powerful set of math functions. Most of them were brought to the Baseline 2024 in May and they bring access to the very much-needed calculations. They provide powerful mathematical capabilities directly in CSS, allowing for more dynamic styling without relying on JavaScript, which is great news for all the CSS properties-driven animations.
领英推荐
The round() function
As you probably already guessed from the name, it rounds the value based on the parameters. The first parameter is the value you want to round and the second parameter is the rounding precision. That’s 1 by default, but can be adjusted based on the property. For example, while rounding opacity, you would prefer a precision of 0.1 instead of 1.
By default, the nearest strategy will be used:
font-size: round(12.3rem, 1rem); /* Returns 12rem */
There is also a third parameter, at the start, which specifies the rounding strategy. The default is nearest but you can use either one of these:
rotate: round(up, -83deg, 45deg); /* -45deg */
rotate: round(down, -83deg, 45deg); /* -90deg */
rotate: round(nearest, -83deg, 45deg); /* -90deg */
rotate: round(to-zero, -83deg, 45deg); /* -45deg */
The rem() function
The rem() function calculates the remainder of a division operation, just like the % operator in JavaScript. The value will always take the sign of the dividend (the first parameter).
margin-left: rem(32px, 5px); /* Returns 2px */
margin-left: rem(-32px, 5px); /* Returns -2px */
margin-left: rem(32px, -5px); /* Returns 2px */
margin-left: rem(-32px, -5px); /* Returns -2px */
The mod() function
The mod() function works similar to the rem(), but works slightly differently if the signs of the divisor and dividend are different. In that case, it looks for the multiple bigger than the dividend and returns the difference (note the example below). Also, compared to the rem(), result takes the sign of a divisor instead of a dividend.
margin-left: mod(32px, 5px); /* Returns 2px */
margin-left: mod(-32px, 5px); /* Returns 3px */
margin-left: mod(32px, -5px); /* Returns -3px */
margin-left: mod(-32px, -5px); /* Returns -2px */
The pow() function
The pow() function raises a number to a specified power. It takes two parameters: the base and the exponent. One thing to note is that this function only works with plain numbers without units. If you need to use it with units, you can do so by nesting it inside a calc function, like in the example below.
font-size: pow(2, 3); /* Returns 8 */
font-size: calc(1rem * pow(2, 3)); /* Returns 8rem */
The sqrt() function
The sqrt() function calculates the square root of a given number without a unit. It takes one parameter: the number you want to find the square root of.
width: sqrt(64); /* Returns 8 */
width: calc(1rem * sqrt(64)); /* Returns 8rem */
Pi, infinity, and beyond
CSS also provides some Math constants that can be used either with the new functions or simply by using calc. These are:
Putting It All Together
As you can see, modern CSS has evolved into a powerful toolkit that goes far beyond basic styling. The features we have explored today — from simplified centering to mathematical functions — show just how much can be accomplished with pure CSS now. And these are just the tip of the iceberg.
The CSS landscape is rich with other recent additions that have wide browser support: the game-changing :has selector, :empty for targeting empty tags, scroll-snap-type for creating CSS-only snapping animations, @container queries, and many more. And the evolution continues – new features like anchor-name, scroll-driven animations, and interpolate-size are already making their way into the Baseline.
What are your thoughts on these new CSS features? Drop a comment below to share your favorites, tell me which ones you’re missing, or suggest topics for my next deep dive!
If this article has been interesting to you, consider joining us live for our web developer conference Webstack in Bratislava, Slovakia where many other interesting themes are coming up!
?? The whole article is also available on our Medium – https://blog.meetbrackets.com/css-today-powerful-features-you-might-not-know-about-39adbbd5c65b
Author: Ján Timoransky , Senior Full-Stack Developer at BRACKETS