Back to Blog
CSSAspect RatioResponsiveLayout

CSS Aspect Ratio Guide

Master the CSS aspect-ratio property for responsive images, videos, and containers.

B
Bootspring Team
Engineering
February 7, 2020
5 min read

The aspect-ratio property maintains proportions without padding hacks. Here's how to use it.

Basic Syntax#

1/* Width to height ratio */ 2.square { 3 aspect-ratio: 1 / 1; /* or just: 1 */ 4} 5 6.widescreen { 7 aspect-ratio: 16 / 9; 8} 9 10.portrait { 11 aspect-ratio: 3 / 4; 12} 13 14.ultrawide { 15 aspect-ratio: 21 / 9; 16} 17 18/* Common ratios */ 19.ratio-4-3 { 20 aspect-ratio: 4 / 3; /* Classic TV/photo */ 21} 22 23.ratio-3-2 { 24 aspect-ratio: 3 / 2; /* DSLR photo */ 25} 26 27.ratio-1-1 { 28 aspect-ratio: 1; /* Square */ 29}

Responsive Images#

1/* Image container with fixed ratio */ 2.image-container { 3 aspect-ratio: 16 / 9; 4 width: 100%; 5 overflow: hidden; 6} 7 8.image-container img { 9 width: 100%; 10 height: 100%; 11 object-fit: cover; 12} 13 14/* Card image */ 15.card-image { 16 aspect-ratio: 4 / 3; 17 width: 100%; 18} 19 20.card-image img { 21 width: 100%; 22 height: 100%; 23 object-fit: cover; 24 object-position: center; 25} 26 27/* Thumbnail grid */ 28.thumbnail { 29 aspect-ratio: 1; 30 width: 100%; 31 background-size: cover; 32 background-position: center; 33 border-radius: 4px; 34}

Video Embeds#

1/* Responsive video container */ 2.video-wrapper { 3 aspect-ratio: 16 / 9; 4 width: 100%; 5} 6 7.video-wrapper iframe, 8.video-wrapper video { 9 width: 100%; 10 height: 100%; 11 border: none; 12} 13 14/* YouTube embed */ 15.youtube-embed { 16 aspect-ratio: 16 / 9; 17 width: 100%; 18 max-width: 800px; 19} 20 21/* Vertical video (TikTok/Reels) */ 22.vertical-video { 23 aspect-ratio: 9 / 16; 24 max-height: 80vh; 25 width: auto; 26}

Card Layouts#

