Skip to main content

Top level navigation menu

A drawn image of Fredrik Bergqvist in a blue shirt

New CSS magic in 2024

Fredrik Bergqvist

Now and then I stumble upon some new CSS magic that I didn't know existed. Here are some of the new things I've found in 2024.

align-content: center

This is a really old one that I completely missed as I've gotten so used to using flexbox to align elements.

I did not know that align-content: center align the content like with flexbox, but display: flex is not actually needed.

Just regular text in a div
With align-content: center 💪

https://developer.mozilla.org/en-US/docs/Web/CSS/align-content

starting-style

This is a real gem! It will allow you to set a starting style for an element, which will be overridden by the actual style when the element is loaded.

So if you have a modal window which is hidden when the page is loaded, but visible when pressing a button, you can set the starting style to opacity: 0 and the actual style to opacity: 1. By also adding a transition to the modal, you can make it fade in nicely.

.modal {
	@starting-style {
		opacity: 0;
	}
	opacity: 1;
	transition: all 0.5s ease-in-out;
}

Right now we can only use this on an element enters the page (from hidden to visible), later on we will be able to add similar functionality for when an element leaves the page as well.

Limited, usable in all browsers but FireFox (2024-11-26)

https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style

:user-valid & :user-invalid

A classic problem when working with forms is to style the input fields when they are invalid. You want to signal when a form is invalid, but only when the user has actually interacted with the input field.

This is usually done with JavaScript, keeping track if an input has been touched or not, but now you can do it with CSS using the :user-valid and :user-invalid pseudo-classes.

input:user-invalid {
	border: 1px solid red;
}

input:user-valid {
	border: 1px solid green;
}

As you may have noticed, you actually have to type something before the field is marked as user-invalid, focus alone won't trigger the behavior.

Baseline 2023

https://developer.mozilla.org/en-US/docs/Web/CSS/:user-valid

CSS nesting

Nesting in CSS has felt like a part of the language, since preprocessors like Sass and Less have had it for a long time. But now it's finally here in CSS as well.

Before, you had to write something like this:

nav ul {
	margin: 0;
	padding: 0;
	list-style: none;
}
nav li {
	display: inline-block;
}

With nesting, you can write it like this:

nav {
	ul {
		margin: 0;
		padding: 0;
		list-style: none;
	}

	li {
		display: inline-block;
	}
}

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting

text-wrap: balance & pretty

The default behavior would look like this: (text-wrap: wrap)

The text is wrapped to the next line and disregards orphaned words.

Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore dolore

Using text-wrap: pretty will make sure we do not have orphaned words.

Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore dolore

While text-wrap: balance will balance the whole text, also making sure we do not have orphaned words.

Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore dolore

focus-visible

This is a pseudo-class that will only apply when the element is focused and the focus is not coming from a mouse click.


button:focus-visible {
	border: 1px solid green;
}
input:focus-visible {
	border: 1px solid green;
}

Try it out by tabbing to the button and input field, and then click the button.

Notice how the border turns green when you tab to the button field, but not when you click it.

The input field will have a green border both when you tab to it and when you click it.

This is what makes it so useful, as you can remove active style when clicking a button, but still offer support for keyboard navigation.

Baseline 2022

https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible

light-dark(#fff, #000)

This is a new function that will return the light color if the user has a light theme and the dark color if the user has a dark theme, so instead of using media queries to change the color, you can use this function.

:root {
  color-scheme: light dark;
}

body {
  background-color: light-dark(#f2f2f2, #333);
}

Baseline 2024

https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark

interpolate-size

:root {
	interpolate-size: allow-keywords;
	interpolate-size: numeric-only;
}

Experimental. Only works in Chrome (2024-11-26).

https://developer.mozilla.org/en-US/docs/Web/CSS/interpolate-size