Utility component that maintains a fixed aspect ratio for any child content.
Use this component to display images, videos, maps, iframes, or any embed that must maintain a predictable width-to-height ratio regardless of its container width. Zero JavaScript — pure CSS.
How it works
The outer <div> uses the padding-top trick to enforce the aspect ratio:
padding-top: calc(1 / ratio * 100%)Because padding percentages in CSS are calculated relative to the element's
width, setting padding-top to 1/ratio * 100% creates a box whose
height is always proportional to its width. The inner <div> is then
absolutely positioned with inset: 0 to fill this space.
| Ratio | Float | Resulting padding-top |
|---|---|---|
| 16:9 | 16/9 | ~56.25% |
| 4:3 | 4/3 | ~75% |
| 1:1 | 1.0 | 100% |
| 21:9 | 21/9 | ~42.86% |
| 9:16 | 9/16 | ~177.78% (portrait) |
| 3:2 | 3/2 | ~66.67% |
Examples
Responsive hero image (16:9)
<.aspect_ratio ratio={16 / 9}>
<img src="/images/hero.jpg" alt="Mountain landscape" class="object-cover w-full h-full" />
</.aspect_ratio>Product gallery card (4:3)
<.aspect_ratio ratio={4 / 3} class="rounded-lg overflow-hidden">
<img src={@product.thumbnail} alt={@product.name} class="object-cover w-full h-full" />
</.aspect_ratio>Embedded YouTube video (16:9)
<.aspect_ratio ratio={16 / 9}>
<iframe
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
title="Video player"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen
class="w-full h-full"
/>
</.aspect_ratio>Square avatar or profile image (1:1)
<.aspect_ratio ratio={1.0} class="rounded-full overflow-hidden w-32">
<img src={@user.photo} alt={@user.name} class="object-cover w-full h-full" />
</.aspect_ratio>Portrait social card (9:16)
<.aspect_ratio ratio={9 / 16} class="max-w-xs">
<div class="w-full h-full bg-gradient-to-b from-primary to-primary/80 p-6 flex flex-col">
...
</div>
</.aspect_ratio>Interactive map embed
<.aspect_ratio ratio={16 / 9} class="rounded-lg overflow-hidden border">
<iframe
src="https://maps.google.com/maps?q=New+York&output=embed"
title="Location map"
class="w-full h-full"
/>
</.aspect_ratio>Notes
- Always set
class="w-full h-full object-cover"(or similar) on child<img>elements so they fill the constrained box without distortion. - The outer
<div>isposition: relative w-full— add width constraints viaclass(e.g.class="max-w-sm") to limit the component's width. overflow-hiddenmust be on the outer container (via:class) for rounded corners to clip the child content.
Summary
Functions
Renders a container that maintains a fixed aspect ratio.
Functions
Renders a container that maintains a fixed aspect ratio.
The outer <div> uses padding-top to lock the ratio; the inner <div>
uses position: absolute; inset: 0 so child content fills the full space.
Example
<.aspect_ratio ratio={16 / 9}>
<img src="/poster.jpg" alt="Movie poster" class="h-full w-full object-cover" />
</.aspect_ratio>Attributes
ratio(:float) - Aspect ratio expressed aswidth / height. Default1.0(square). Common values:16/9,4/3,21/9,9/16. Defaults to1.0.class(:string) - Additional CSS classes applied to the outer wrapper<div>. Usemax-w-N,rounded-*, andoverflow-hiddenhere. Defaults tonil.- Global attributes are accepted. HTML attributes forwarded to the outer
<div>(e.g.data-*,aria-*).
Slots
inner_block(required) - Content to render inside the aspect-ratio-constrained space. Setclass="w-full h-full"on child elements to fill the box.