Responsive Design and Media Queries

1. Media Query Syntax and Features

Component Syntax Description Example
@media @media type and (feature) Apply styles conditionally based on device characteristics @media screen and (min-width: 768px)
Media Types all | screen | print | speech Target specific device types @media print { ... }
Logical Operators and | or | not | only Combine multiple media features (min-width: 768px) and (max-width: 1024px)
Width Queries min-width | max-width | width Query viewport or container width (min-width: 768px)
Height Queries min-height | max-height | height Query viewport or container height (min-height: 600px)
Orientation portrait | landscape Detect device orientation (orientation: landscape)
Aspect Ratio aspect-ratio: width/height Query viewport aspect ratio (aspect-ratio: 16/9)
Resolution resolution: value Query pixel density (dpi, dpcm, dppx) (resolution: 2dppx) for Retina
Display Mode display-mode: value Detect PWA display mode (display-mode: standalone)
Pointer pointer: none | coarse | fine Primary input mechanism precision (pointer: coarse) for touch
Hover hover: none | hover Can primary input hover over elements (hover: hover) for mouse
Any-pointer any-pointer: none | coarse | fine Any available input mechanism (any-pointer: fine)
Any-hover any-hover: none | hover Any available input can hover (any-hover: hover)

Example: Basic media query patterns

/* Mobile-first approach (min-width) */
.container {
    width: 100%;
}

@media (min-width: 768px) {
    .container {
        width: 750px;
    }
}

@media (min-width: 1024px) {
    .container {
        width: 980px;
    }
}

@media (min-width: 1280px) {
    .container {
        width: 1200px;
    }
}

/* Desktop-first approach (max-width) */
.nav {
    display: flex;
}

@media (max-width: 1023px) {
    .nav {
        display: none;
    }
}

/* Range queries (Level 4 syntax) */
@media (768px <= width <= 1024px) {
    .tablet-only {
        display: block;
    }
}

