zero-height-side-element
Layout pattern for placing a side element (toggle, badge, icon) that visually occupies horizontal space but does not affect the row's vertical height. Use when building list rows, settings rows, or an
SKILL.mdskills/zero-height-side-element/SKILL.md
GitHubZero-Height Side Element
A flexbox technique for placing a side element (toggle, badge, icon button) in a row without letting it dictate the row's height. The element still occupies its natural horizontal width and remains vertically centered.
Problem
In a flex row with items-center, the tallest child determines the row height. A large side element (e.g. a 28px toggle in a row with 20px text) stretches the row, breaking consistent spacing set by padding alone.
Using position: absolute solves height but removes the element from flow, losing its horizontal space reservation and requiring manual right / padding-right management.
Pattern
Wrap the side element in a zero-height flex container with centered alignment:
<div className="flex items-center justify-between px-4 py-3.5">
<span className="min-h-[1lh] min-w-0 truncate">{label}</span>
<div className="flex h-0 shrink-0 items-center">
<Toggle />
</div>
</div>;
How It Works
| Class | Purpose |
|---|---|
h-0 |
Container contributes zero height to the flex cross-axis |
shrink-0 |
Prevents the wrapper from being compressed by flex |
flex items-center |
Centers the child vertically relative to the wrapper's position |
min-h-[1lh] on the text |
Guarantees the row never collapses to zero when text is empty |
The wrapper sits in normal flow — it occupies horizontal space just like any flex child — but its zero height means the row's cross-size is determined solely by the text element and the container's padding.
Why Not absolute
position: absolute removes the element from the document flow in both axes — block (vertical) and inline (horizontal). This means:
- The side element no longer reserves horizontal space.
- If the left-side text grows long, it will overlap the absolutely positioned element because flex doesn't know it's there.
- You must manually manage
rightoffset and matchingpadding-righton the container to prevent collision.
The zero-height wrapper only opts out of the block axis (height). In the inline axis (width) it remains a normal flex child — shrink-0 ensures it keeps its natural width, and justify-between pushes it to the trailing edge. When the left-side text is long, flex's min-w-0 truncate on the text element causes it to shrink and ellipsize before it reaches the side element, because the side element legitimately occupies that space in the flow.
absolute: [text overflows underneath] [toggle floating on top]
zero-height: [text truncates with ...] [toggle]
When to Use
- Settings / toggle rows where padding controls row height
- List items with trailing badges or action buttons
- Any row where side content is taller than primary content
When NOT to Use
- Side element height should legitimately determine row height
- Complex multi-line layouts where absolute positioning is more appropriate