Options to toggle open additional content. HTML paper pages, for example, hold far more than a reader wants to see all at once, so they use every progressive disclosure mechanism we have: A "show more" link to toggle open a full author list, accordions for secondary metadata, and popovers for footnotes.
Using the native <details>/<summary> elements means no JavaScript is needed, and accordions are keyboard and screen-reader friendly by default. Another bonus is that the browser's find-in-page can open a closed panel to show a match inside it. A +/− glyph replaces the default marker.
<div class="ds-acc-stack">
<details class="ds-acc" open>
<summary>Versions</summary>
<div class="ds-acc-body">
<dl>
<dt>v3 · current</dt><dd>24 Apr 2026</dd>
<dt>v2</dt><dd><a href="#">2 Mar 2026</a></dd>
<dt>v1</dt><dd><a href="#">10 Jan 2026</a></dd>
</dl>
</div>
</details>
<details class="ds-acc">
<summary>Paper information</summary>
<div class="ds-acc-body">
<dl>
<dt>arXiv ID</dt><dd><a href="#">2604.22725</a></dd>
<dt>Subjects</dt><dd>gr-qc · hep-th</dd>
<dt>Licence</dt><dd><a href="#">CC BY 4.0</a></dd>
</dl>
</div>
</details>
<details class="ds-acc">
<summary>Related</summary>
<div class="ds-acc-body">Connected papers, datasets, and code links.</div>
</details>
</div>
<details>. Ruled: no box, no fill, no horizontal padding. The
label sits on the same left edge as the prose around it, with a rule above and below. The
<summary> is the label; the +/− marker comes from the stylesheet.<summary>. A
<dl> inside it renders as label and value pairs, one column on a narrow
screen.While an accordion hides an entire labelled section, the 'show more' control reveals the hidden tail end of partially displayed content. When hiding the remainder of a list we display the additional item count in the link.
A tail cannot be a details element, because a summary would put a heading in the middle of a sentence.
The rest of a paragraph
We study the convergence of stochastic gradient methods under heavy-tailed noise, and show that gradient clipping restores the optimal rate for a broad class of non-convex objectives, with matching lower bounds.
The rest of a countable list
Keywords: stochastic optimisation, heavy-tailed noise, gradient clipping, non-convex analysis, lower bounds, sample complexity, robust statistics
The rest of a list of links
<!-- The rest of a paragraph -->
<p>We study the convergence … under heavy-tailed noise<span id="abstract-tail" hidden>, and show that …</span>.
<button type="button" class="ds-show-more" aria-expanded="false" aria-controls="abstract-tail"
data-open-label="show less">show more</button></p>
<!-- The rest of a countable list: the label carries the count -->
<p>Keywords: stochastic optimisation, …<span id="keywords-tail" hidden>, non-convex analysis, …</span>
<button type="button" class="ds-show-more" aria-expanded="false" aria-controls="keywords-tail"
data-open-label="show fewer">show 4 more keywords</button></p>
<!-- The rest of a list of links -->
<ul>
<li><a href="#">R. Almeida</a></li>
…
<li><a href="#">L. Cheng</a></li></ul><span id="authors-tail" hidden>, <a href="#">T. Okonkwo</a>, …</span>
<button type="button" class="ds-show-more ds-show-more--among-links" aria-expanded="false"
aria-controls="authors-tail" data-open-label="show fewer">… show all 22 authors</button>
<button type="button"> at the end of the visible part. It takes
the link colour, because in running text it is the one thing a reader can act on. An
accordion is <details>, so the browser supplies the semantics; a tail
cannot be, so this is a real <button> that has to declare for itself what
the browser would otherwise have said, with the three attributes below."false" / "true", flipped on every toggle. Without it the control
announces as a button that does something unspecified.A quick lookup the reader can access without losing their place. Popovers are used on HTML papers pages for citations and footnotes, which is especially helpful for screen reader users. Popovers can contain nearly any type of content including links but should be used only for short bursts of information, or a list the reader opens, looks through and closes, such as the categories a report covers.
For a screen reader user, the trigger is an ordinary link whose accessible name includes the reference itself, such as “Reference 47: Ashtekar and Bojowald (2006)”, so most readers hear what they need without opening anything. Opening the popover does not move focus: the trigger reports that it is expanded, and the reader can continue through the main text. To read the popover, they move to it as a named region, from the screen reader's list of landmarks. Escape closes it and returns focus to the trigger.
Popovers resize to the content but should be reserved for short pieces of information. If the content gets too long it may not be contained within the viewport.
<span class="ds-popover" role="region" aria-label="Reference 47">
<div class="ds-popover-title">Reference 47</div>
<button type="button" class="ds-close">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
<span class="is-sr-only">Close reference 47</span>
</button>
Ashtekar, A. and Bojowald, M. <em>Quantum geometry and the Schwarzschild singularity.</em>
Class. Quantum Grav. 23 (2006).
<a href="#">Jump to reference</a>
</span>
position: fixed: the host sets top and
left, and moves it to <body> if the trigger has a transformed
ancestor. Closed, it has the hidden attribute.<span class="is-sr-only"> that says what it
closes.overscroll-behavior: contain
stops that scroll running on into the page beneath once it reaches the end.aria-expanded on the trigger, which is what gives the same fact to a
screen reader; the wash is the visible half of one state, not a decoration.Tabs switch between views of the same page. Each tab shows one panel and hides the others. To move between pages, use the secondary navigation instead.
1,284 member institutions in 46 countries.
2,391 submissions from member institutions this month.
4.2 million downloads from member institutions this month.
<div class="ds-tabs" data-label="Membership activity">
<section class="ds-tabs-panel">
<h3>Members</h3>
<p>1,284 member institutions in 46 countries.</p>
</section>
<section class="ds-tabs-panel">
<h3>Submissions</h3>
<p>2,391 submissions from member institutions this month.</p>
</section>
<section class="ds-tabs-panel">
<h3>Downloads</h3>
<p>4.2 million downloads from member institutions this month.</p>
</section>
</div>
<script src="tabs.js" defer></script>
data-label names the set for a screen
reader.<section> that starts with a heading. The heading
becomes the tab label.Need in-page navigation? The TOC bar is a row that holds a single disclosure control, which opens a list of the page’s sections. The bar is always sticky and it stays at the top of the viewport while the reader scrolls through the page.
<div class="ds-container">
<div class="ds-full ds-zone-secondary">
<header class="ds-page-header">…</header>
</div>
<div class="ds-full ds-toc-bar">
<div class="ds-toc-bar-inner">
<details class="ds-toc">
<summary class="ds-toc-trigger">
<svg aria-hidden="true">…</svg>
<span class="ds-toc-text"><span class="ds-toc-prefix">Contents</span></span>
<svg class="ds-toc-chevron" aria-hidden="true">…</svg>
</summary>
<nav class="ds-toc-menu" aria-label="Contents">
<ol></ol> <!-- written by hand, or left empty for toc.js to fill -->
</nav>
</details>
</div>
</div>
<section>…</section>
</div>
<script src="toc.js" defer></script>
<details>. It works on its own anywhere, and it opens
with JavaScript off.<summary>. Holds the list icon, .ds-toc-text with
its .ds-toc-prefix, and .ds-toc-chevron.<nav> holding an <ol>. The link to the
current section gets .is-current. A page whose sections are numbered puts each
number in .ds-toc-num..ds-container, with .ds-full. Placed directly after a
.ds-zone-secondary band, it sits on that band’s bottom edge. The bar is always sticky:
it keeps to the top of the viewport, where it becomes .is-stuck and
tightens, and it sets scroll-padding-top so an anchor lands below it.
Sticky chrome is governed by
DESIGN-POLICIES; check there before
adding the bar to a page..ds-toc: a selector for the element whose headings fill an
empty list. Without it, toc.js reads <main>, or the whole
page when there is no <main>.<ol> by
hand, or leave it empty and toc.js fills it when the page loads, with one link for every
h2 and h3 that has an id. A written list works with
JavaScript off, so these docs write theirs: verification/gen-anchors.py fills the
<ol> from the page’s section headings, and --check fails when the two
disagree.toc.js adds closing on Escape,
closing on a click outside, and the name of the current section on the control.toc.js drives the first
.ds-toc it finds, which on this page is the bar at the top; the control in the
card above comes later in the document, so it opens and closes on its own and nothing else.<details>
element, as the accordion and the TOC bar are, use it. It includes the expanded state, the keyboard
behaviour and the announcement without any script, and find-in-page can open a closed panel to reveal
a match. A hand-built accordion loses all four, and losing find-in-page on a research site is the
expensive one.<details>, the summary is the whole label. Never put a
second interactive control inside it — a link or button in a <summary> is reachable
but its activation fights the disclosure's own.hidden attribute, not with a class. Content hidden
by a class that fails to load is invisible but still tabbable, which puts a keyboard user in a place
they cannot see.aria-expanded. A show-more button and a
popover trigger are not <details>, so they state it themselves. Its absence is the
single most common defect in this pattern: the control announces as a button, does something visible
to everyone else, and says nothing.position: fixed, so left open it would follow
the viewport while the sentence it belongs to scrolls away.role="menu"
is for application menus — the kind with arrow-key roving focus and menu items that are not links. A
list of links is a disclosure, and W3C’s own guidance is to build it this way. Using
role="menu" here would make a screen reader promise keyboard behaviour the
component does not have.toc.js gives the TOC bar's link to the
current section aria-current="location".A disclosure inside another one is the second level: indented one step, its label a step smaller. Two levels is the limit a reader can follow. Shown inside a card with a heading, the paper reader's sidebar, where the stack ends the card and the card's own edge closes it.
<div class="ds-card">
<h3>Paper information</h3>
<div class="ds-acc-stack">
<details class="ds-acc" open>
<summary>Versions</summary>
<div class="ds-acc-body">
<dl>
<dt>v3 · current</dt><dd>24 Apr 2026</dd>
<dt>v2</dt><dd><a href="#">2 Mar 2026</a></dd>
<dt>v1</dt><dd><a href="#">10 Jan 2026</a></dd>
</dl>
</div>
</details>
<details class="ds-acc">
<summary>Metadata</summary>
<div class="ds-acc-body">
<details class="ds-acc">
<summary>Subjects</summary>
<div class="ds-acc-body">General Relativity and Quantum Cosmology (<a href="#">gr-qc</a>); Cosmology and Nongalactic Astrophysics (<a href="#">astro-ph.CO</a>)</div>
</details>
<details class="ds-acc">
<summary>Identifiers</summary>
<div class="ds-acc-body">
<dl>
<dt>arXiv ID</dt><dd><a href="#">2604.22725</a></dd>
<dt>DOI</dt><dd><a href="#">10.48550/arXiv.2604.22725</a></dd>
</dl>
</div>
</details>
</div>
</details>
<details class="ds-acc">
<summary>Related</summary>
<div class="ds-acc-body">Connected papers, datasets, and code links.</div>
</details>
</div>
</div>
A view has one level of tabs. Tabs inside a tab panel are not used.
The question that separates them is not how much is hidden. It is what relationship the hidden thing has to what the reader is looking at.
| Use | When the hidden content is | Costs the reader |
|---|---|---|
Accordion.ds-acc |
A labelled section the reader can decide about from its label alone — Versions, Paper information, Related. More than a line or two; a single line goes on the page. | One click, stays on the page, keeps their place. |
Show more.ds-show-more |
The tail of something already begun — authors nine through twenty-two, the rest of a category list, the rest of an abstract. There is no label to give it, because it is not a different thing. | One click, expands in place, no new surface. |
Popover.ds-popover |
A lookup the reader wants without leaving their sentence — what reference 47 is, what footnote 3 says. | Nothing permanent. It closes on Escape and does not move the page. |
| A link to a full page | Something with its own identity — a different paper, an author's other work, the full licence. | Leaves the page. Pay this only when the destination deserves a URL. |
.ds-show-more--among-links is for. Anywhere else, the default link colour is right.prefers-reduced-motion to switch off. An accordion that animates its height also
animates the position of everything below it, which is motion a reader did not ask for.z-index: 110, per the
Z-layer scale). A popover is always the thing
the reader just asked for, so it is never the thing that gets hidden.