
CSS Aspect Ratio 16 9 Iframe YouTube
Published
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.
Related22 CSS Image Galleries15 CSS Card Grid Layouts31 CSS Hero Sections

Published

Published

Published

<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.Published

Published

Published
Published

Published

Published

Published

<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.Published

Published

Published

Published

Published
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.<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..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.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.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.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.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 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 production CSS card grid layouts covering the most-searched grid patterns plus originals built for real use cases — auto-fit responsive blog archive grid, asymmetric bento-box feature grid, equal-height product grid, fluid Pinterest-style masonry, team directory face grid, 3D hover-flip card grid, stratified duotone bento, editorial tabloid bento with masthead and TOC, use-case showcase grid, SaaS pricing comparison with featured tier, Vercel-style testimonial wall with featured 2x2, Airbnb-style hero photo collage with location pills, SaaS stats dashboard with CSS-bar sparklines, editorial featured-article magazine grid with category-coded pills, and a Liquid Glass bento grid with per-tile refraction rims (Apple iOS 26 / macOS Tahoe aesthetic). Every layout scoped under .cg-NN, zero dependencies, copy-paste ready.