📝 CSS-Tricks 281: Tabs and Spicy Drama

[Robin]: If you want to make a tab component today then you have to either

  1. Make your own custom tabs — which is a faff because making them is not easy at all or,
  2. Just npm install something popular.

Although, every project I’ve worked on in the last decade has its own custom tabs component—and to me that always feels like a waste. We keep reinventing the wheel over and over again!

So why isn’t there an HTML element to help us out here? Why isn’t there a <tabs> element that could do all the basics for us and make sure we’re doing things accessibly without having to build everything from scratch each time. The drama!

Dave Rupert wrote all about native HTML tabs back in October:

For the past year I’ve been on a team of folks inside Open UI dedicated to figuring out how get a native, accessible element into HTML. We’re a team of people with varying backgrounds; spec authors, browser vendors, implementors, and normie practitioners like myself. Open UI is a community group so we can’t technically make HTML (for legal reasons), but we can present research to the W3C working groups. I see Open UI as an ad hoc research arm for the W3C with specific experience in design systems and common web componentry.

Exciting! Except so far they’ve come to the conclusion that we don’t need a native <tabs> element in HTML at all. Their solution right now? spicy-sections, a web component that wraps any markup you’ve written and gives you a custom property that lets you change the component based on the width of the browser.

Chris made a real good example of this where it started to click for me. First, you need to import the custom element like this:


And then wrap it around your HTML…

<spicy-sections> <!-- any heading here, followed by an element containing content --> <h2>Ingredients</h2> <div>A list of ingredients</div> <!-- repeat the pattern... --> <h2>Instructions</h2> <div>A list of instructions</div> </spicy-sections>

Then you can use a CSS custom property built into <spicy-sections> which tells it how to behave and—watch out—this CSS I’m about to show you looks weird as heck:

spicy-sections { --const-mq-affordances: [screen and (max-width: 40em) ] collapse | [screen and (min-width: 60em) ] tab-bar; display: block; }

Weird! But also, that kiiinda makes sense to me. What’s happening here is you’re setting props for that web component and toggling between collapse and tab-bar when the browser meets those min-width/max-width conditions. Here’s an example Chris made where the largest browser width looks like this…

Great, we have tabs. Lovely. Next up, at smaller sizes, we have something like this where the content breaks out of the tabs into each of their own sections…

And then finally, at mobile-ish sizes, we have the following design where you can click each of these sections to pop them open…

I love this but I have a ton of questions. First up, it’s probably not going to be called <spicy-sections> when, and or if, it lands in browsers eventually. So what will it be called? Also, I’m not entirely sure I understand the greater implications on the rest of the HTML language here. Like, does this open up other doors to other features like tabs?

Oh, one last note: this chat between Dave and Chris all about <tabs> and this spicy-sections stuff is very much worth listening to if you’re more interested in all this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s