Interactive and immersive elements
The latest advancements in CSS have introduced a suite of interactive and immersive elements that enhance user engagement and elevate web experiences. Features such as popovers, anchor positioning, select menus, discrete property transitions, and scroll-driven animations provide designers with powerful tools to create intuitive and captivating interfaces. This section explores these innovative features, demonstrating how they transform web design by enabling more responsive, engaging, and visually rich interactions. Let’s start with the popover attribute.
Popover
Since April 2024, modern devices and updated browser versions have embraced the popover global attribute, revolutionizing the way we handle popovers in HTML. This attribute brings convenience, performance gains, and cleaner code—all with minimal reliance on JavaScript.
The popover global attribute is a game-changer for web developers. It automates popover behavior, reducing the need for custom JavaScript implementations. Here’s how it works:
- Automatic handling: Popover elements remain hidden (
display: none
) until triggered by an invoking/control element. This could be a<button>
or an<input type="button">
with apopovertarget
attribute. Alternatively, you can programmatically invoke a popover usingHTMLElement.showPopover()
. - Layer management: When a popover opens, it appears above all other elements in the top layer. No more wrestling with z-index values! Plus, parent elements position and overflow styling won’t interfere with your popover’s display.
To create a popover, use the following syntax:
<div id="popup" popover> … popover content </div> <button popovertarget="popup"> Hello, I'm a popover! </button>
One of the standout features of the popover global attribute is its light-dismiss behavior. Once a popover is opened, if the user clicks outside it, it will gracefully dismiss itself. No extra JavaScript is needed.
Since popovers are now natively handled, your application gains performance benefits. Next time you’re building a web app, consider embracing the popover global attribute. If you want to learn more about this feature, check out the official MDN documentation at https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover.
The next feature is a major overhaul: the <select>
element has been redesigned to allow greater customization. Let’s dive into the details!
New select menu
The <select>
element, as it currently exists, offers limited customization options for web developers. This often drives developers to create custom implementations, which can negatively impact performance, reliability, and accessibility compared to using native form controls.
Open UI, a community-driven initiative focused on standardizing and improving user interface components across the web, is actively working on developing a more customizable select menu. Their efforts aim to enhance the flexibility and styling capabilities of form elements while maintaining native performance and accessibility.
The future <select>
element will maintain its current behavior unless styled with the appearance: base-select
CSS property. In the past, suggestions for enabling additional customization included using a new tag name, adding an HTML attribute, or incorporating a child <button>
or <datalist>
.
Here’s an example of a basic <
select>
element:
<select> <option>one</option> <option>two</option> </select>
And here is the same <select>
element with the new styling behavior proposed in this explainer:
<select style="appearance:base-select"> <option>one</option> <option>two</option> </select>
The new customizable select menu offers significant benefits for developers by enhancing the appearance and functionality of dropdowns. The ability to replace the default button with a custom one provides greater control over interactions and visual styling, allowing seamless integration of custom-designed buttons with the overall UI. Moreover, developers can use CSS to style the listbox
and button
independently, allowing for more complex UI patterns and richer user experiences.
The menu also supports the inclusion of arbitrary content within the listbox
using <datalist>
, facilitating intricate layouts and advanced grouping within dropdowns. Furthermore, the new select menu includes support for animations when opening and closing listboxes, providing smoother transitions and enhancing the user experience.
Overall, these enhancements empower developers to create dynamic, accessible, and visually appealing web applications using native components that align with modern design principles. To stay up to date on discussions about improving form elements, take a look at the Open UI explainer on the new select menu: https://open-ui.org/components/selectlist/.
This feature is available in Chromium-based browsers by enabling the Experimental Web Platform features in about:flags
. Give it a try!
In the CSS realm, a new anchor()
function has been introduced to manage element positioning. Let’s explore this feature further.
Anchor positioning
The CSS Anchor Positioning CSS API allows for dynamic and flexible layout designs by tethering elements together. This feature is particularly useful in creating responsive designs where certain elements need to be aligned or positioned relative to others, regardless of changes in the viewport size or content updates.
The anchor()
function allows precise control over the position of elements relative to their anchors. It is used within the inset property of the anchored element and helps define relationships based on edge positions. The basic syntax is as follows:
anchor(<anchor-element> <anchor-side>, <length-percentage>)
<anchor-element>
is an optional name for the anchor element. If not provided, it defaults to the element’s position-anchor
property or its associated anchor.
<anchor-side>
is the side of the anchor element that the positioned element aligns with. Finally, <length-percentage>
is an optional fallback value for the function. Here’s an example demonstrating how to position a tooltip anchored to a button using the anchor()
function:
HTML
<body> <button id="anchorButton" class="anchor" aria-label="Button with tooltip" > Hover me! </button> <div id="tooltip" class="tooltip"> This is a tooltip. </div> </body>
CSS
.anchor { position: relative; width: 100px; height: 50px; background-color: #007bff; color: white; border: none; cursor: pointer; } .tooltip { position: absolute; inset: anchor(anchorButton end, 10px) 0 auto 0; background-color: #333; color: #fff; padding: 5px; border-radius: 3px; visibility: hidden; } .anchor:hover + .tooltip { visibility: visible; }
In this example, button
is used as the anchor, defined with an ID of anchorButton
. The tooltip is positioned using the anchor()
function, tethered to the end side of the anchorButton
, with a 10-pixel offset. Also, the tooltip becomes visible when hovering over the button, demonstrating a basic interaction without JavaScript. Figure 13.11 shows the visual outcome:
Figure 13.11 – Tooltip created with CSS anchor() function
This approach provides a clean and efficient way to manage element positioning in complex layouts, leveraging the power of CSS for responsive design. Next, we’ll see about the new CSS discrete properties transitions.
Discrete property transitions
In the realm of web design, creating smooth transitions and animations has always been a key aspect of enhancing user experience. Traditionally, CSS animations were limited to properties that could transition smoothly over time, such as opacity or transform. However, recent advancements have introduced the ability to animate discrete CSS properties, opening new possibilities for developers.
As we discussed in Chapter 5, browsers are now supporting the animation of discrete properties as part of efforts to improve transitions for elements such as popovers, select menus, dialogs, and custom components.
Discrete properties are those that typically toggle between distinct values, such as moving elements to and from the top layer or transitioning display states, such as display: none
.
Generally, these properties flip between two values at the midpoint, or 50% of the animation. This is unlike continuous properties, which transition smoothly over the duration of the animation.
To utilize these new capabilities, developers can use the transition-behavior
property. This property allows discrete animations to be specified alongside traditional continuous transitions, providing a unified approach to animation design. Here’s an example:
.element { transition: display 0.5s ease-in-out; transition-behavior: allow-discrete; }
In this example, the transition-behavior: allow-discrete
rule enables the discrete animation of the display property. This allows developers to incorporate complex animations seamlessly into their web projects, enhancing the interactivity and visual appeal of their interfaces.
Continuing with the theme of animations, CSS has recently introduced scroll-driven animations. Let’s delve into how this feature functions.
Scroll-driven animations
Scroll-driven animations are increasingly popular in modern web design, providing engaging and interactive user experiences. These animations are directly linked to the scroll position of a container, meaning that as users scroll up or down, the animation progresses in sync with their scroll actions. Common examples include parallax effects, where background images move at different speeds than the foreground, and scroll-based reading indicators that advance as you move through content.
Traditionally, implementing scroll-driven animations involved responding to scroll events on the main thread, which often led to performance issues. This approach could cause lag and stutter, affecting the overall smoothness of the animation.
With the release of Chrome version 115, a new set of APIs—Scroll Timelines and View Timelines—has been introduced to revolutionize scroll-driven animations. These concepts integrate seamlessly with the existing Web Animations API (WAAPI) and CSS Animations API, enabling animations to run smoothly off the main thread. This advancement means you can achieve silky smooth, scroll-driven animations with minimal code and without compromising performance. Here’s a simple example of a progress bar demonstrating how to use CSS scroll-driven animations:
<style> @keyframes grow-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } } #progress { position: fixed; left: 0; top: 0; width: 100%; height: 1em; background: red; transform-origin: 0 50%; animation: grow-progress auto linear; animation-timeline: scroll(); } .content { height: 200vh; width: 100px; background-color: linear-gradient( 180deg, #e75656, #fff ); } </style> <body> <div id="progress"></div> <div class="content"></div> </body>
In this example, the animation scales an element horizontally from scaleX(0)
(invisible) to scaleX(1)
(fully visible) over time, using the scroll()
timeline function, which synchronizes the animation with the scroll position of the container.
For more demos and tools to explore scroll-driven animations, visit https://scroll-driven-animations.style/. Scroll-driven animations are powerful tools for creating engaging and interactive web experiences. As these technologies continue to evolve, they offer a compelling way to enrich user interfaces and create memorable, immersive web experiences. Next, we’ll explore the latest developments in colors and visual effects.