Complete CSS Course Module 15: Advanced: Modern CSS Features

Modern Layout Tricks: aspect-ratio, object-fit, subgrid and logical properties

  • Beginner
  • Lesson 15.4
  • 5 min read
  • 66 of 77 in the course

In short

Modern CSS layout tricks like aspect-ratio, object-fit, subgrid, logical properties and scroll-snap solve everyday layout problems with just a few lines. How to use aspect-ratio in CSS The aspect-ratio property keeps an element's width and height in a fixed proportion.

Modern CSS layout tricks like aspect-ratio, object-fit, subgrid, logical properties and scroll-snap solve everyday layout problems with just a few lines.

How to use aspect-ratio in CSS

The aspect-ratio property keeps an element's width and height in a fixed proportion. You set the width, and the browser works out the height.

.video-frame {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #111827;
}

.avatar {
  width: 80px;
  aspect-ratio: 1;
  border-radius: 50%;
}

The video frame is always 16:9, like a TV screen, at any width. The avatar is a perfect square (and so a perfect circle). Before aspect-ratio, developers needed a confusing "padding-top hack" to do this.

object-fit and object-position for images

When you force an image into a box with a different shape, it gets stretched and looks squashed. object-fit tells the image how to fill its box, like choosing how a photo fits into a frame.

  • fill (default): stretches the image to fill the box. Often looks wrong.
  • cover: fills the whole box and crops the extra parts. Best for thumbnails.
  • contain: shows the whole image and leaves empty space if needed. Good for logos.

object-position chooses which part stays visible when the image is cropped.

<div class="gallery">
  <img src="https://picsum.photos/800/500" alt="City at night">
  <img src="https://picsum.photos/400/700" alt="Tall tree in a forest">
  <img src="https://picsum.photos/600/600" alt="Cup of coffee">
</div>
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
}

.gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center top;
  border-radius: 8px;
}

All three images have different original shapes, but in the gallery they look like a neat, even row of 4:3 thumbnails. Nothing is stretched. The crop keeps the top of each picture.

How subgrid aligns cards in a grid

A common problem: a row of cards where the titles have different lengths. The buttons at the bottom end up at different heights, and it looks messy. Subgrid lets each card use the rows of its parent grid, so matching parts line up across all cards.

<section class="plans">
  <article class="plan">
    <h3>Starter</h3>
    <p>Everything you need to begin.</p>
    <a href="#">Choose</a>
  </article>
  <article class="plan">
    <h3>Professional plan for growing teams</h3>
    <p>More tools, more space and priority help for your whole team.</p>
    <a href="#">Choose</a>
  </article>
  <article class="plan">
    <h3>Team</h3>
    <p>Share with everyone.</p>
    <a href="#">Choose</a>
  </article>
</section>
.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.5rem;
}

.plan {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  gap: 0.75rem;
  padding: 1.5rem;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.plan h3,
.plan p {
  margin: 0;
}

.plan a {
  align-self: end;
  justify-self: start;
  padding: 0.5rem 1rem;
  background: #4f46e5;
  color: white;
  border-radius: 6px;
  text-decoration: none;
}

Each card takes up three rows of the parent grid (span 3) and uses those rows as its own (subgrid). Now all titles share one row, all descriptions share the next, and all buttons sit on the same line, even though the text lengths are different.

Note: Subgrid is supported in all modern browsers. You can also use grid-template-columns: subgrid to share columns.

What are CSS logical properties?

margin-left always means the left side. But some languages, like Arabic and Hebrew, read from right to left. Logical properties describe sides by the direction of the text instead:

  • Inline is the direction text flows (left to right in English).
  • Block is the direction paragraphs stack (top to bottom).
Physical propertyLogical property
margin-left and margin-rightmargin-inline
padding-top and padding-bottompadding-block
margin-leftmargin-inline-start
widthinline-size
top, right, bottom, leftinset
.content {
  max-inline-size: 70ch;
  margin-inline: auto;
  padding-block: 2rem;
  padding-inline: 1rem;
}

.quote {
  border-inline-start: 4px solid #4f46e5;
  padding-inline-start: 1rem;
}

The content is centered with comfortable spacing. The quote has a border on the side where text starts. In English that is the left. On an Arabic page with dir="rtl", it moves to the right automatically.

Tip: Even for English-only sites, margin-inline: auto and padding-block: 2rem are shorter than writing two separate properties.

Smooth scrolling with scroll-behavior and scroll-snap

scroll-behavior: smooth makes jump links (like href="#pricing") glide down the page instead of jumping.

Scroll snap makes a scrolling area stop neatly on each item, like a photo carousel on a phone.

html {
  scroll-behavior: smooth;
}

.carousel {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-block-end: 1rem;
}

.carousel img {
  flex: 0 0 80%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  scroll-snap-align: center;
  border-radius: 12px;
}

When you swipe or scroll the carousel sideways, it always stops with one image in the center. x mandatory means "snap on the horizontal axis, every time". Each image says where it wants to snap with scroll-snap-align.

Common mistake: Forgetting reduced motion. Wrap scroll-behavior: smooth in @media (prefers-reduced-motion: no-preference) so people who turned off motion get instant jumps.

Practice exercise

Build a "team members" section with four cards. Each card has a photo, a name and a short bio of different lengths. Make every photo a square with aspect-ratio and object-fit: cover, align the names and bios across cards with subgrid, and use only logical properties for spacing.

Hint: Each card needs grid-row: span 3 and grid-template-rows: subgrid, because it has three parts.

Key takeaways

  • aspect-ratio keeps a fixed width-to-height shape, like 16 / 9 or 1.
  • object-fit: cover crops images to fill a box without stretching.
  • Subgrid lets cards share the parent grid's rows, so their parts line up.
  • Logical properties like margin-inline follow the text direction.
  • scroll-snap-type and scroll-snap-align create neat carousels; scroll-behavior: smooth softens jump links.