Creating a tab interface using CSS remains a popular topic in web development. Are they achievable? If so, can they be accessible? I first explained how to create them nine years ago and how to incorporate accessible practices into them.
While my earlier solution might still be relevant, I’ve developed a more modern method using the `
First, the HTML:
Start by setting up the HTML structure with a set of `
First item
Second item
Third item
These don’t look like true tabs yet, but it’s the right structure before implementing CSS with CSS Grid and Subgrid.
Next, the CSS:
Set up the grid for the wrapper element using CSS Grid. Create a three-column grid, one column for each tab, with some spacing between them. Also, set up two rows in the `.grid`, one sized to the content and another that maintains its proportion with the available space. The first row holds the tabs, and the second row displays the active tab panel.
“`css
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(200px, 1fr));
grid-template-rows: auto 1fr;
column-gap: 1rem;
}
“`
Now, set up the subgrid for the tab elements. Use subgrid to align with the main `.grid` lines without nesting a new grid. Set each `
“`css
details {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
“`
Ensure each tab element fills the entire `.grid` by using `grid-column` and `grid-row` properties:
“`css
details {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 1 / -1;
grid-row: 1 / span 3;
}
“`
Next, position the tab panel content in the second row of the subgrid and stretch it across all three columns using `::details-content`:
“`css
details::details-content {
grid-row: 2; /* position in the second row */
grid-column: 1 / -1; /* cover all three columns */
padding: 1rem;
border-bottom: 2px solid dodgerblue;
}
“`
To show only one open tab panel at a time, select the `[open]` state of the `
“`css
details:not([open])::details-content {
display: none;
}
“`
Turning `
Distribute the tabs evenly along the `.grid`’s top row. Each `
` for the tab label and button. Place the `
` in the first subgrid row and apply light styling when a tab is `[open]`:
“`css
summary {
grid-row: 1; /* First subgrid row */
display: grid;
padding: 1rem; /* Some breathing room */
border-bottom: 2px solid dodgerblue;
cursor: pointer; /* Update the cursor when hovered */
}
/* Style the
element when
is [open] */
details[open] summary {
font-weight: bold;
}
“`
Position the `
` elements in the subgrid’s columns using `:nth-of-type`:
“`css
/* First item in first column */
details:nth-of-type(1) summary {
grid-column: 1 / span 1;
}
/* Second item in second column */
details:nth-of-type(2) summary {
grid-column: 2 / span 1;
}
/* Third item in third column */
details:nth-of-type(3) summary {
grid-column: 3 / span 1;
}
“`
Use variables to keep styles DRY:
“`css
summary {
grid
Discover more from WIREDGORILLA
Subscribe to get the latest posts sent to your email.
“`css
summary {
grid-row: 1; /* First subgrid row */
display: grid;
padding: 1rem; /* Some breathing room */
border-bottom: 2px solid dodgerblue;
cursor: pointer; /* Update the cursor when hovered */
}
/* Style the
element when
is [open] */
details[open] summary {
font-weight: bold;
}
“`
Position the `
` elements in the subgrid’s columns using `:nth-of-type`:
“`css
/* First item in first column */
details:nth-of-type(1) summary {
grid-column: 1 / span 1;
}
/* Second item in second column */
details:nth-of-type(2) summary {
grid-column: 2 / span 1;
}
/* Third item in third column */
details:nth-of-type(3) summary {
grid-column: 3 / span 1;
}
“`
Use variables to keep styles DRY:
“`css
summary {
grid
Discover more from WIREDGORILLA
Subscribe to get the latest posts sent to your email.
details[open] summary {
font-weight: bold;
}
“`
Position the `
` elements in the subgrid’s columns using `:nth-of-type`:
“`css
/* First item in first column */
details:nth-of-type(1) summary {
grid-column: 1 / span 1;
}
/* Second item in second column */
details:nth-of-type(2) summary {
grid-column: 2 / span 1;
}
/* Third item in third column */
details:nth-of-type(3) summary {
grid-column: 3 / span 1;
}
“`
Use variables to keep styles DRY:
“`css
summary {
grid
Discover more from WIREDGORILLA
Subscribe to get the latest posts sent to your email.
/* First item in first column */
details:nth-of-type(1) summary {
grid-column: 1 / span 1;
}
/* Second item in second column */
details:nth-of-type(2) summary {
grid-column: 2 / span 1;
}
/* Third item in third column */
details:nth-of-type(3) summary {
grid-column: 3 / span 1;
}
“`
summary {
grid
Discover more from WIREDGORILLA
Subscribe to get the latest posts sent to your email.


