Aspect ratio
hc-aspect reserves a box of a fixed proportion so media (and embeds)
keep their shape as the column resizes — no layout shift while an image
loads. It is pure CSS, built on the native aspect-ratio property; a
direct media child fills the box with object-fit: cover.
Basic HTML
Section titled “Basic HTML”<div class="hc-aspect" data-ratio="16/9"> <img src="/cover.jpg" alt="…" /></div>
<div class="hc-aspect" data-ratio="1/1"> <img src="/avatar.jpg" alt="…" /></div>Ratios
Section titled “Ratios”Common ratios ship as data-ratio presets. Omit the attribute for the
default 1 / 1.
data-ratio | Ratio | Typical use |
|---|---|---|
| omitted | 1 / 1 | Avatars, thumbnails. |
16/9 | 16 / 9 | Video, hero images. |
4/3 | 4 / 3 | Photos, cards. |
3/2 | 3 / 2 | Photography. |
2/1 | 2 / 1 | Wide banners. |
21/9 | 21 / 9 | Cinematic / ultrawide. |
9/16 | 9 / 16 | Portrait / stories. |
For any other ratio, set the custom property directly — no preset needed:
<div class="hc-aspect" style="--hc-aspect-ratio: 3 / 4"> <img src="/poster.jpg" alt="…" /></div>Embeds
Section titled “Embeds”An <iframe> (e.g. a video player or map) fills the box just like an
image, so responsive embeds need no padding wrappers.
<div class="hc-aspect" data-ratio="16/9"> <iframe src="https://example.com/embed/…" title="Demo video" allowfullscreen></iframe></div>The media child is cropped to fill (object-fit: cover) by default. Use
data-fit="contain" to letterbox the whole image inside the box instead.
<div class="hc-aspect" data-ratio="16/9" data-fit="contain"> <img src="/logo.png" alt="…" /></div>Accessibility
Section titled “Accessibility”hc-aspectis a presentational wrapper — it adds no role or semantics. The child carries the meaning: give<img>a meaningfulalt(oralt=""if purely decorative) and<iframe>atitle.- Because the box reserves space before the image loads, it prevents the layout shift (CLS) that hurts both UX and assistive-tech reading order.
Baseline & fallback
Section titled “Baseline & fallback”aspect-ratio and object-fit are Baseline 2021 (widely available
across current browsers), so no @supports gate is used. On a legacy
engine without aspect-ratio, the box collapses to its content height;
the historic fallback is the padding-top hack:
/* Only needed for engines predating Baseline 2021. */@supports not (aspect-ratio: 1 / 1) { .hc-aspect { position: relative; padding-top: 56.25%; /* 16:9 */ } .hc-aspect > * { position: absolute; inset: 0; }}CSS variables
Section titled “CSS variables”Show the generated CSS variables
--hc-aspect-ratio (default 1 / 1; set by data-ratio presets or inline)