A CSS Only Tabs Prototype (No JavaScript Required)
Component Kickoff
I was listening to an episode of Shop Talk Show that discussed putting native HTML elements inside web components instead of having the component insert them. For example, a fancy-checkbox component could contain a checkbox element:
Show Example
Or, it could be empty, pushing the responsibility for adding the checkbox element into the component itself.
Modal Pondering
The conversation got me wondering what you can do with a checkbox if there's no JavaScript running on the page. Specifically, I was wondering if you could do something like make a dark mode switcher using only HTML and CSS. The answer is, yes, you can.
Check this out:
There's no JavaScript involved. Everything happens thanks to this HTML:
Activate Dark Mode:
and this CSS:
}
}
}The magic is the :has() pseudo-class on the
body element on line 11. It watches the #mode-checkbox-x element
to see if it's check. When it is, it overrides
the default property variables to do the switch.
Tab Coded
Of course, the dark mode switcher doesn't set anything on the browser to maintain the mode between pages. You would need JavaScript for that.
However, there are other things that don't require keeping track of state across pages. Tabs come to mind. For example:
Again, no JavaScript. Just this HTML:
Tab 1
Tab 2
Tab 3
Content 1
Content 2
Content 3and this CSS:
}
}
}
}
}
}First Try
To be clear: this is a prototype. It's purpose is a first test to see what's possible. There's several things to investigate, including:
-
What's the accessibility of this like? Is it dead on arrival? Are there adjustments that can be made to bring it in line?
-
The radio buttons themselves being visible is pretty ugly. I'm pretty sure they can be hidden. TBD on what that does to accessibility.
-
The CSS is pretty verbose. It does an explicit check for each radio button and updates all the variables inside each check. I wouldn't be surprised to learn there's a more efficient way to do that.
Overall, it's very exciting. Even if there are reasons not to do it now, the continuing march of CSS makes me think it won't be long.
-a
References
- The CSS :has() pseudo-class which provides the horsepower for the functionality. It hit Baseline Widely Available in December 2023.
Endnotes
-
Thanks to Alex for introducing me to
:has()and showing me how to use it. -
If you've got feedback on the accessibility aspects of this approach please hit me up on Bluesky or Mastodon
-
Another thing I learned about is command and commandfor for buttons. Feels like there's a lot of potential there in future updates.
-
Another episode of Shop Talk Show was an interview with Dan Abramov about AT Proto. I'd been toying with the idea of creating a lexicon for Neopolitan (my markdown replacement format). After the episode, I'm absolutely gonna do it. The goal being to provide a nice way to created pages and posts using less than HTML but more than Markdown.
One of the biggest considerations is if JavaScript will be allowed. I love the idea of providing for interaction. I hate the idea of introducing the security issues that come with the language. Seeing this prototype seals the deal. Current CSS can do so much the reward of introducing the JavaScript risk isn't worth it. And, I expect CSS will get nothing but more powerful.