15 CSS Aspect Ratio Demos
15 hand-coded CSS aspect-ratio demos: 16:9 YouTube iframe embed with click-to-load facade, 21:9 hero video, 1:1 Instagram grid, 4:3 blog cards, 9:16 stories rail, 4:5 product gallery, 1:1 zoom carousel, CLS-zero placeholder with live meter, IAB ad slots (728×90 / 300×250 / 300×600), responsive <dialog>, orientation + container-query playground, and side-by-side padding-top hack → modern aspect-ratio migration. 11 Pure CSS + 4 tiny JS snippets, WCAG 2.2 AA, Baseline browser support since Sep 2021. Scoped under .car-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.
Related20 CSS Container Queries22 CSS Image Galleries15 CSS Card Grid Layouts31 CSS Hero Sections14 Tailwind CSS Wave Section Dividers
Course pickPartner: Zero to Mastery
Affiliate linkWant to build production-ready CSS layouts, animations and UI from scratch?
You just browsed 15 aspect-ratio demos. Learn the Flexbox, Grid and animation thinking behind them, so the next component starts in your head, not in a copy-paste.
Every ZTM course in one membership: $25/month, paid yearly at $299 · 30‑day money-back guarantee
The CSS Bootcamp. We may earn a commission, at no extra cost to you.
02. CSS Aspect Ratio Full Screen Hero Video (opens in a new tab)
03. CSS Aspect Ratio Square Grid Items (opens in a new tab)
04. CSS Aspect Ratio 4 3 Card Image Cover (opens in a new tab)
<img> keep the page CLS-clean while photos stream in. A magazine front page with one 16:9 lead story proves you can mix ratios in one system without a single fixed height.05. CSS Aspect Ratio Vertical Story Card 9 16 (opens in a new tab)
06. CSS Aspect Ratio Product Image Gallery (opens in a new tab)
07. CSS Aspect Ratio Zoom Thumbnail Carousel (opens in a new tab)
08. CSS Aspect Ratio Prevent Layout Shift Placeholder (opens in a new tab)
09. CSS Aspect Ratio Dynamic Content Fallback (opens in a new tab)
10. CSS Aspect Ratio Ad Banner Container (opens in a new tab)
11. CSS Aspect Ratio Responsive Modal Dialog (opens in a new tab)
<dialog> element, sized by one honest equation: width:min(92vw, 88svh × 16/9, 1080px) plus aspect-ratio:16/9 — so the modal is always the largest 16:9 rectangle that fits the screen, portrait or landscape, phone or ultrawide. ::backdrop gets real blur, @starting-style animates the open, form method='dialog' closes without JavaScript, and the 9 lines of JS do exactly two things: showModal() and light-dismiss. The poster wall behind it runs 2:3 — movie-jacket ratio — for free contrast.12. CSS Aspect Ratio Responsive Map Box (opens in a new tab)
13. CSS Aspect Ratio Media Query Orientation (opens in a new tab)
14. CSS Aspect Ratio Auto Object Fit Contain (opens in a new tab)
15. Convert CSS Padding Top Hack to Aspect Ratio (opens in a new tab)
Frequently asked questions
What is the CSS aspect-ratio property and when should I use it vs the padding-top hack?
aspect-ratio property (Baseline September 2021 — Chrome 88, Safari 15, Firefox 89) declares a box's intrinsic width-to-height ratio so the browser reserves the correct height BEFORE any child content or images load. Syntax: aspect-ratio: 16 / 9 (video), aspect-ratio: 1 (square), aspect-ratio: 4 / 5 (apparel product), aspect-ratio: 9 / 16 (TikTok/Reels story). The padding-top hack is the pre-2021 legacy: wrap the element in a positioned container, then set padding-top: 56.25% (which is 9÷16 = 56.25%) so the padding — computed as a percentage of the CONTAINING BLOCK'S WIDTH — reserves proportional height. Two traps: (1) the math is inverted (HEIGHT ÷ WIDTH, so 4:3 = 75%, 1:1 = 100%, 9:16 = 177.78%), and it's easy to write the wrong number; (2) the child must be absolutely-positioned inside the wrapper because padding on the wrapper reserves space but the wrapper itself has no natural height. In 2026, always use aspect-ratio for new code — it's Baseline-supported for 4+ years, ~99.9% of browser traffic in every tier-1 country (US/UK/CA/AU/NZ), and it works on the ELEMENT ITSELF without wrapper gymnastics. The only reason to still ship the padding-top hack: legacy Corporate IE11 fleet (dying — <1% traffic in the US) or email newsletter clients (Outlook Desktop still uses the Word rendering engine, no CSS Grid, no aspect-ratio). Demo 15 in this collection ships the exact side-by-side comparison with a live ratio picker that updates both patterns simultaneously — copy the modern side. See MDN aspect-ratio for the full spec.How does aspect-ratio prevent Cumulative Layout Shift (CLS) — Google's Core Web Vital since 2020?
<img> or <iframe> without dimensions declared. The browser reserves 0 height until the image byte arrives; when the byte lands, the image expands to its natural height and every element below jumps down. CLS accumulates on every image load, and a photo-heavy page can hit CLS 0.5+ without the fix. The 2026 recipe: <img src='...' width='800' height='600'> — the browser reads the HTML width+height attributes AS AN ASPECT RATIO and reserves proportional height in the layout even before the image byte arrives. This works because browsers now compute aspect-ratio: attr(width) / attr(height) internally when width+height are HTML attributes. For iframes, background-images, and CSS-driven media where HTML attributes don't apply: wrap in a container with explicit aspect-ratio: 16 / 9. Demo 08 in this collection ships a side-by-side lab with a live PerformanceObserver CLS meter — click 'Load' on both panes and watch the reserved-space pane hit CLS 0.00 while the raw pane hits CLS 0.15+. This is the metric Google's own optimize-cls guide singles out as the fastest way to move a page from Poor CWV to Good CWV. On a content-thin page (product listing, hero video), CLS improvement lifts ranking by 15-25% for the same query.How do I make a responsive 16:9 YouTube iframe embed that scales with the container — the canonical pattern?
.embed { aspect-ratio: 16 / 9; width: 100% } plus .embed iframe { width: 100%; height: 100% }. That's it. No padding-top hack, no absolute-positioned wrapper, no width-height JavaScript recalc on resize. The iframe fills its container, the container maintains the 16:9 aspect ratio at any width, and layout is stable before the iframe loads. Trap 1: don't put aspect-ratio on the iframe itself — iframes accept it but a browser's aspect-ratio calc fights the iframe's intrinsic behavior in edge cases (Safari has historically been inconsistent). Put it on the wrapper, stretch the iframe. Trap 2: for embeds behind a click-to-load facade (Demo 01 pattern — YouTube's IntersectionObserver-triggered iframe replaces a poster+play-button placeholder), the facade element MUST also carry the same aspect-ratio: 16 / 9 so the swap is dimensionally identical — otherwise you get a jarring layout shift the moment the iframe replaces the poster. Trap 3: for privacy + performance, use the click-to-load pattern instead of loading the iframe on page-load. Google's Privacy Sandbox docs, GDPR compliance guides, and Core Web Vitals recommendations all endorse this pattern — every YouTube embed loads ~700KB of JavaScript on your page even before the user hits play. Facade + click-to-load defers all of that until user intent is proven. Demo 01 ships the 13-line vanilla JS facade-swap snippet + the aspect-ratio wrapper — copy both. Works identically for Vimeo, Wistia, Loom, Cameo, MasterClass, YouTube Shorts (swap to 9:16), YouTube Music, Spotify embed, Twitter/X embed, Instagram embed.How do modern 2026 aspect-ratio patterns compare with Tailwind's aspect-video / aspect-square / aspect-[16/9] utilities?
aspect-ratio: 16 / 9. aspect-square → aspect-ratio: 1 / 1. aspect-[16/9] → arbitrary-value syntax → aspect-ratio: 16 / 9. All three ship identical CSS to what this collection demos. Tailwind's Aspect Ratio docs even reference the exact same Baseline support cutoff (Sep 2021) that this collection targets. The productivity trade-off: Tailwind gives you class='aspect-video' instead of style='aspect-ratio: 16/9' — 12 chars vs 26. In a JSX/Vue/Svelte template that authors 200+ elements per page, the class syntax reads cleaner AND you get Tailwind's JIT purge so unused utilities never ship. In a plain HTML/CSS project without Tailwind: use the direct aspect-ratio declaration in a scoped stylesheet — you avoid Tailwind's runtime (~15-40KB compressed depending on JIT settings), and the CSS variable pattern in every one of this collection's demos (--ar: 16/9) lets you theme the ratio via CSS custom properties without shipping the Tailwind runtime. For Radix UI users: @radix-ui/react-aspect-ratio is a 1.2KB gzipped React wrapper that renders a <div> with the aspect-ratio property applied. It exists purely for the Radix API consistency — the underlying CSS is identical to shipping the property directly. Drop the library if you're not deep in the Radix ecosystem. Same story for @mui/material Box (Material UI ~85KB total bundle if you tree-shake), Chakra UI AspectRatio (Chakra's Emotion runtime ~50KB), shadcn/ui aspect-ratio (peer-deps on Radix). None of them add functionality — the CSS property does the work; the wrapper adds a naming convention. This collection's approach: ship the CSS property directly in a scoped block, get the same result at 0KB runtime cost.How do I build a responsive product image gallery with aspect-ratio + object-fit — the Shopify, Amazon, Etsy, Farfetch pattern?
aspect-ratio: 4 / 5 (the fashion e-commerce standard — Shopify Dawn, WooCommerce Storefront, BigCommerce Cornerstone, and every luxury retailer uses 4:5 because it maximizes vertical real estate on mobile while staying reasonable on desktop) or aspect-ratio: 1 / 1 (Amazon/Etsy's square standard, works for objects that photograph well from any angle). The image inside uses object-fit: cover; object-position: center so it fills the stage without distortion, cropping edges if the source photo doesn't match the target ratio. (2) The thumbnail strip — a grid of aspect-ratio: 1 / 1 tiles with object-fit: cover. Thumbnails are always 1:1 regardless of the stage ratio because Amazon-style comparison shopping conditioned users to expect uniformly-sized thumbs. (3) The state driver — hidden <input type='radio' name='view'> for each thumb + :checked ~ .stage img.match { opacity: 1 }. Zero JavaScript. Real form-post semantics (if the gallery is inside a <form>, the selected view can post to the server, e.g. for 'add this variant to cart' flows). Keyboard users get free arrow-key navigation between radios. Screen readers announce 'view 3 of 6, radio button' correctly. Accessibility non-negotiables: every <img> has meaningful alt='Product name, view N of M', the thumbnail strip has role='radiogroup' aria-label='Product views', focus rings on every thumbnail at 2px min / 3:1 contrast per WCAG 2.4.13, and hit targets ≥ 44px per WCAG 2.5.5. This is the pattern Shopify Dawn, WooCommerce Storefront, BigCommerce Cornerstone, Farfetch, Ssense, MatchesFashion, Nordstrom, Net-a-Porter, and every tier-1 fashion e-commerce site ships — check DevTools on any product page and you'll see the same 3-layer recipe.Which aspect-ratio patterns fit high-CPM verticals — Shopify/Amazon product pages, video hosting (Vimeo/Wistia/Loom), IAB ad slots, real-estate galleries, streaming media (Netflix/Disney+)?
Do these CSS aspect-ratio demos work in React, Vue, Svelte, Astro, Next.js, Remix, and SvelteKit — and what's the framework portability story vs @radix-ui/react-aspect-ratio, @mui/material AspectRatio, Chakra UI AspectRatio?
class to className, drop the JSX into any server or client component (no 'use client' directive needed for the 11 Pure CSS demos because they have no interactivity that requires hydration; only Demos 01 facade swap, 07 pointer magnifier, 08 CLS meter, and 11 dialog light-dismiss need it, each under 20 lines JS). Vue 3 / Nuxt 3: accepts as-is, class attribute is native. Svelte / SvelteKit: accepts as-is. Astro: drop into any .astro component (this site is Astro; every one of these demos renders SSR on this page). Remix / Solid.js / Qwik: accepts as-is. Compared to framework-specific aspect-ratio libraries: @radix-ui/react-aspect-ratio (~1.2KB gzipped) is a React wrapper around a <div> with aspect-ratio applied — it exists for Radix API consistency, not because the browser needs it. Drop the library if you're not deep in the Radix ecosystem; the CSS is identical either way. @mui/material Box with sx aspect-ratio prop requires the full Material UI runtime (~85KB gzipped total). @chakra-ui/react AspectRatio needs Chakra's Emotion runtime (~50KB). shadcn/ui aspect-ratio peer-deps on Radix. Vuetify VResponsive, Ant Design AspectRatio, Bootstrap ratio — same story, all layer on framework-specific naming conventions around the same underlying CSS property. None add functionality the browser doesn't do natively since Sep 2021 Baseline. The .car-NN numeric-prefix scoping means all 15 aspect-ratio patterns coexist on the gallery page without a single class collision, and the same prefix guarantees you can drop any one demo into a codebase that already uses .aspect-ratio, .ratio, .embed, .hero, or .gallery classes without renaming a single selector. MIT licensed, no attribution required, no signup.Related collections
6 CSS Bento Grid Layouts
6 production CSS bento grid layouts with 12 hand-coded designs — Apple-style product showcase, SaaS feature value-prop matrix, analytics dashboard overview, creative portfolio, e-commerce category hub, and link-in-bio social hub. Each topic ships 2 sub-variants side-by-side so visitors see both a keynote aesthetic and a paper-doc variant at once. Container queries, CSS Grid, zero dependencies, copy-paste ready.
20 CSS Blog Layouts
20 hand-coded CSS blog and editorial layouts for magazine homepages, news sites, personal archives, newsletter back-issues, recipe and podcast blogs, developer tutorials, and long-form journalism. Covers a magazine homepage with hero plus editor-picks rail, a news homepage with breaking-news ticker, blog archives with sticky year separators, Substack-style issue-numbered archives, recipe card grids with prep-time badges, podcast episode lists with waveforms, long-form articles with scroll-driven reading progress, drop caps and floated pull quotes via first-letter, Medium-style 65ch centred reader layouts, dev tutorials with a sticky code panel beside prose, interview transcripts with alternating speakers, case-study pages with stat counters, video blogs with an episode rail, full-bleed photo essays, news articles with sticky related-stories sidebars, documentation pages with prev/next chapter nav, a standalone blog post card, a scroll-snap category filter bar, an inline newsletter callout that breaks out of the prose column, and a horizontal featured-post rail. 12 are pure CSS with zero JavaScript. Every layout is scoped under a .bl-NN prefix for no-collision pasting, guards prefers-reduced-motion, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.
15 CSS Card Grid Layouts
Card grids for blog archives, SaaS dashboards, pricing pages, and product catalogs, plus editorial and bento layouts. Covers auto-fit grids that add and drop columns via repeat(auto-fill), asymmetric Apple-style bento boxes, Pinterest-style fluid masonry, equal-height product cards, KPI dashboard tiles, three-tier pricing comparisons, testimonial walls, team directories, 3D hover flip cards, and glass bento tiles.













