How to Use the Details Tag for Creating CSS Tabs

Creating tabs in a webpage can greatly enhance navigation and improve the user experience by organizing content in a visually appealing and accessible way. One of the simplest methods to implement tabs is by using the HTML <details> and <summary> tags, combined with some clever CSS styling. In this post, I’ll guide you through the process of creating tabs using these HTML elements, step by step.

Step1: Tabs Structure With HTML

This HTML code demonstrates how to transform the <details> tag into a tabbed interface, leveraging CSS for seamless visual integration and JavaScript to enforce tab-like behavior where only one tab remains active at a time, enhancing the user experience with controlled interactivity.

<h1>HTML Details Tag</h1>
<div class="details-tabs">
<details class="details-item" open> <!-- default first "tab" to open -->
<summary class="details-tab">Overview</summary>
<div class="details-content">
<p>Visualize a component similar to an accordion, which supports keyboard interaction right out of the box and doesn't depend on JavaScript for its functionality.</p>
<p>That's what the details tag brings to the table.</p>
<details>
<summary>Example</summary>
<p>This is what the inside of a details tag looks like.</p>
</details>
<p>The details tag provides a straightforward accordion experience by default, which is excellent. However, its potential extends further—what if it could function as a tab control?</p>
</div>
</details>
<details class="details-item">
<summary class="details-tab">Transforming</summary>
<div class="details-content">
<p>While tabs and accordions share similar underlying mechanics, tabs usually require distinct parent and child containers for the tabs and their respective contents.</p>
<p>Another key difference is their interactivity; accordions can be manipulated individually, but tab interfaces maintain one active tab at all times.</p>
<p>Initially, it might seem challenging to adapt the details tag for tab functionality due to structural, layout, and functional discrepancies, but these challenges can be addressed with a closer examination.</p>
</div>
</details>
<details class="details-item">
<summary class="details-tab">Leveraging CSS</summary>
<div class="details-content">
<p>By utilizing the CSS property <strong>display: contents;</strong>, it's possible to visually eliminate the boundaries of the details tags, allowing their contents to blend seamlessly within the document flow.</p>
<p>Imagine having several small containers each filled with a mix of distinct items. These containers can only interact at a surface level, not allowing deeper interaction among the contained items. With <strong>display: contents;</strong>, it's as though these barriers are removed, mixing everything into one coherent group.</p>
<p>Now, all elements within the details tags can be reorganized flexibly using CSS's <strong>display: flex;</strong> and <strong>order</strong> properties, creating a clean separation of tabs and their content while maintaining a fluid layout.</p>
</div>
</details>
<details class="details-item">
<summary class="details-tab">Enhancing User Experience</summary>
<div class="details-content">
<p>Although the goal was to minimize JavaScript usage, achieving a true tab-like behavior requires minimal scripting. This involves monitoring attribute changes and preventing toggling actions from keyboard and mouse that conflict with expected tab functionality.</p>
<p>The essential behavior to implement is keeping one tab active at all times, which involves toggling sibling details tags appropriately when a new tab is activated.</p>
</div>
</details>
</div>

Step2: Styling With CSS

This CSS code defines a visually appealing style for a tabbed interface using the HTML <details> tag. It sets a consistent typography, color scheme, and layout, enhancing user interaction by modifying background, color properties on hover/focus, and rearranging elements using the order property for a clean, organized appearance.

body{
font-family: "Libre Franklin", Arial, sans-serif;
max-width: 50rem;
margin: 4rem auto;
background: #1e8266 !important;
color: #ddd;
padding: max(calc(50vh - 22rem), 1rem) 1rem 1rem;
font-size: 18px;
}
h1 {
margin-bottom: 2em;
text-align: center;
color: #fff;
}
h1 span {
color: #77b728;
}
p {
color: #ffffff7f;
font-size: 1.2rem;
line-height: 1.66;
font-weight: 300;
margin: 1rem 0 1.5rem;
}
p strong {
color: #ddd;
font-weight: 700;
}
.details-tab {
padding: 0.5rem 1rem;
font-size: 1.1rem;
color: #ffffffcc;
font-weight: 600;
display: block;
order: 0;
background: #ffffff13;
border-radius: 1.5rem;
margin-right: 0.35rem;
margin-bottom: 0.5rem;
cursor: pointer;
border: 2px solid transparent;
}
.details-tab:hover, .details-tab:focus {
border-color: #fff;
}
.details-tab::-webkit-details-marker {
display: none;
}
.details-tabs {
position: relative;
justify-content: center;
display: flex;
flex-wrap: wrap;
}
.details-content {
order: 1;
padding: 1rem;
width: 100%;
}
.details-content details {
margin: 1.5rem;
}
.details-content details summary {
font-weight: 600;
}
.details-item {
display: contents;
}
.details-item[open] > .details-tab {
background: #fff;
color: #333;
}

Step3: Tab Behavior with jQuery and MutationObserver

This JavaScript code utilizes jQuery and the MutationObserver API to enhance the behavior of HTML <details> tags, making them function like tabs. It ensures that only one tab remains open at a time by closing others when a new tab is opened and prevents the active tab from being closed via keyboard or mouse interactions, mimicking typical tab functionality.

(function($) {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
$.fn.attrchange = function(callback) {
if (MutationObserver) {
var options = {
subtree: false,
attributes: true
};
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(e) {
callback.call(e.target, e.attributeName);
});
});
return this.each(function() {
observer.observe(this, options);
});
}
}
})(jQuery);
// when one details opens, close the others
$('.details-item').attrchange(function(attribute){
if(attribute == "open" && $(this).attr("open")) {
$(this).siblings(".details-item").removeAttr("open");
}
});
// keyboard: prevent closing the open details to emulate tabs
$('.details-tab').on("keydown", function(e) {
if(e.keyCode == 32 || e.keyCode == 13) {
if($(this).parent().attr("open")) {
e.preventDefault();
}
}
});
// mouse: prevent closing the open details to emulate tabs
$('.details-tab').on("click", function(e) {
if($(this).parent().attr("open")) {
e.preventDefault();
}
});

Step4: CDNs

https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js

How to Use the Details Tag for Creating CSS Tabs Demo

Using the HTML <details> and <summary> tags along with CSS for styling provides a straightforward method to create functional tabs without the need for complex frameworks or libraries. This approach is not only easy to implement but also keeps your code clean and maintainable.

You Might Be Interested In:

Ashfaq Ahmed is a freelance WordPress developer and owner of codeconvey.com. I developed modern and highly interactive websites. I always focus on improving my development and design skills.

Leave a Comment