Kingsley Ubah 21. Web Developer. Technical Writer. African in Tech.

Advanced guide to the CSS toggle() pseudo-class

4 min read 1358

Advanced Guide To The Css Toggle Pseudo Class

In mid-April of 2022, Chromium announced that it’ll begin prototyping compatibility with CSS Toggles, a new CSS feature that is currently only available as an unofficial draft.

CSS Toggles is a declarative mechanism for associating a “toggleable value” with an element, as well as setting and modifying that value. You can also use CSS Toggles in selectors within CSS to select an element for the purpose of styling or adding interactivity.

Included in the draft is toggle(), a functional pseudo-class that makes it possible to select elements based on a toggle state. In this article, we will explore what is currently known about this upcoming CSS feature, including what makes it exciting and some of its potential use cases.

Jump ahead:

Note that because CSS toggle() is still currently an unofficial draft, what we know about this pseudo-class is subject to change.

Why CSS toggle() is an exciting upcoming feature

Before toggle(), you could only leverage the inbuilt browser states to style elements or add interactivity. For example, the checkbox input has :checked, a built-in browser state related to form inputs that you can use to change the input’s appearance once it’s checked.

With toggle(), you can create your own custom states on any element and define style variations for the different states. The spec also comes with properties such as toggle-visibility and toggle-group, both of which will be particularly useful for building disclosure widgets like tabs and accordions.

Let’s see some examples.

Using toggle() to select an element based on its toggle state

You can define an element’s state in CSS with the toggle-root property and describe how the state will change based on user interaction with the toggle-trigger property. Then, you can have the element respond to the state change using the toggle() pseudo-class.

Consider the following button:

    <button>TOGGLE ME!</button>

    <p>Demo for <em><a href="" target"_top"></a></em></p>

We want the button to have two toggleable states — though you can have more than two. Each state will have a given set of styles associated with it.

The following example shows an easy way to do this using the CSS toggle() pseudo-class. We register the toggle in the HTML root element, define the button as the toggle activator, and then describe what should happen when the toggle switches:

html {
  toggle-root: switch;

button {
  toggle-trigger: switch;
  background-color: black;
  color: white;

html:toggle(switch) button {
  background-color: white;
  color: black;

With the above CSS, when the toggle value is changed by clicking the button, we simply change the button’s background and text color to white and black respectively. Below is a demo of this behavior:

See the Pen Toggle button demo by Kingsley Ubah (@kingsleyubah)
on CodePen.

If you’d like to make your button more visually dynamic, check out our guide to animating a button in CSS.

Note that an element can be both the toggle root and the toggle trigger. In that case, use the toggle shorthand property. The following example demonstrates this case:

li {
  toggle: check self

li:toggle(check) {
  color: silver;
  text-decoration: line-through;

Here, the list items are both toggle root and trigger. As a result, when an item is clicked, we change the text color to silver and strike a line through it:

See the Pen Toggle list items demo by Kingsley Ubah (@kingsleyubah)
on CodePen.

Next, let’s take a look at toggling visibility.

Using toggle-visibility to toggle the visibility of elements

With the toggle-visibility property, you can build different kinds of expanders — collapsible components such as tabs, accordions, popups, and detail or summary widgets — without having to write a single line of JavaScript code. This property allows an element to automatically tie its display to the state of a particular toggle.

Using toggle-visibility also provides extra accessibility benefits by allowing the unrendered content to be accessible when searched or accessed with features like find-in-page, hash-based navigation, or tab order.

Let’s consider the following description list:

<dl class="accordion">
  <dt>What is HTML?
  <dd>Hyper Text Markup Language is the standard markup language for documents intended to be viewed in a web browser
  <dt>What is CSS?
Cascading Style Sheets is used to describe the appearance of a document wtitten in HTML or some other markup language

The descriptions <dd> are hidden by default. We want to expand the description only when the corresponding title is clicked. Here’s the CSS for adding that effect:

.accordion > dt {
  background-color: black;
  margin-bottom: 10px;
  padding: 5px 5px;
  width: 120px;
  color: white;
  toggle: show;
  .accordion > dd {
    margin-bottom: 10px;
    toggle-visibility: toggle show;

And here’s the demo for that behavior:

See the Pen Demo of toggle-visibility effect by Kingsley Ubah (@kingsleyubah)
on CodePen.

You can also create toggle groups using this CSS pseudo-class. Let’s look at that next.

Using toggle-group to group exclusive toggles

If you have multiple toggles, you can group them together with the toggle-group property. Keep in mind that only one toggle from the group can be active at a time. This is similar to how HTML radio buttons behave, where two buttons cannot be checked at the same time.

With that behavior in mind, you could use toggle groups to describe patterns where you have multiple branches of content that are mutually exclusive, meaning only one of them can be shown at a time. Two examples are tabs and accordion or dropdown menus.

Consider the following HTML:

  <button>tab one</button>
  <p>tab one content</p>
  <button>tab two</button>
  <p>tab two content</p>
  <button>tab three</button>
  <p>tab three content</p>

Given that only one of the three paragraphs is to be shown at a given time, we can define the exclusive or grouped behavior using toggles:

div {
  /* Set group on a common ancestor */
  toggle-group: tab;

button {
  /* Creates sticky tabs and declares itself a toggle activator */  
  toggle: tab 1 group sticky;

button:first-of-type {
  /* The first tab is active by default */
  toggle: tab 1 at 1 group sticky;

button:toggle(tab) {
  /* Specify how you want the active
  tab/button to look */

p {
  /* Visibility of paragraph is 
  linked to toggle state */
  toggle-visibility: toggle tab;

With the above CSS, the visibility of each paragraph is tied to its activator — in this case, its respective button — and only one paragraph can appear at a time. The first paragraph is visible by default.

Other features of the CSS toggle() pseudo-class

There is a lot more to the draft than the basic examples we covered. Here are some other behaviors to keep in mind:

  • A toggle root can contain multiple toggles
  • It’s possible to have more than one active state in a toggle
  • The toggle state is set to inactive by default, but this can be overridden
  • You can also represent states with a set of words, not just numbers
  • Sticky toggles are always active because there’s always at least one active item
  • State machines with transitions are being considered

Again, keep in mind that CSS toggle() currently remains available as an unofficial draft only. These behaviors may be updated or changed over time.


When fully implemented across web browsers, CSS toggles will be an incredibly useful tool for CSS authors.

It’s quite a powerful feature that’ll no doubt make the process of adding interactivity to HTML elements much easier. Of course, it’ll take time to properly grasp the whole syntax, but it’ll be time well invested.

Do you have any questions regarding this new feature? Let me know in the comments below.

Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.

LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web and mobile apps — .

Kingsley Ubah 21. Web Developer. Technical Writer. African in Tech.

One Reply to “Advanced guide to the CSS toggle() pseudo-class”

Leave a Reply