AZ.dev

CSS & Layout Essentials Cheat Sheet

CSS & Layout

The layout moves you make every week, from centering and responsive columns to sticky headers, clamped text, and container queries.

13 cards | css: Baseline 2024

Centering and columns

Center anything, both axes

.hero {
  display: grid;
  place-items: center;
}

A row that wraps when it runs out of room

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

Push one item to the far end

.toolbar > .logout {
  margin-left: auto;
}

An auto margin takes all the free space in a flex or grid container. It works on the cross axis too.

Center a column of content

.page {
  max-width: 65ch;
  margin-inline: auto;
}

Logical properties follow the writing direction, so this also works for right-to-left pages.

Sizing

Keep a box at a fixed ratio

.thumb {
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

Fluid type between two sizes

h1 {
  font-size: clamp(1.5rem, 1rem + 2vw, 3rem);
}

Minimum, preferred, maximum. The middle value scales with the viewport.

Text

Truncate a single line with an ellipsis

.title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

All three are needed. The element also needs a width to run out of.

Clamp text to three lines

.excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

The -webkit- prefix is the standard spelling every browser ships.

Positioning and queries

A header that stays put while the page scrolls

header {
  position: sticky;
  top: 0;
}

Sticks within its parent. An overflow: hidden on any ancestor between here and the scroller breaks it.

Full entry: Why position sticky isn't sticking

Style a component by its own width, not the viewport

.card-slot {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card {
    grid-template-columns: 1fr 2fr;
  }
}

The query reads the nearest ancestor with a container-type.

Style a parent from what it contains

.field:has(input:invalid) {
  border-color: var(--color-destructive);
}

Works for any selector inside. .card:has(> img) matches cards with a direct image child.