Tabs
3 minutes read
Tabs show one section at a time and let the reader pick another. They are for any content, not only code: install steps per platform, one topic per audience, or a short and a long explanation. A choice made by hand is remembered and applied to every tab group on the page that offers the same label.
Syntax
A container directive whose body holds one ## or ### heading per section. The heading's text is the tab label and starts that section:
:::tabs{group="install-beacon"}
### macOS
```bash
brew install beacon
```
### Linux
```bash
curl -fsSL https://get.example.com | sh
```
### Windows
```powershell
winget install beacon
```
:::
group is the group's key. Give each group on a page its own key; when two groups share one — the same key twice, two names that sanitize alike, or no key at all — the first keeps the ids it published and each later group's ids gain a -2, -3, … suffix, so links never land on the wrong group. The heading text is also the label the island syncs on, so two groups that both offer Linux switch together.
A heading may author its own link target: ### Install notes {#notes} labels the tab Install notes and keeps #notes pointing at the section; a heading written with an id attribute is honored the same way. The fragment is carried onto the generated panel title, so it resolves with and without JavaScript. A malformed marker ({#with space}) stays as literal label text.
Options
| Option | Type | Default | What it does |
|---|---|---|---|
group |
string | generated | The group's key and the prefix for its element ids. Repeats on a page gain a suffix past the first group. |
id |
string | — | Fallback id prefix when group is absent. |
Example
macOS
Use Homebrew, or download the darwin archive.
Linux
Use the linux archive and put beacon on your PATH.
Windows
Use the windows archive and add its folder to Path.
Notes
- Without JavaScript the tab list stays hidden and every section shows stacked under its title, so nothing is locked behind a control that does not run.
- Every tab, panel, and title id is unique on the page: a group that repeats another's key renders under a suffixed key, and one group's ids can never move another group's selection.
- Choosing a tab by hand is remembered in
localStorage["lateen-tabs"]and switches every group on the page and on later pages that offers the same label. ?tab=in the URL chooses a label and beats what is remembered;?lang=works too, because the sync module is shared with code tabs.- Choosing a tab by hand also writes
?tab=<label>into the address bar, keeping every other query parameter, and does not reload or move the page, so the address can be shared. A link that opens the page with that parameter starts on the same tab. - A fragment that points at a panel, or at a heading inside one, opens that panel on load even when a shared
?tab=would leave it closed. Following a fragment after load — an in-page link, or Back and Forward — opens the owning panel as well. Fragments and?tab=labels that no longer match anything are ignored, and a group that stays stacked is never touched. - Arrow keys move between tabs,
HomeandEndgo to the ends, and the arrows follow the reading direction in right-to-left pages. - Use OS tabs when the sections are operating systems and the reader's system should win, or code tabs when the choice is a language or package manager.
- Component islands are not wired into built pages yet, so a built site shows the no-JavaScript state — every section stacked — until island wiring lands.