Skip to content

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.

Common ratios ship as data-ratio presets. Omit the attribute for the default 1 / 1.

data-ratioRatioTypical use
omitted1 / 1Avatars, thumbnails.
16/916 / 9Video, hero images.
4/34 / 3Photos, cards.
3/23 / 2Photography.
2/12 / 1Wide banners.
21/921 / 9Cinematic / ultrawide.
9/169 / 16Portrait / 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>

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>
  • hc-aspect is a presentational wrapper — it adds no role or semantics. The child carries the meaning: give <img> a meaningful alt (or alt="" if purely decorative) and <iframe> a title.
  • Because the box reserves space before the image loads, it prevents the layout shift (CLS) that hurts both UX and assistive-tech reading order.

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; }
}
Show the generated CSS variables
--hc-aspect-ratio (default 1 / 1; set by data-ratio presets or inline)
  • Card — a common host for a ratio-locked cover image.
  • Avatar — a circular 1 / 1 image with an initials fallback.
  • Skeleton — pair with a ratio box as a loading placeholder.