React Aspect Ratio Examples — Video, Image, Portrait
Copy-paste React Aspect Ratio examples — 16:9 video embed, responsive hero image, square avatar tile, portrait video clip, and Next.js Image integration.
Aspect ratio is one of those CSS problems that looks trivial in a screenshot and gets fiddly in production. The container has to stay the right shape whether it holds a 1920x1080 still, a YouTube iframe, a Ken Burns zoom, or a Next.js Image with fill. Ship it wrong and the page reflows every time media finishes loading, or the image crops unexpectedly on mobile, or the overlay text drifts half a line away from where the designer placed it in Figma.
Drivn's AspectRatio handles this in fifteen lines of React. It takes a ratio prop — either a string preset like "16/9" or a raw number like 2.35 — and writes the value directly to the container's aspect-ratio CSS property. The container is position: relative and overflow: hidden out of the box, so absolutely-positioned overlays anchor to the ratio box automatically. The default ratio is "16/9", which fits most hero images, video embeds, and media cards without any prop at all.
This page collects five AspectRatio patterns you will actually ship: a default 16:9 video container, a responsive hero image, a square avatar tile, a portrait 9:16 reel clip, and the two-line integration with Next.js Image fill. Every snippet is copy-paste and assumes Drivn is already installed via the CLI. For an engineering comparison against shadcn/ui's AspectRatio, see Drivn vs shadcn/ui AspectRatio.
Default 16:9 video embed
The single most common AspectRatio use is a 16:9 container for an embedded video — YouTube, Vimeo, Loom, Wistia, or a self-hosted <video> element. Drivn's default ratio is "16/9", so you can omit the prop entirely for this case. Children fill the container with w-full h-full, and the overflow-hidden default keeps any slight oversizing clipped cleanly to the ratio box edge.
Drop this snippet into a marketing page, a course lesson, or a product landing hero. Because the ratio is locked at 16:9, the iframe never triggers cumulative layout shift when it loads — the space is reserved by CSS before any JavaScript runs. The aspect ratio docs cover the full prop list and API reference.
1 import { AspectRatio } from '@/components/ui/aspect-ratio' 2 3 // Default ratio is "16/9" — the prop is optional 4 <AspectRatio> 5 <iframe 6 src="https://www.youtube.com/embed/dQw4w9WgXcQ" 7 title="YouTube video" 8 className="w-full h-full" 9 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 10 allowFullScreen 11 /> 12 </AspectRatio>
Responsive hero image
For a hero banner or landing-page image, pair AspectRatio with a single <img> styled w-full h-full object-cover. The object-cover rule ensures the image fills the ratio box and crops the overflow rather than distorting the pixels. Add rounded-lg or rounded-2xl on either the container or the child for rounded media cards that match your card component radius.
This pattern also works for responsive product images on e-commerce grids. Pair the 16/9 ratio with a max-width on the parent container and the image scales fluidly down to mobile without ever changing shape. The browser serves the right resolution through a srcset on the img tag if you configure one — nothing about AspectRatio is specific to srcset handling, so the usual HTML rules apply.
For a more advanced setup that layers a gradient and text overlay on top of the image, the container is already position: relative, so overlays anchor inside the ratio box without an extra wrapper div.
1 <AspectRatio ratio="16/9"> 2 <img 3 src="/hero.jpg" 4 alt="Team collaborating" 5 className="w-full h-full object-cover rounded-lg" 6 /> 7 </AspectRatio>
Square 1:1 avatar tile
Square aspect ratios show up in profile galleries, team pages, and Instagram-style grids. Use the "1/1" string preset — one of the three built-in values alongside "16/9" and "4/3" — and combine it with a Tailwind grid for a responsive gallery that stays square on every breakpoint. Each tile renders its child image with w-full h-full object-cover so cropping stays consistent across the grid.
For user avatars specifically, Drivn's dedicated Avatar component is the stronger choice — it ships rounded fallbacks, image loading states, and consistent sizing presets. AspectRatio is the right tool when you need a square media tile that is not a user avatar: product thumbnails, blog card covers, collection tiles, or album artwork. The rendered DOM is identical at runtime; the API choice is about intent, not visual output.
1 <div className="grid grid-cols-2 md:grid-cols-4 gap-4"> 2 {images.map((img) => ( 3 <AspectRatio key={img.id} ratio="1/1"> 4 <img 5 src={img.url} 6 alt={img.alt} 7 className="w-full h-full object-cover rounded-lg" 8 /> 9 </AspectRatio> 10 ))} 11 </div>
Portrait 9:16 reel clip
Vertical video is now the default shape for short-form content — TikTok, Instagram Reels, YouTube Shorts, and Spotify Video all render at 9:16. AspectRatio handles this with a custom numeric ratio of 9 / 16, which resolves to 0.5625. You pass the division expression directly or the evaluated number, whichever reads better in the surrounding code.
Constrain the parent container to a maximum width around 320-400 pixels for a natural mobile-preview feel on desktop. Without the constraint, a 9:16 box becomes taller than most viewports and pushes subsequent page content far below the fold. The parent should also avoid overflow: hidden at the section level if you want the embedded player's fullscreen controls to escape the ratio box on user interaction.
For a gallery of reel clips, combine this ratio with a horizontal scroll container. The ScrollArea component gives you styled native scrollbars and snap-scrolling behavior without a third-party dependency.
1 <div className="max-w-sm"> 2 <AspectRatio ratio={9 / 16}> 3 <video 4 src="/reel.mp4" 5 className="w-full h-full object-cover rounded-xl" 6 controls 7 playsInline 8 /> 9 </AspectRatio> 10 </div>
Next.js Image with fill
Next.js's Image component gives you automatic srcset generation, blurhash placeholders, and lazy loading. Render it with the fill prop as a child of AspectRatio and the framework handles all the responsive sizing details. Set sizes to help Next.js pick the right resolution at each viewport width — a typical value for a hero image is "(max-width: 768px) 100vw, 50vw".
Because AspectRatio provides a container with explicit dimensions through the native aspect-ratio property, Image fill has a concrete box to fill. This pattern avoids the older trick of wrapping the image in a relative div with a padding-bottom hack; the ratio is enforced by CSS rather than by layout math. The rendered HTML stays minimal — two nested wrappers and the Next.js-generated <img> with its srcset.
See the Installation guide for how to set up next/image with Drivn, and the theming docs for how media cards in light and dark mode should tune their background placeholder colors before the image loads.
1 import Image from 'next/image' 2 import { AspectRatio } from '@/components/ui/aspect-ratio' 3 4 <AspectRatio ratio="16/9"> 5 <Image 6 src="/hero.jpg" 7 alt="Hero" 8 fill 9 sizes="(max-width: 768px) 100vw, 50vw" 10 className="object-cover rounded-lg" 11 /> 12 </AspectRatio>
Install Drivn in one command
Copy the source into your project and own every line. Zero runtime dependencies, pure React + Tailwind.
npx drivn@latest createRequires Node 18+. Works with npm, pnpm, and yarn.
Frequently asked questions
The default is "16/9", set as the default value of the ratio prop inside src/components/ui/aspect-ratio.tsx. Change it by editing the default in the destructured prop signature — for instance to ratio = "4/3". Because the component file lives in your repo after install, the change is permanent and survives every future package update. Most teams keep the "16/9" default and override per call site when needed.
Functionally they are identical — AspectRatio writes the same aspect-ratio property to the container via inline style. The component exists to give you a consistent, typed API across your codebase, so every ratio-locked media box uses the same wrapper rather than scattered one-off class names. It also bakes in position: relative and overflow: hidden defaults that media containers usually want anyway.
Yes. The container is a block-level div with w-full, so it expands to fill the available width of its flex parent and then calculates height from the ratio. If the flex parent has align-items: stretch on a row layout, the AspectRatio will not grow vertically beyond its computed ratio. In a column layout with flex-grow set on a sibling, the AspectRatio stays at its ratio-derived height naturally.
Yes. A common pattern is an outer AspectRatio for a card tile with an inner AspectRatio for the card's thumbnail at a different ratio — for example a 4:3 card containing a 16:9 thumbnail above a title block. Each level has its own ratio prop and resolves independently. There is no performance cost to nesting; every instance is a single div with one inline style and three Tailwind utility classes.
Yes. The ratio is enforced by the aspect-ratio CSS property on the container, not by the children's intrinsic size. An empty AspectRatio still reserves its ratio-correct box, which is why the pattern works for skeleton loading states — render an empty container with a bg-muted class while the real content fetches, and the layout stays stable the moment the image or video slots in.