/* Multiple conditions */
@media screen and (min-width: 768px) and (orientation: landscape) {
    .landscape-tablet {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* Print styles */
@media print {
    .no-print {
        display: none;
    }
    
    body {
        font-size: 12pt;
        color: black;
        background: white;
    }
}

Example: User interaction and device queries

/* Touch device detection */
@media (hover: none) and (pointer: coarse) {
    /* Touch-only device */
    button {
        min-height: 44px;  /* Larger touch targets */
        min-width: 44px;
    }
}

/* Mouse/trackpad device */
@media (hover: hover) and (pointer: fine) {
    .interactive:hover {
        background: #f0f0f0;
    }
}

/* Hybrid device (touch + mouse) */
@media (any-hover: hover) {
    .tooltip {
        display: none;
    }
    
    .element:hover .tooltip {
        display: block;
    }
}

/* High-resolution displays (Retina) */
@media (resolution: 2dppx), (resolution: 192dpi) {
    .logo {
        background-image: url('logo@2x.png');
        background-size: 100px 50px;
    }
}

/* PWA standalone mode */
@media (display-mode: standalone) {
    .install-prompt {
        display: none;
    }
    
    .app-header {
        padding-top: env(safe-area-inset-top);
    }
}

/* Landscape orientation */
@media (orientation: landscape) {
    .video-player {
        height: 100vh;
    }
}

/* Specific aspect ratios */
@media (aspect-ratio: 16/9) {
    .widescreen-layout {
        display: grid;
        grid-template-columns: 2fr 1fr;
    }
}
Note: Use (hover: hover) to distinguish devices with mouse from touch devices. Use any-hover for hybrid devices. Modern Level 4 range syntax: (width >= 768px) is cleaner than (min-width: 768px).

2. Responsive Length Units and Viewport

Unit Full Name Description Use Case
vw Viewport Width 1% of viewport width Full-width elements, responsive font sizes
vh Viewport Height 1% of viewport height Full-height sections, hero images
vmin Viewport Minimum 1% of smaller viewport dimension Square elements that fit any orientation
vmax Viewport Maximum 1% of larger viewport dimension Background images, diagonal layouts
svh NEW Small Viewport Height Height when UI is expanded (mobile) Fixed mobile headers, reliable 100% height
lvh NEW Large Viewport Height Height when UI is retracted Full-screen experiences
dvh NEW Dynamic Viewport Height Adjusts as browser UI shows/hides Smooth mobile experiences
vi, vb Viewport Inline/Block Writing mode aware viewport units Internationalized layouts
% Percentage Relative to parent element Fluid layouts, responsive sizing
rem Root Em Relative to root font-size (html) Consistent spacing, scalable layouts
em Em Relative to parent font-size Component-scoped scaling
ch Character Width of "0" character Optimal reading line length (45-75ch)
ex X-height Height of lowercase "x" Vertical rhythm, icon sizing

Example: Viewport units for responsive layouts

/* Full-viewport hero section */
.hero {
    height: 100vh;  /* May have issues on mobile */
    height: 100dvh; /* Better: adjusts with mobile browser UI */
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Mobile-safe full height */
.mobile-full-height {
    min-height: 100svh;  /* Smallest viewport (UI visible) */
    min-height: 100dvh;  /* Fallback for dynamic */
}

/* Fluid typography with viewport units */
.responsive-text {
    font-size: calc(16px + 1vw);  /* Grows with viewport */
    /* Better: use clamp() for min/max bounds */
}

/* Square element regardless of orientation */
.square {
    width: 50vmin;
    height: 50vmin;
}

/* Responsive spacing with rem */
:root {
    font-size: 16px;
}

@media (min-width: 768px) {
    :root {
        font-size: 18px;  /* All rem values scale up */
    }
}

.section {
    padding: 2rem;  /* 32px mobile, 36px tablet+ */
    margin-bottom: 3rem;
}

/* Optimal reading width */
.article {
    max-width: 65ch;  /* ~65 characters per line */
    margin: 0 auto;
}

/* Percentage-based fluid grid */
.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 2%;  /* Scales with container */
}

Example: Small/Large/Dynamic viewport units (mobile)

/* Problem: 100vh on mobile includes browser UI space */
.old-full-height {
    height: 100vh;  /* May extend below visible area */
}

/* Solution 1: Small viewport (UI always visible) */
.safe-full-height {
    height: 100svh;  /* Accounts for mobile browser chrome */
}

/* Solution 2: Large viewport (UI hidden) */
.expanded-full-height {
    height: 100lvh;  /* Maximum available space */
}

/* Solution 3: Dynamic (recommended) */
.adaptive-full-height {
    height: 100vh;   /* Fallback */
    height: 100dvh;  /* Smoothly adjusts as UI shows/hides */
}

/* Width equivalents */
.full-width {
    width: 100vw;   /* Standard */
    width: 100dvw;  /* Dynamic (for horizontal scrolling scenarios) */
}

/* Practical example: Mobile modal */
.modal-overlay {
    position: fixed;
    inset: 0;
    height: 100dvh;  /* Covers visible viewport */
    width: 100dvw;
    background: rgba(0, 0, 0, 0.5);
}

.modal-content {
    max-height: 90dvh;  /* Leave space for gestures */
    overflow-y: auto;
}
Warning: 100vh on mobile includes browser UI, causing overflow. Use 100dvh for dynamic adjustment or 100svh for consistently safe height. Browser support: Chrome 108+, Safari 15.4+.

3. Container Queries Implementation NEW

Property Syntax Description Example
container-type size | inline-size | normal Define element as query container container-type: inline-size;
container-name name Name container for targeted queries container-name: sidebar;
container name / type Shorthand for name and type container: card / inline-size;
@container @container (condition) { } Query container dimensions @container (min-width: 400px)
cqw Container Query Width 1% of container's width font-size: 5cqw;
cqh Container Query Height 1% of container's height padding: 2cqh;
cqi Container Query Inline 1% of inline axis (width in LTR) margin: 3cqi;
cqb Container Query Block 1% of block axis (height in LTR) gap: 2cqb;
cqmin, cqmax Container Query Min/Max 1% of smaller/larger dimension width: 50cqmin;

Example: Container queries for component-based responsive design

/* Define container */
.card-grid {
    container-type: inline-size;
    container-name: card-container;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 1rem;
}

/* Query container, not viewport */
.card {
    padding: 1rem;
}

@container (min-width: 400px) {
    .card {
        display: grid;
        grid-template-columns: 150px 1fr;
        gap: 1rem;
    }
    
    .card-image {
        height: 150px;
    }
}

@container (min-width: 600px) {
    .card {
        grid-template-columns: 200px 1fr;
    }
    
    .card-title {
        font-size: 1.5rem;
    }
}

/* Named container queries */
.sidebar {
    container: sidebar / inline-size;
}

@container sidebar (min-width: 300px) {
    .sidebar-widget {
        display: block;
    }
}

@container sidebar (min-width: 500px) {
    .sidebar-widget {
        display: grid;
        grid-template-columns: 1fr 1fr;
    }
}

Example: Container query units for intrinsic responsive design

/* Responsive typography with container units */
.container {
    container-type: inline-size;
}

.headline {
    font-size: clamp(1rem, 5cqi, 3rem);
    /* Scales with container, not viewport */
}

/* Container-relative spacing */
.card {
    padding: 3cqi 4cqi;
    gap: 2cqi;
}

/* Grid with container units */
@container (min-width: 500px) {
    .grid {
        display: grid;
        grid-template-columns: 30cqi 1fr;
        gap: 3cqi;
    }
}

/* Aspect ratio with container units */
.media {
    width: 100cqi;
    height: 56cqi;  /* 16:9 aspect ratio based on container */
}

/* Fluid icon sizing */
.icon {
    width: 8cqi;
    height: 8cqi;
    max-width: 48px;  /* Cap size */
}

/* Container-relative transforms */
.floating-element {
    transform: translateX(10cqi);
}

/* Responsive grid tracks */
.responsive-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(25cqi, 1fr));
    gap: 2cqi;
}
Note: Container queries enable true component-based responsive design. Components adapt to their container size, not viewport. Use inline-size for width-only queries (most common). Browser support: Chrome 105+, Safari 16+, Firefox 110+.

