The last time I seriously worked with CSS was back when Firefox was still a relevant browser (š¢), and Internet Explorer 11 was just on its way out.
Flexbox had just become a popular way to create layouts, and CSS Grid was new and exciting, but not yet widely supported. Not that I could use either, since IEās implementation of flexbox was so riddled with bugs that it was practically unusable.
But now. Weāre in 2024, and things have changed. A lot.
Here are a few of my favourite features of modern CSS, in no particular order:
CSS Variables
CSS variables were once only possible with a preprocessor like SASS or LESS, but now theyāre a native feature of CSS.
Here is how to define a variable:
:root {
--primary-color: #ff0000;
}
Specifying the variable at the root level makes it available to the entire document.
The variable can then be used with the var()
function:
div {
color: var(--primary-color);
}
The neat thing is that variables follow the cascading logic of CSS, so you can update their value at any level of the document, and all elements that use that variable will automatically update.
See the Pen CSS Variables by Loris Bognanni (@codemade) on CodePen.
Nesting in CSS
This is again one of those things that you would have needed a CSS preprocessor for in the past, but is now a native feature of CSS. Useful for keeping your code concise and readable.
.parent {
color: red;
.child {
color: blue;
}
}
I especially find this useful when styling pseudo-elements and states:
button {
background-color: blue;
&:hover {
background-color: red;
}
&:after {
content: 'š';
}
}
Centering a div
is now very easy
Centerig a div
has long been a recurring joke amongst web developers, but thanks to CSS Grid, itās now a two-liner:
div.parent {
display: grid;
place-items: center;
}
Viewport units
Viewport units are a way to size elements based on the size of the viewport. They are particularly useful for creating responsive designs.
Viewport units include vw
(viewport width), vh
(viewport height), vmin
(the smaller of the two), and vmax
(the larger of the two). So for example, if you want an element to be half as wide as the viewport, you can do this:
.my-element {
width: 50vw;
}
Here is an example that combines viewport units and CSS Grid to center a div in the middle of the screen:
See the Pen centering by Loris Bognanni (@codemade) on CodePen.
Math in CSS
CSS has a calc()
function that allows you to perform calculations right in your stylesheets. This can be useful for things like calculating widths, margins, and padding.
The exciting thing about calc()
is that it can combine different units of measurement, so you can do things like this:
.my-element {
width: calc(50% - 20px);
}
You can of course use calc()
with variables as well:
:root {
--margin: 20px;
}
article {
margin: calc(var(--margin) * 2);
}
CSS Containers, container queries, and container measurements
By telling CSS that a certain element is a container
, you can now do things like size its children based on the containerās size, or apply styles based on the containerās size.
Similar to viewport units, container units are based on the size of the container element. They include cqw
, cqh
, cqmin
, and cqmax
.
See the Pen Untitled by Loris Bognanni (@codemade) on CodePen.
Container queries take this a step further by allowing you to apply styles based on the size of the container. This is particularly useful for creating responsive designs where the layout changes based on the size of the container, rather than the viewport.
aspect-ratio
property
If you ever wanted to embed a video in your responsive page in the old days, you probably had to use some javascript to calculate the correct height based on the width of the video.
But now, you can use the aspect-ratio
property:
.video {
width: 100%;
aspect-ratio: 16 / 9;
}
:has()
selector
The :has()
selector allows you to select an element based on its descendants. This can be useful for styling elements based on their content, or for selecting elements that contain a specific child element.
While before :has
you would have to use javascript or some sort of preprocessing to achieve the same effect, now you can do it with a single line of CSS.
For example, here is a simple way to style a <label>
element when its child <input>
is checked:
See the Pen :has demo by Loris Bognanni (@codemade) on CodePen.