1/* Product card with image */ 2.product-card { 3 display: flex; 4 flex-direction: column; 5} 6 7.product-image { 8 aspect-ratio: 1; 9 background: #f5f5f5; 10 overflow: hidden; 11} 12 13.product-image img { 14 width: 100%; 15 height: 100%; 16 object-fit: contain; 17 transition: transform 0.3s; 18} 19 20.product-card:hover .product-image img { 21 transform: scale(1.05); 22} 23 24/* Blog post card */ 25.blog-card { 26 display: grid; 27 gap: 1rem; 28} 29 30.blog-card-image { 31 aspect-ratio: 2 / 1; 32 border-radius: 8px; 33 overflow: hidden; 34} 35 36/* Profile avatar */ 37.avatar { 38 aspect-ratio: 1; 39 width: 48px; 40 border-radius: 50%; 41 overflow: hidden; 42} 43 44.avatar img { 45 width: 100%; 46 height: 100%; 47 object-fit: cover; 48}

Skeleton Loading#

1/* Loading skeleton with aspect ratio */ 2.skeleton { 3 aspect-ratio: 16 / 9; 4 background: linear-gradient( 5 90deg, 6 #f0f0f0 25%, 7 #e0e0e0 50%, 8 #f0f0f0 75% 9 ); 10 background-size: 200% 100%; 11 animation: shimmer 1.5s infinite; 12 border-radius: 8px; 13} 14 15@keyframes shimmer { 16 0% { background-position: 200% 0; } 17 100% { background-position: -200% 0; } 18} 19 20/* Different skeleton shapes */ 21.skeleton-square { 22 aspect-ratio: 1; 23} 24 25.skeleton-banner { 26 aspect-ratio: 4 / 1; 27} 28 29.skeleton-card { 30 aspect-ratio: 3 / 4; 31}

Grid with Aspect Ratio#

1/* Image gallery grid */ 2.gallery { 3 display: grid; 4 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 5 gap: 1rem; 6} 7 8.gallery-item { 9 aspect-ratio: 1; 10 overflow: hidden; 11 border-radius: 8px; 12} 13 14.gallery-item img { 15 width: 100%; 16 height: 100%; 17 object-fit: cover; 18 transition: transform 0.3s; 19} 20 21.gallery-item:hover img { 22 transform: scale(1.1); 23} 24 25/* Featured layout */ 26.featured-grid { 27 display: grid; 28 grid-template-columns: 2fr 1fr; 29 grid-template-rows: 1fr 1fr; 30 gap: 1rem; 31} 32 33.featured-grid .main { 34 grid-row: span 2; 35 aspect-ratio: 4 / 5; 36} 37 38.featured-grid .secondary { 39 aspect-ratio: 16 / 9; 40}

Hero Sections#

1/* Full-width hero */ 2.hero { 3 aspect-ratio: 21 / 9; 4 min-height: 400px; 5 max-height: 600px; 6 background-size: cover; 7 background-position: center; 8 display: flex; 9 align-items: center; 10 justify-content: center; 11} 12 13/* Mobile-friendly hero */ 14.hero-responsive { 15 aspect-ratio: 16 / 9; 16} 17 18@media (max-width: 768px) { 19 .hero-responsive { 20 aspect-ratio: 4 / 3; 21 } 22} 23 24@media (max-width: 480px) { 25 .hero-responsive { 26 aspect-ratio: 1; 27 } 28}

Intrinsic Sizing#

1/* With min/max constraints */ 2.constrained { 3 aspect-ratio: 16 / 9; 4 width: 100%; 5 max-width: 800px; 6 max-height: 450px; 7} 8 9/* Minimum size */ 10.min-size { 11 aspect-ratio: 1; 12 width: 100%; 13 min-width: 200px; 14 min-height: 200px; 15} 16 17/* Combined with object-fit */ 18.fit-contain { 19 aspect-ratio: 16 / 9; 20 width: 100%; 21} 22 23.fit-contain img { 24 width: 100%; 25 height: 100%; 26 object-fit: contain; 27 background: #f5f5f5; 28}

Override with Content#

1/* Aspect ratio as preferred, content can override */ 2.flexible { 3 aspect-ratio: 16 / 9; 4 min-height: min-content; /* Allow content to expand */ 5} 6 7/* Force aspect ratio regardless of content */ 8.strict { 9 aspect-ratio: 16 / 9; 10 overflow: hidden; 11} 12 13/* Auto height when content is larger */ 14.auto-expand { 15 aspect-ratio: auto 16 / 9; 16 /* Uses natural ratio if available, falls back to 16/9 */ 17}

Replaced Elements#

1/* Images with natural aspect ratio */ 2img { 3 max-width: 100%; 4 height: auto; 5 /* Browser uses natural aspect-ratio */ 6} 7 8/* Override natural ratio */ 9img.square { 10 aspect-ratio: 1; 11 object-fit: cover; 12} 13 14/* Video with aspect ratio */ 15video { 16 aspect-ratio: 16 / 9; 17 width: 100%; 18 object-fit: cover; 19} 20 21/* Canvas */ 22canvas { 23 aspect-ratio: 16 / 9; 24 width: 100%; 25 background: #000; 26}

Fallback for Older Browsers#

1/* Padding-bottom fallback */ 2.video-container { 3 position: relative; 4 padding-bottom: 56.25%; /* 16:9 fallback */ 5 height: 0; 6} 7 8/* Modern browsers */ 9@supports (aspect-ratio: 16 / 9) { 10 .video-container { 11 aspect-ratio: 16 / 9; 12 padding-bottom: 0; 13 height: auto; 14 } 15} 16 17.video-container iframe { 18 position: absolute; 19 top: 0; 20 left: 0; 21 width: 100%; 22 height: 100%; 23} 24 25@supports (aspect-ratio: 16 / 9) { 26 .video-container iframe { 27 position: static; 28 } 29}

Best Practices#

Usage: ✓ Use for responsive media ✓ Combine with object-fit ✓ Set on container, not content ✓ Use meaningful ratios Responsive: ✓ Adjust ratio at breakpoints ✓ Set min/max constraints ✓ Test at various sizes ✓ Consider content overflow Performance: ✓ Prevents layout shift ✓ Improves CLS score ✓ Set explicit dimensions ✓ Use with loading="lazy" Avoid: ✗ Forcing ratio on text content ✗ Forgetting object-fit ✗ Ignoring browser support ✗ Breaking content accessibility

Conclusion#

The aspect-ratio property simplifies responsive media handling without padding hacks. Use it for images, videos, cards, and any element needing consistent proportions. Combine with object-fit and constraints for flexible, responsive layouts that prevent layout shift.

Share this article

Help spread the word about Bootspring