4. Responsive Typography with clamp()

Function Syntax Description Use Case
clamp() clamp(min, preferred, max) Value between min and max bounds Fluid typography that scales with viewport
min() min(value1, value2, ...) Smallest of provided values Ensure element doesn't exceed size
max() max(value1, value2, ...) Largest of provided values Ensure minimum size is maintained
calc() calc(expression) Mathematical calculations Combine units, create fluid scales

Example: Fluid typography with clamp()

/* Fluid font-size that scales between bounds */
h1 {
    font-size: clamp(2rem, 5vw, 4rem);
    /* Min: 2rem (32px)
       Preferred: 5vw (grows with viewport)
       Max: 4rem (64px) */
}

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

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

/* Fluid spacing */
.section {
    padding: clamp(1rem, 5vw, 4rem) clamp(1rem, 5vw, 2rem);
    margin-bottom: clamp(2rem, 8vh, 6rem);
}

/* Fluid line-height */
.article {
    line-height: clamp(1.4, 1.2 + 0.5vw, 1.8);
}

/* Type scale with clamp() */
:root {
    --fs-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
    --fs-sm: clamp(0.875rem, 0.8rem + 0.4vw, 1rem);
    --fs-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
    --fs-lg: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);
    --fs-xl: clamp(1.5rem, 1.2rem + 1.5vw, 2.5rem);
    --fs-2xl: clamp(2rem, 1.5rem + 2.5vw, 4rem);
}

