Tabs¶
hextra-tabs groups a set of mutually-exclusive content sections behind
a tab bar. It is the right choice when you have the same instructions
for several operating systems, several languages, or several install
methods, and you want the reader to see one at a time instead of
scrolling past all of them.
Syntax¶
Inside a hextra-tabs directive, each H3 (###) heading becomes a tab.
Everything between one H3 and the next is the tab’s body. There are no
options — the directive has no arguments and no fields.
```{hextra-tabs}
### macOS
Install with Homebrew:
brew install sphinx-hextra
### Linux
On Debian/Ubuntu:
apt install python3-sphinx-hextra
### Windows
On Windows with winget:
winget install sphinx-hextra
```
Rendered behaviour¶
A tab bar sits on top, with each H3 title rendered as a button. Clicking
a button shows the corresponding panel and hides the others. The active
tab has a coloured underline matching --hx-accent, inactive tabs are
dimmed to 70% opacity.
The active tab is persisted to sessionStorage keyed by the group’s
position on the page, so if a reader picks “Linux” in one tab group and
scrolls further down the same page, subsequent tab groups also start on
the matching label when possible. This behaviour is scoped to the browser
session — it does not persist across page reloads from a fresh tab, and
it does not sync across tabs.
On keyboards, left/right arrows move focus between tabs once the tab bar
has focus, and Enter/Space activates the focused tab. The panels are
linked by aria-controls / aria-labelledby so assistive technology can
navigate them as a tab set.
Three-tab example for a cross-platform install¶
```{hextra-tabs}
### macOS
```bash
brew tap example/tap
brew install example-cli
```
### Linux
```bash
curl -sSL https://example.com/install.sh | bash
```
### Windows
```powershell
winget install Example.CLI
```
```
Inside a tab body you can use any Markdown or directive — including
other hextra-* directives — as long as your backtick nesting is
consistent.
H1 + H3 and the myst.header warning¶
Because tabs split on H3 headings, a page that has an H1 at the top
and a hextra-tabs block with H3s will produce a MyST header-level
warning (“non-consecutive header level increase”) unless you suppress
it. sphinx-hextra’s own documentation suppresses this globally in
conf.py:
suppress_warnings = ["myst.header", "config.cache"]
You want this set in your own project too. It suppresses the one
specific warning that fires on legitimate uses of hextra-tabs and
hextra-steps inside titled pages, without suppressing anything else.
If you would rather not suppress the warning globally, you can use H2s
in the tabs directive — sphinx-hextra splits on H3s specifically, so
H2 content will not be recognised as a tab label. The best current
workaround is to live with the global suppression.