← All articles

motion-components 0.7: A Theme Toggle With a Circular Wipe

Version 0.7 of motion-components adds two new elements: <motion-theme-toggle> and <motion-theme-icon>. The toggle switches a page between a light theme, a dark theme and the system theme. The icon morphs from sun to moon, and an optional circular wipe can reveal the new theme. This release also upgrades the animation library underneath, Motion, from version 11 to version 13.

You can see the toggle now: the theme menu in the header of this site is a <motion-theme-toggle>.

Install

The toggle sets two things on the <html> element: a data-theme attribute and the color-scheme CSS property. Your own CSS reads the attribute:

Four appearances

The appearance attribute chooses how the control looks.

AppearanceWhat it showsBest for
icon (default)One button with the sun or moon iconA site header with little space
toggleA segmented control with one option for each themeSettings pages
switchA switch with “Light” and “Dark” labels on each sideForms and preference panels
menuA button that opens a drop-down listA header that also offers “System”

Add the system attribute to offer a third option. When the user chooses “System”, the page follows the OS setting, and it changes when the OS setting changes.

The optional page wipe

By default, the theme changes at once. A wipe animates the whole page, and on most sites that is too much for a control people use often. Add the wipe attribute when you want the theme change to stand out, for example on a landing page:

The wipe uses the View Transitions API. The browser takes a picture of the page before the change. Then the toggle changes the theme, and the browser takes a second picture. The toggle shows the new picture inside a circle and makes the circle grow.

The circle starts at the center of the control. It grows until it covers the farthest corner of the window. Motion drives the circle with its animateView function and a spring with no bounce, so the edge does not overshoot.

If the user clicks again during a wipe, the toggle stops the running wipe and starts a new one. Two wipes never run at the same time. Browsers without the View Transitions API change the theme at once, with no error.

The icon is its own element

The morph between sun and moon lives in <motion-theme-icon>. You can use it alone, for example as a status indicator:

When mode changes, the sun rays shrink and turn, and a circle slides in to cut the sun into a crescent moon. For the “System” mode, the icon shows a half filled circle. Every part moves on a spring, so a fast change of mind reverses smoothly from the current position.

Compatible with dark-mode-toggle

The attributes and events follow dark-mode-toggle from Google Chrome Labs. If your page already uses that element, most of your markup works without changes.

Featuredark-mode-togglemotion-theme-toggle
mode, appearance, legend, light, dark, remember, permanentYesYes
colorschemechange and permanentcolorschemechange eventsYesYes
Switching stylesheets that use a prefers-color-scheme media queryYesYes
A third “System” optionNoYes
A drop-down menu appearanceNoYes
A custom target element instead of <html>NoYes, with target
Animated iconNoYes
Optional circular wipeNoYes, with wipe

With permanent, the toggle saves the choice in localStorage and restores it on the next visit. A toggle that themes <html> saves under the key motion-theme. A toggle with a different target saves under its own key, so a themed card does not change the theme of the whole page.

Prevent a flash of the wrong theme

Web components start after the browser paints the page for the first time. For a short moment, the page can show the wrong theme. To prevent this, put this small script in the <head> of your page. It follows the same rules as the toggle: first the saved choice, then the OS setting.

Accessibility

Every appearance works with the keyboard and with screen readers.

AppearanceRole for screen readersKeys
icon and switchA switch with an on and off stateSpace or Enter
icon with systemA button that names the current modeSpace or Enter
toggleA group of radio buttons with a labelArrow keys
menuA menu button with a list of optionsArrow keys, Home, End, Enter, Escape

If the user turns on the reduced motion setting of the OS, the theme and the icon change at once. There is no morph and no wipe.

Motion 13

The library now depends on Motion 13 instead of Motion 11. The attributes and events of the existing components did not change. If your own code also imports motion, update it to version 13. Then your bundler includes one copy of Motion instead of two.

What comes next

A later version will make the attribute names more consistent across all 40 components. For example, every time value will use seconds. The release notes will list every renamed attribute.

Read the motion-theme-toggle documentation for every attribute, event and CSS custom property.