.text-xs { font-size: var(--fs-xs); }
.text-sm { font-size: var(--fs-sm); }
.text-base { font-size: var(--fs-base); }
.text-lg { font-size: var(--fs-lg); }
.text-xl { font-size: var(--fs-xl); }
.text-2xl { font-size: var(--fs-2xl); }

Example: Responsive layout with min/max/clamp

/* Fluid container width */
.container {
    width: min(100% - 2rem, 1200px);
    /* Never exceeds 1200px, has 1rem padding on mobile */
    margin: 0 auto;
}

/* Responsive grid columns */
.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
    /* Columns min 250px but won't break on narrow screens */
    gap: clamp(1rem, 3vw, 2rem);
}

/* Fluid gap sizing */
.flex-container {
    display: flex;
    gap: clamp(0.5rem, 2vw, 2rem);
}

/* Responsive padding without media queries */
.card {
    padding: clamp(1rem, 4vw, 3rem);
}

/* Optimal reading width */
.article {
    max-width: min(65ch, 100% - 4rem);
    /* Max 65 characters but leaves margin on narrow screens */
}

/* Fluid border-radius */
.button {
    border-radius: clamp(4px, 0.5vw, 8px);
}

/* Height constraints */
.hero {
    min-height: max(400px, 50vh);
    /* At least 400px, but grows on tall screens */
}

/* Aspect ratio with bounds */
.video-container {
    height: clamp(300px, 56.25vw, 720px);
    /* Maintains ~16:9 ratio with min/max */
}

Example: Advanced fluid typography calculation

/* Calculate fluid typography slope */
/*
Formula: clamp(minSize, minSize + (maxSize - minSize) * ((100vw - minVw) / (maxVw - minVw)), maxSize)

Example calculation for h1:
- Viewport range: 320px to 1200px
- Font size range: 24px to 64px
*/

h1 {
    /* Simple version */
    font-size: clamp(1.5rem, 2vw + 1rem, 4rem);
    
    /* Precise calculation */
    font-size: clamp(
        1.5rem,
        1.5rem + (4 - 1.5) * ((100vw - 20rem) / (75 - 20)),
        4rem
    );
}

/* Fluid type scale generator */
:root {
    /* Base settings */
    --fluid-min-width: 320;
    --fluid-max-width: 1200;
    --fluid-min-size: 16;
    --fluid-max-size: 20;
    
    /* Calculate slope */
    --fluid-min-ratio: 1.2;
    --fluid-max-ratio: 1.333;
    
    /* Apply to scale */
    --step-0: clamp(
        calc(var(--fluid-min-size) * 1px),
        calc((var(--fluid-min-size) * 1px) + (var(--fluid-max-size) - var(--fluid-min-size)) * ((100vw - (var(--fluid-min-width) * 1px)) / (var(--fluid-max-width) - var(--fluid-min-width)))),
        calc(var(--fluid-max-size) * 1px)
    );
}

/* Container query-based fluid typography */
.card-container {
    container-type: inline-size;
}

.card-title {
    font-size: clamp(1rem, 5cqi, 2.5rem);
    /* Scales with container, not viewport */
}
Note: clamp() eliminates most responsive typography media queries. Formula: clamp(min, base + scaleFactor, max). Use viewport units (vw, vh) or container units (cqi, cqb) for fluid scaling. Tools: utopia.fyi for fluid type scale generation.

5. Responsive Images and Picture Element

Feature Syntax Description Use Case
srcset srcset="url 1x, url 2x" Multiple resolution image sources Serve higher resolution for Retina displays
sizes sizes="(query) width" Define image display width at breakpoints Let browser choose optimal image size
picture <picture><source><img> Art direction for different layouts Different crops/images per breakpoint
source type <source type="image/webp"> Serve modern image formats WebP, AVIF with fallback to JPEG
loading loading="lazy" Native lazy loading Defer offscreen images, improve performance
decoding decoding="async" Asynchronous image decoding Non-blocking image loading
fetchpriority fetchpriority="high" Hint browser about image priority Prioritize hero images, defer others
aspect-ratio aspect-ratio: 16/9 Reserve space before image loads Prevent layout shift (CLS)
object-fit cover | contain | fill Control image sizing in container Maintain aspect ratio while fitting
object-position top | center | 20% 40% Position image within container Focus on specific area when cropped

