pure css* tabs
i've had a few people ask me about making tabs. there's an easy way to do it with css, using...
- url hashes — the text after a "#" in the url, usually used to auto-scroll to an element with a matching id
- :target — a css pseudo-class that selects the element referenced by the url hash
here's an example. say i want to navigate between a set of tabs, with only one visible at a time.
links can direct to url hashes like any other url; clicking a link with href="#id"
will append the hash "id" to your url. i can give each of my tabs a unique id and set up a corresponding link for each, like so...
<a href="#tab1">tab one</a>
<a href="#tab2">tab two</a>
<a href="#tab3">tab three</a>
<div class="tab" id="tab1">tab one</div>
<div class="tab" id="tab2">tab two</div>
<div class="tab" id="tab3">tab three</div>
by default, the document will automatically scroll to the first element with an id matching the url hash, so clicking on a link will scroll to its corresponding tab. that's nice but not exactly what i need.
i only want to show the tab matching the url hash, which i can select easily with :target
. to hide all tabs that aren't the current tab, i just invert the rule:
.tab:not(:target) {display: none}
and that's it!
flaws
this technique has some flaws, which need some javascript to be remedied.
first, if there is no url hash present, then all tabs are hidden. this is sometimes desired, but most of the time you want to show a tab by default. you can append a url hash without refreshing the page like so
if (!location.hash) history.replace(null, "", "#placeholder");
second, if you're on a scrolling page and the tab isn't right at the top, the document'll scroll down to that tab. you can kind of prevent this behavior by just scrolling back up to the top every time you change the hash
addEventListener("hashchange", () => scrollTo(0, 0));
ok have fun i love you