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.