Example: Responsive images with srcset and sizes

<!-- Resolution switching (1x, 2x, 3x) -->
<img
    src="image-1x.jpg"
    srcset="image-1x.jpg 1x,
            image-2x.jpg 2x,
            image-3x.jpg 3x"
    alt="Description"
/>

<!-- Width-based selection -->
<img
    src="image-800w.jpg"
    srcset="image-400w.jpg 400w,
            image-800w.jpg 800w,
            image-1200w.jpg 1200w,
            image-1600w.jpg 1600w"
    sizes="(max-width: 600px) 100vw,
           (max-width: 1200px) 50vw,
           800px"
    alt="Description"
/>
<!-- Browser selects best image based on:
     - Screen width and DPR
     - sizes attribute hints -->

<!-- Complex sizes attribute -->
<img
    src="fallback.jpg"
    srcset="small.jpg 400w,
            medium.jpg 800w,
            large.jpg 1200w"
    sizes="(max-width: 400px) 100vw,
           (max-width: 800px) 80vw,
           (max-width: 1200px) 60vw,
           800px"
    alt="Responsive image"
    loading="lazy"
    decoding="async"
/>

Example: Picture element for art direction

<!-- Different images for different layouts -->
<picture>
    <!-- Mobile: portrait crop -->
    <source
        media="(max-width: 600px)"
        srcset="portrait-400w.jpg 400w,
                portrait-800w.jpg 800w"
        sizes="100vw"
    />
    
    <!-- Tablet: square crop -->
    <source
        media="(max-width: 1200px)"
        srcset="square-600w.jpg 600w,
                square-1200w.jpg 1200w"
        sizes="50vw"
    />
    
    <!-- Desktop: landscape crop -->
    <source
        media="(min-width: 1201px)"
        srcset="landscape-800w.jpg 800w,
                landscape-1600w.jpg 1600w"
        sizes="800px"
    />
    
    <!-- Fallback -->
    <img src="landscape-800w.jpg" alt="Hero image" />
</picture>

<!-- Modern format with fallback -->
<picture>
    <!-- AVIF (best compression) -->
    <source
        type="image/avif"
        srcset="image.avif"
    />
    
    <!-- WebP (good compression) -->
    <source
        type="image/webp"
        srcset="image.webp"
    />
    
    <!-- JPEG fallback -->
    <img src="image.jpg" alt="Description" />
</picture>

<!-- Combine format and responsive sizing -->
<picture>
    <source
        type="image/avif"
        srcset="image-400w.avif 400w,
                image-800w.avif 800w"
        sizes="(max-width: 600px) 100vw, 50vw"
    />
    <source
        type="image/webp"
        srcset="image-400w.webp 400w,
                image-800w.webp 800w"
        sizes="(max-width: 600px) 100vw, 50vw"
    />
    <img
        src="image-800w.jpg"
        srcset="image-400w.jpg 400w,
                image-800w.jpg 800w"
        sizes="(max-width: 600px) 100vw, 50vw"
        alt="Description"
        loading="lazy"
    />
</picture>

Example: CSS for responsive images

/* Responsive image container */
.image-container {
    width: 100%;
    aspect-ratio: 16 / 9;  /* Prevent layout shift */
    overflow: hidden;
    background: #f0f0f0;  /* Placeholder */
}

.image-container img {
    width: 100%;
    height: 100%;
    object-fit: cover;  /* Fill container, crop if needed */
    object-position: center;
}

/* Art-directed positioning */
.hero-image {
    object-position: top center;  /* Keep top of image visible */
}

@media (max-width: 600px) {
    .hero-image {
        object-position: center center;  /* Center on mobile */
    }
}

