The Best of 2023’s CSS & UI Features

Yahia Berashish
Stackademic
Published in
5 min readSep 9, 2023

--

Google I/O 2023 blog cover.

There were a lot of new CSS & UI features added in the past few months, too much to cover in this article, so I’m going to tell you about what I think are the most exciting ones among them.

This article isn’t a full explanation of all the new features but instead intended to be a quick overview of those I found to be most exciting.
If you want a more detailed overview of the new features, consider reading this
Google Blog Post.

1. Container Queries

If you have ever used CSS before, you almost certainly have worked with media queries.

They enable you to create responsive layouts by adding breakpoints based on the width of the viewport from which the user is currently using your website.

But there was a problem: You couldn’t add breakpoints to a specific container, you had to add them based only on the viewport itself, which complicated the process of responsive web development by forcing you to a fixed number of breakpoints across the whole application, and that’s the problem container queries aim to solve.

With container queries – which are supported across all modern browsers – you can label an element as a container, and then apply styles to its children based on its size.

.my-container{
container: my-container / inline-size;
}

.child{
background-color: red;
}

@container my-container (width <= 500px){
.child{
background-color: blue;
}
}

2. :has() selector

The :has() selector is one of the most powerful new features added to CSS recently.

It allows you to apply styles based on the presence of specific children inside a parent element, or if those children are in a specific state, which means: we have a parent selector now!

Selecting a previous sibling

/*
selects an h1 element that has a p
element as its direct sibling
*/
h1:has(+ p){
margin: 0;
}

Applying styles based on the parent element

/*
selects a p element with an h1 element with
the class of .transparent as its parent element
*/
h1:has(.transparent) p{
opacity: 0.75;
}

3. Nesting

This is a simple but beautiful one, If you have used SASS before, you know one of its best features is nesting, and now, that amazing feature is natively supported in CSS!

.card {}
.card:hover {}

/* can be done with nesting like */
.card {
&:hover {

}
}

4. Cascading layers and Scoped style

Layers and scoping are revolutionary features for organizing your CSS.

Using layers, you can specify which styles should be prioritized, and with scoping, you can specify the scope that the styles will affect.

/* layers.css */

@layer base{

/* styles scoped to .card element */
@scope (.card){

.body{
background-color: white;
border: 1.5px solid #aaa;
}

.title{
color: black;
}

}

}

@layer dark{
@scope (.card){

.body{
background-color: black;
}

.title{
color: white;
}

}
}
/* style.css */

/*
“base” styles will be overridden
by “dark” styles since they are used after them
*/
@layer base, dark;
<div class=”card”>
<h3 class=”title”>
card title
</h3>
<div class=”body”>

</div>
<div/>

5. Customizable Components

Some of the most exciting new features are ones allowing you to control the UI in ways that would’ve required JavaScript to work, including:

Popover API

The popover API provides built-in popover functionality with event handlers, a declarative DOM structure, and accessible defaults.

<div id="event-popup" popover>

</div>

<button popovertarget="event-popup">Create New Event</button>

Anchor positioning

Anchor positioning is a new CSS API that enables anchor positioning between two elements.

To solve the problem of menus overflowing out of the screen, the API includes a fallback position that you can customize.

.center-tooltip {
position-fallback: --top-then-bottom;
translate: -50% 0;
}

@position-fallback --top-then-bottom {
@try {
bottom: calc(anchor(top) + 0.5rem);
left: anchor(center);
}

@try {
top: calc(anchor(bottom) + 0.5rem);
left: anchor(center);
}
}

<selectmenu>

<selectmenu> is a customizable dropdown menu component, for when you want to style content inside of a select.

<selectmenu>
<button slot="button" behavior="button">
<span>Select event type</span>
<span behavior="selected-value" slot="selected-value"></span>
<span><img src="icon.svg"/></span>
</button>
<option value="meeting">
<figure class="royalblue"></figure>
<p>Meeting</p>
</option>
<option value="break">
<figure class="gold"></figure>
<p>Lunch/Break</p>
</option>
...
</selectmenu>

Transitions and animations

The new updates also include some exciting additions to transitions and animations, including:

Discrete property transitions

Previously, properties like “display” couldn't be animated, but with discrete property transitions, such properties can be animated.

This is particularly useful for animating the newly added popovers and selectmenus.

Scroll-driven animations

Scroll-driven animations allow you to control the playback of animation based on the scroll position of the scroll container, making things like parallax backgrounds and reading indicators a lot easier to implement.

@keyframe scroll-animation{...}

.container{
animation: scroll-animation linear;
animation-timeline: scroll(root block);
}
const element = document.querySelector("#my-element");
element.animate(
{
transform: ["scale(0)", "scale(1)"]
},
{
fill: "forwards",
timeline: new ScrollTimeline({
source: document.documentElement,
})
}
)

View transitions

The View Transition API makes it easy to change the DOM in a single step while creating an animated transition between the two states, giving you the ability to easily implement page transitions in Single-Page Apps (SPAs), but Multi-page apps (MPAs) support is being currently worked on.

function spaNavigate(data) {
// Fallback for browsers that don't support this API:
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}

// With a transition:
document.startViewTransition(() => updateTheDOMSomehow(data));
}
@keyframes slide-from-right {
from { opacity: 0; transform: translateX(75px); }
}

@keyframes slide-to-left {
to { opacity: 0; transform: translateX(-75px); }
}

::view-transition-old(root) {
animation: 350ms both slide-to-left ease;
}

::view-transition-new(root) {
animation: 350ms both slide-from-right ease;
}

Conclusion

With the latest additions to CSS and HTML, new possibilities have been opened in frontend development, enabling some things that were simply impossible or at the very least very hard previously, and making less code do more.

Stackademic

Thank you for reading until the end. Before you go:

  • Please consider clapping and following the writer! 👏
  • Following us on Twitter(X), LinkedIn, and YouTube.
  • Visiting Stackademic.com to find out more about how we are democratizing free programming education around the world.

--

--