[Proposal] CSS "toggle" Pseudo Class

Currently it seems that isn’t possible to toggle property(s) in CSS. I want to be able to click on this sidebar thing and have it toggle between open and closed.

<!DOCTYPE html>
<meta charset="UTF-8">
<title>Some Page...</title>
.thing {
  transform-origin:0% 0%;
  border:3px solid #339955;
  transition: left 1s;
.thing:active {
.top {
  border:3px solid #335599;
  width: calc(100% + 10px);
<div class="top">Top Thing</div>
<div class="thing">Side Thing</div>

That code in action: https://www.w3schools.com/code/tryit.asp?filename=FRQAB0QBSE04

If this becomes a reality, this could have some really useful applications. (like the one above)

.thing:toggle {left:26px;}

CSS doesn’t have the ability to permanently change based on events. That’s what JavaScript is for. Something like the example you provided is doable in a few lines of JS at most.

I recall @tabatkins had a toggle idea long ago http://tabatkins.github.io/specs/css-toggle-states/ … Don’t recall what ever happened to it…

1 Like

I think a toggle state handled via CSS would be pretty amazing. Right now it’s possible but with a lot of wonky complex hacks. Right now it is only really easy to do with JavaScript. But, with mobile being super important we know the less scripting all around to send and run the better. One great example of a toggle system like what Tab has mocked up is the ability to do a hidden navigation drawer on mobile cleanly with only CSS.

I think making as much layout as we can use the least amount of JS possible the better. So I’d love to see some more exploration in this area.


I think it would likely only be a part of a good drawer (in otherwords, probably still wouldn’t be css only) since in order for it to be accessible I think you’d have more to do… but yeah, it would be interesting.

Well, in combo with the Edge team’s idea that the inert attribute could also be implemented as a CSS property to toggle the same effect. That would provide a powerful CSS only combo for many various parts of a great UX.

1 Like

We can already close dialogs with <form method=dialog> but no way to open dialogs without JS.

This feature would help solving that … we’re not toggling html attributes here… however I wonder: how would CSS toggles provide feedback on open/closed (etc.) states to screen readers?

I’d expect for external tools taking advantage of the Accessibility Tree that the state would be observed, on modification do a check on what needs to be updated. Just like how a visibility change affects a11y tree.

1 Like


I have concerns that a CSS toggle would merely provide status feedback of the togglable element’s visibility and not e.g. a controlling element (aria-controls="menu").

For e.g. you mention a css-only mobile drawer scenario. Currently one could convey a menu button as controlling an expandible element by setting aria-expanded="false" and aria-haspopup="true" to a <button>. Would a CSS property be able to convey such infomation?

Maybe https://drafts.csswg.org/css-ui/#keyboard could be extended to allow for such controls.

I did throw in a quick proposal in the discussion I linked to in my earlier reply for a <button type="toggle"> attribute. Which in addition would take a toggle="{open|hidden} attribute with 2 values to toggle the controlled element between (using for="controlledElement"). This would allow for easier ARIA-mappings of roles/states.

I’m not saying that a CSS only drawer would be perfect in terms of a11y. It would however be great to have it function well, and let the JS focus more on the a11y improvements to help in other areas.

CSS alone can’t control everything, but if we can get the baseline of support there which helps make things more accessible w/o JS. Then JS can pop in when available to make the experience even better.

That sounds like the <details> element. You can even style the open state via the [open] attribute selector.

Here’s a demo.

Details is a very specific case where it works right. In this case, like a navigation drawer that slides in from the side of the screen, it doesn’t work. Plus there is no way for a toggle within the drawer to them change the state further without JavaScript.

Details is close, but very limited use cases that are almost all in flow content.


I put this together for you: https://codepen.io/anon/pen/ERvoPa

If you’re on google chrome it’ll even look pretty :grin:

Although CSS toggling would be nice to have, I think a new HTML toggle ability would achieve so much more. Obviously it’d allow styling through CSS anyways. You could toggle HTML attributes, such as open, hidden, inert, aria-*, data-*, class etc.

1 Like

Very close, but the linchpin for why it doesn’t work is quoted above. The close toggle should be an item within the drawer for accessibility. Plus, it is a common pattern to have a backdrop over the page when a side drawer is displayed so the user’s focus is on that context.

Really, very close but the concept doesn’t hold up once you add all the other needs into the system for a good design that is also accessibly done.

Sure, the <details> element is close, but it is a little more buggy.

I wouldn’t use the <details> tag because is not supported in Microsoft Edge and other older browsers. The only way (as far as I know) to add context or a summary is through the <summary> tag, which has a similar incompatibility problem to the <details> tag. The <summary> tag also has the problem of Chrome not supporting the list-style CSS property for it. Chrome instead uses a non-standard pseudo element, ::-webkit-details-marker.


I have had cases where I wanted to have the user click on certain text and have it be replaced by other, alternative text to help users understand something if they don’t already.


.replace-text-1::after {content: "the London underground,";}
.replace-text-1::after:toggle {content: "a transit system serving London,";}

Though as you mentioned, @Malvoz, next to your example you said, “If you’re on google chrome it’ll even look pretty.” That is also one of my problems. Not everyone is on Google Chrome, so for all of the users not on Google Chrome, your example looks really choppy. Either more browsers need to pick up on your styles, or we need to make an alternative that is smoother and more versatile.

More HTML tags and attributes is not the solution for that problem in my opinion. After all, HTML wasn’t ever meant to deliver high-end content. CSS is far more dynamic, but still quick loading for old browsers and mobile devices.

Browser support in itself for the element compared to what you want isn’t really relevant. You’re asking for something supported by no one currently. By the time even this gets built and supported, we may very well have details everywhere. MS already says it is a high priority item and they plan to start soon on developing it. So within two or three releases I’d wager we have it.

The summary styling mods are also more “meh” to me. I’ve modified it personally in the past. It is easy to deal with and not a major issue.

The primary point is, having a CSS Toggle system allows for numerous far more versatile designs without scripting. And in the future possibly even more easily accessible systems as well. This helps us (hopefully) reduce the amount of scripting going on which speeds up the web for users on constrained resource devices. Which is a major benefit to a very large chunk of users.

Adding a new feature because some other feature isn’t supported doesn’t make much sense. I do agree that using figure/details/summary for a menu isn’t appropriate either, and that’s a stronger argument to me.

1 Like

Yea, you’re right. Compatibility isn’t the main focus, but CSS togglability can be useful in many scenarios.

Dunno if anything like this is useful. It’s a bit futuristic, ie. it needs a shift in viewpoint, and would probably need to be a completely separate branch of CSS in the future. But here’s an example of how CSS could potentially be used as a higher-level alternative to JavaScript. There’s a toggle-class command in there somewhere. Those basic things are surprisingly nicer to use in practice than attaching to the page elements via the JS API. I don’t know much about the styling engine, but it would probably need to be a new branch of CSS rather than be part of the existing engine for it to work.


This doesn’t seem like it belongs in CSS or HTML but it’s repetitive and verbose to do in JS. It certainly seems like it should be easier.

Maybe there needs to be a new declarative pattern-action language that lets you name some elements by CSS selectors then say things like, “when this event happens to this element and these conditions are met, change these attributes/properties on that element and maybe fire another event”. I think the only other thing it would need to do would be to let you focus elements.

I’m not sure exactly what that would look like but it seems like it could cover a lot of cases more compactly than JS.

It could let you set aria-expanded to its opposite value on a button when it’s clicked and let you focus that button when the menu drawer closes.

It could also let you show a textbox when the Other radio is selected and hide it when not.

CSS can handle the associated presentational changes when the attributes change and if necessary JS can listen to/send custom events or just check the value of attributes.