css-only dialog

zero bytes of javascript. the height animates to intrinsic content.
text reflows during the transition. not after.

the web shipped <details> in 2011. it shipped CSS grid in 2017. combining a checkbox hack with grid-template-rows: 0fr / 1fr gives you animated disclosure with no script, no hardcoded heights, no layout thrash. the browser does the work. you do less. that is the point.

the technique

the problem: CSS cannot transition height: auto. every framework ships javascript to measure, cache, and animate element heights. that is a runtime cost paid on every interaction.

the grid trick: a grid container with grid-template-rows transitioning between 0fr and 1fr. the fractional unit resolves to the child's intrinsic height. the browser interpolates between fractions. the child has overflow: hidden and a min-height for the collapsed preview. the content reflows continuously because the available height changes on every animation frame. no measurement. no javascript. no layout recalculation.

the toggle: a hidden checkbox. labels act as buttons. the :checked pseudo-class drives the transition. keyboard accessible via tabindex and role="button" on the labels.

demo: short content

bandwidth is finite

every kilobyte you send is a kilobyte the user pays for. on a metered connection, your hero image costs money. your analytics script costs money. your font costs money.

the user did not agree to fund your design preferences. they agreed to read your content. deliver the content. delete the rest.

demo: long content

the weight of the web

in 2024 the median web page was 2.3 megabytes. in 1997 the entire space jam website was 45 kilobytes. it still loads faster than most modern homepages.

we added frameworks to manage complexity that the frameworks introduced. we added build tools to optimize bundles that the build tools created. we added loading spinners to hide latency that our javascript caused.

the web got slower because we decided that developer experience was more important than user experience. DX is a euphemism for "I do not want to write HTML."

a document is the fastest thing the web can serve. it compresses well. it caches perfectly. it renders progressively. it works without javascript. it works on a 2G connection. it works on a ten-year-old phone.

every layer you add between the document and the user is a layer that can break, a layer that costs time, a layer that excludes someone. the question is never "can we add this?" the question is "does this justify its weight?"

most things do not.

demo: max-height + scrollable body

purchase: bandwidth audit

bandwidth audit report — $0.00
because the audit is a document. documents are free.

terms: you agree that every kilobyte has a cost. you agree that the cost is paid by the user, not the developer. you agree that a loading spinner is an admission of failure. you agree that system fonts exist and are beautiful.

you further agree that smooth scroll is a vanity. that parallax is not a feature. that a 2MB hero image of a laptop on a desk communicates nothing that the word "laptop" could not.

you accept that the browser is not a virtual machine. it is a document viewer. you will treat it accordingly. you will write HTML first. you will add CSS only when the document structure is insufficient. you will add javascript never.

these terms are non-negotiable. the bandwidth has already been allocated. the user is already waiting. ship less. ship now.

demo: max-height, short content (no scroll needed)

receipt

item: one semantic HTML element.
cost: 0 bytes of javascript.
total: free.

demo: expanded by default

already open

some dialogs should start open. the content is the reason the user came to the page. hiding it behind a click is not progressive disclosure. it is obstruction.

use expanded=true when the content is primary. use collapsed when the content is supplementary. the distinction matters.

total javascript in this component: 0 bytes.

browser support: the grid-template-rows transition works in Chrome 111+, Safari 17.2+, Firefox 126+. for older browsers the content simply appears without animation. that is progressive enhancement. the content is always accessible. the animation is a bonus.