/* Aspect ratio boxes */
.aspect-16-9 {
    aspect-ratio: 16 / 9;
}

.aspect-4-3 {
    aspect-ratio: 4 / 3;
}

.aspect-1-1 {
    aspect-ratio: 1 / 1;
}

/* Lazy load placeholder */
img[loading="lazy"] {
    background: linear-gradient(110deg, #ececec 8%, #f5f5f5 18%, #ececec 33%);
    background-size: 200% 100%;
    animation: shimmer 1.5s linear infinite;
}

@keyframes shimmer {
    to {
        background-position: -200% 0;
    }
}

/* High priority hero image */
.hero img {
    /* fetchpriority="high" in HTML */
    content-visibility: visible;
}

/* Lazy images below fold */
.content img {
    /* loading="lazy" in HTML */
    content-visibility: auto;
}

/* Responsive background images */
.bg-image {
    background-size: cover;
    background-position: center;
}

@media (max-width: 600px) {
    .bg-image {
        background-image: url('mobile.jpg');
    }
}

@media (min-width: 601px) and (max-width: 1200px) {
    .bg-image {
        background-image: url('tablet.jpg');
    }
}

@media (min-width: 1201px) {
    .bg-image {
        background-image: url('desktop.jpg');
    }
}

/* High-resolution background */
@media (resolution >= 2dppx) {
    .bg-image {
        background-image: url('desktop@2x.jpg');
    }
}
Note: Use srcset for resolution switching, <picture> for art direction. Always include alt text. Set aspect-ratio to prevent CLS. Use loading="lazy" for images below fold. Serve modern formats (AVIF, WebP) with fallbacks.

6. Mobile-first vs Desktop-first Strategies

Strategy Approach Pros Cons
Mobile-first Base styles for mobile, use min-width to enhance for larger screens Progressive enhancement, better performance on mobile, simpler CSS May require more rework for desktop-heavy sites
Desktop-first Base styles for desktop, use max-width to adapt for smaller screens Easier for existing desktop sites, familiar workflow Mobile devices load unnecessary desktop CSS, harder to simplify
Hybrid Container queries + viewport queries Component adapts to container, layout adapts to viewport More complex, newer browser support
/* Base styles: Mobile (320px+) */
.container {
    width: 100%;
    padding: 1rem;
}

.nav {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.nav-link {
    padding: 0.75rem;
    font-size: 1rem;
}

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

.hero {
    padding: 2rem 1rem;
}

.hero h1 {
    font-size: 1.75rem;
}

/* Tablet: 768px+ */
@media (min-width: 768px) {
    .container {
        padding: 2rem;
        max-width: 720px;
        margin: 0 auto;
    }
    
    .nav {
        flex-direction: row;
        justify-content: space-between;
    }
    
    .grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 2rem;
    }
    
    .hero {
        padding: 4rem 2rem;
    }
    
    .hero h1 {
        font-size: 2.5rem;
    }
}

/* Desktop: 1024px+ */
@media (min-width: 1024px) {
    .container {
        max-width: 960px;
    }
    
    .grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 3rem;
    }
    
    .hero {
        padding: 6rem 3rem;
    }
    
    .hero h1 {
        font-size: 3.5rem;
    }
}

/* Large Desktop: 1280px+ */
@media (min-width: 1280px) {
    .container {
        max-width: 1200px;
    }
    
    .grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

Example: Desktop-first approach

/* Base styles: Desktop */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 3rem;
}

.nav {
    display: flex;
    justify-content: space-between;
    gap: 2rem;
}

.grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 3rem;
}

.hero h1 {
    font-size: 3.5rem;
}

/* Tablet: Below 1024px */
@media (max-width: 1023px) {
    .container {
        max-width: 960px;
        padding: 2rem;
    }
    
    .grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 2rem;
    }
    
    .hero h1 {
        font-size: 2.5rem;
    }
}

