Code

CSS

CSS Responsive Design

Media queries, mobile-first approach, container queries, and fluid techniques. MDN Reference

1. Viewport meta tag — always required

<!-- In <head> — tells mobile browsers not to zoom out -->
<meta name="viewport" content="width=device-width, initial-scale=1">

2. @media queries

Apply styles conditionally based on viewport width, height, orientation, or media type.

xs < 576px
sm ≥ 576px
md ≥ 768px
lg ≥ 992px
xl ≥ 1200px
xxl ≥ 1400px
/* Mobile-first: apply from breakpoint UP */
@media (min-width: 576px)  { /* sm+ */ }
@media (min-width: 768px)  { /* md+ */ }
@media (min-width: 992px)  { /* lg+ */ }
@media (min-width: 1200px) { /* xl+ */ }
@media (min-width: 1400px) { /* xxl+ */ }

/* Desktop-first: apply UP TO breakpoint */
@media (max-width: 767.98px) { /* below md */ }

/* Range (modern syntax) */
@media (768px <= width < 992px) { /* md only */ }

/* Orientation */
@media (orientation: landscape) { }
@media (orientation: portrait)  { }

3. Mobile-first pattern

Start with styles for the smallest screens, then layer on larger-screen overrides.

/* ─── Mobile first ─── */
.nav {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

/* ─── Tablet and up ─── */
@media (min-width: 768px) {
  .nav {
    flex-direction: row;
  }

  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ─── Desktop and up ─── */
@media (min-width: 992px) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

4. Responsive typography

Fluid heading — resize the window

Body text that scales smoothly between 1rem and 1.25rem.

/* Media query approach */
h1 { font-size: 1.75rem; }
@media (min-width: 768px) {
  h1 { font-size: 2.5rem; }
}

/* Fluid approach — no breakpoints */
h1 {
  font-size: clamp(1.75rem, 4vw, 3.5rem);
}

p {
  font-size: clamp(1rem, 1.5vw, 1.25rem);
}

/* CSS custom property fluid scale */
:root {
  --step-0: clamp(1rem,  1.2vw, 1.125rem);
  --step-1: clamp(1.25rem, 2vw, 1.5rem);
  --step-2: clamp(1.5rem,  3vw, 2rem);
}

5. Responsive images

/* Never overflow their container */
img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Intrinsic ratio placeholder */
.img-wrap {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* srcset — browser picks best resolution */
<img
  src="image-800.webp"
  srcset="image-400.webp 400w, image-800.webp 800w, image-1200.webp 1200w"
  sizes="(max-width: 768px) 100vw, 50vw"
  alt="..."
>

6. Container queries

Style a component based on its container's width rather than the viewport — perfect for reusable components.

Wide container card

Layout switches to row above 400px container width.

Narrow container card

Stacked layout below 400px.

/* Mark a containment context */
.wrapper {
  container-type: inline-size;
  container-name: card;
}

/* Query the container */
@container card (min-width: 400px) {
  .card {
    display: flex;
    flex-direction: row;
    gap: 1rem;
  }
}

/* cqw unit */
.title {
  font-size: clamp(1rem, 5cqw, 1.5rem);
}

7. Logical properties — RTL-aware layouts

/* Physical → Logical equivalents */
margin-left:   → margin-inline-start
margin-right:  → margin-inline-end
margin-top:    → margin-block-start
margin-bottom: → margin-block-end

padding-left:  → padding-inline-start
width:         → inline-size
height:        → block-size

/* Centering with logical properties */
.container {
  max-inline-size: 1280px;
  margin-inline: auto;
  padding-inline: 1rem;
}