/* Mobile: Below 768px */
@media (max-width: 767px) {
    .container {
        padding: 1rem;
    }
    
    .nav {
        flex-direction: column;
        gap: 0.5rem;
    }
    
    .grid {
        grid-template-columns: 1fr;
        gap: 1rem;
    }
    
    .hero h1 {
        font-size: 1.75rem;
    }
}

/* Small mobile: Below 480px */
@media (max-width: 479px) {
    .container {
        padding: 0.5rem;
    }
    
    .hero h1 {
        font-size: 1.5rem;
    }
}

Example: Hybrid approach with container queries

/* Global layout: Viewport-based (mobile-first) */
.page-container {
    padding: 1rem;
}

@media (min-width: 768px) {
    .page-container {
        padding: 2rem;
    }
}

@media (min-width: 1024px) {
    .page-container {
        display: grid;
        grid-template-columns: 250px 1fr 300px;
        gap: 2rem;
        max-width: 1400px;
        margin: 0 auto;
    }
}

/* Components: Container-based (intrinsic responsive) */
.card-grid {
    container-type: inline-size;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: 1rem;
}

.card {
    /* Adapts to container, not viewport */
}

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

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

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

p {
    font-size: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
}

/* Spacing: Fluid */
.section {
    padding: clamp(2rem, 5vw, 6rem) clamp(1rem, 3vw, 3rem);
}

/* Best of all approaches */
.hybrid-component {
    /* Mobile-first base */
    padding: 1rem;
    
    /* Fluid scaling */
    gap: clamp(0.5rem, 2vw, 2rem);
    
    /* Container query for component */
    container-type: inline-size;
}

@container (min-width: 500px) {
    .hybrid-component {
        display: grid;
        grid-template-columns: 1fr 1fr;
    }
}

/* Viewport query for global layout */
@media (min-width: 1024px) {
    .hybrid-component {
        padding: 2rem;
    }
}

Example: Common responsive breakpoints

/* Standard breakpoint system */

/* Extra small devices (phones) */
/* Default styles, no media query needed */

/* Small devices (large phones, 600px+) */
@media (min-width: 600px) {
    /* ... */
}

/* Medium devices (tablets, 768px+) */
@media (min-width: 768px) {
    /* ... */
}

/* Large devices (desktops, 1024px+) */
@media (min-width: 1024px) {
    /* ... */
}

/* Extra large devices (large desktops, 1280px+) */
@media (min-width: 1280px) {
    /* ... */
}

/* 2K screens (1440px+) */
@media (min-width: 1440px) {
    /* ... */
}

/* 4K screens (2560px+) */
@media (min-width: 2560px) {
    /* ... */
}

/* Tailwind-style breakpoints */
/* sm: 640px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px */

/* Bootstrap-style breakpoints */
/* xs: <576px, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px */

/* Material Design breakpoints */
/* xs: 0-599px, sm: 600-1023px, md: 1024-1439px, lg: 1440-1919px, xl: 1920px+ */

/* Between breakpoints (range queries) */
@media (min-width: 768px) and (max-width: 1023px) {
    /* Tablet only */
}

/* Level 4 syntax (cleaner) */
@media (768px <= width < 1024px) {
    /* Tablet only */
}

/* Orientation-specific */
@media (min-width: 768px) and (orientation: portrait) {
    /* Tablet portrait */
}

@media (min-width: 768px) and (orientation: landscape) {
    /* Tablet landscape */
}

Responsive Design Best Practices

  • Mobile-first is recommended: progressive enhancement, better performance
  • Use min-width for mobile-first, max-width for desktop-first
  • Combine viewport queries (layout) + container queries (components)
  • Use clamp() for fluid typography and spacing (reduces breakpoints)
  • Standard breakpoints: 640px, 768px, 1024px, 1280px, 1536px
  • Test on real devices, not just browser DevTools
  • Use srcset and <picture> for responsive images
  • Respect prefers-reduced-motion and accessibility preferences
  • Touch devices: (hover: none) and (pointer: coarse)
  • Use 100dvh instead of 100vh for mobile full-height