Responsive CSS

Using responsive CSS is a form of SEO that allows for multiplatform screen support.

Screen sizes

The majority of web traffic is on mobile

  • Mobile ยท 60%
  • Desktop ยท 40%

Devices

  • Watch
  • Mobile
  • Tablet
  • Laptop
  • Desktop
  • TV

Stats Counter โ€” Screen Resolution Market Share
Screen Size Map

Common Breakpoints

You can view a websiteโ€™s breakpoints using Dev Tools

Dev Tools

Mobile S 320px
Mobile M 375px
Mobile L 425px
Tablet 768px
Laptop 1024px
Laptop L 1440px
4K 2560px

Dev Tools โ€” Responsive viewport mode

CSS Frameworks

Tailwind Bootstrap Chakra Primer MUI
Small 40rem 640px 576px 420px 544px 600px
Medium 48rem 768px 768px 768px 768px 900px
Large 64rem 1024px 1024px 1024px 1004px 1200px
XLarge 80rem 1280px 1280px 1280px 1280px 1536px
2XLarge 96rem 1536px 1536px 1536px โ€” โ€”

Tailwind โ€” Breakpoints
Bootstrap โ€” Breakpoints
Chakra โ€” Breakpoints
Primer โ€” Breakpoints
MUI โ€” Breakpoints

Common Page Widths

Documentation

CSS Frameworks

Tailwind โ€” Sizes
Bootstrap โ€” Sizes
Chakra โ€” Sizes

Viewport

index.html
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

Scales the page properly on mobile
MDN Web Docs โ€” Meta viewport

CSS Layout

Reset default style

style.css
body {
margin: 0px;
โ€‰

<body> has a margin of 8px by default

}

Setting width: 100vw; on <body> causes a horizontal scrollbar defect

Content

Website

Hello world

I am Stephcraft

You can contact me at @Stephcraft

index.html
<main>
<section id='hero'></section>
<section id='about'></section>
<section id='contact'></section>
</main>
main.css
main {

This style can be applied to either:

  • main ยท the container
  • section ยท individual sections
  • * ยท all content elements

This allows for full bleed layouts

max-width: 720px;
โ€‰

Set the page width

margin-inline: auto;

Horizontally center the content on Desktop

padding-inline: 1em;
โ€‰

Horizontally space the content on mobile

display: flow-root;
โ€‰

Ensure children margin is contained in section or container

  • flex ยท grid achieve the same result
}

Use section > div.wrapper to allow different background colors for individual sections

Website
header.html
<header>
<!-- logo -->
<a href="/" class="logo">
<img src="/logo.svg" width="64" height="64" alt="Logo"/>
</a>
<!-- pages -->
<nav>
<ul>
<li><a href="/blog">Blog</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
<!-- mobile menu -->
<label class="menu">
<input type='checkbox' name='menu' hidden/>
<img src="/menu.svg" width="64" height="64" alt="Menu"/>
</label>
</header>
header.css
header {
Tweaked <main> โ€” 4 collapsed lines
max-width: 720px;
margin-inline: auto;
padding-inline: 1em;
/* display: flow-root; */
display: grid;
grid-template-columns: 1fr auto 1fr;

Horizontally center the middle content on Desktop

align-items: center;
โ€‰

Vertically center the content

gap: 1em;
nav {
โ€‰

<nav> Layout on Desktop

display: flex;
justify-content: center;
gap: 1em;
}
a { margin-block: 1em; }

Vertically space the content

.logo {
justify-self: start;
โ€‰

Left align the icon in the first cell

}
.mobile {
justify-self: end;
โ€‰

Right align the mobile menu icon in the last cell

grid-column: 3;

Ensure the mobile menu icon is in the last cell on mobile

display: none;
โ€‰

The mobile menu icon is only displayed on mobile

}
ul, li { display: contents; }
โ€‰

Remove the default list styling

}
@media (max-width: calc(175px + 4em)) {

Navbar layout on mobile

  • Size of <nav> ยท 175px + Size of total spacing 4em
  • @media does not support var()
header {
padding-bottom: 1em;
.menu { display: block; }
โ€‰

The mobile menu icon is displayed on mobile

nav {
grid-row: 2;
grid-column: 1 / 4;

Rearrange the <nav> within the grid on mobile

  • Move to the second row of the grid
  • Grow to take up all columns
flex-direction: column;

The <nav> is Vertical on mobile

gap: 0.5em;
}
}
header:has(input[name='menu']:not(:checked)) {
โ€‰

The <nav> is displayed only when the menu is open on mobile

padding-bottom: 0em;
nav {
display: none;
}
}
}
footer.html
<footer>
<section id="footer">
Brand โ€” 19 collapsed lines
<!-- brand -->
<hgroup class="brand">
<!-- logo -->
<h2>
<a href="/" class="logo">
<img src="/logo.svg" width="64" height="64" alt="Logo"/>
</a>
</h2>
<!-- headline -->
<p>...</p>
<!-- social media -->
<nav class="social-media" aria-label="Social Media">
<ul>
<li><a rel="me" href="https://github.com/..." aria-label="GitHub">GitHub</a></li>
<li><a rel="me" href="https://discord.com/..." aria-label="Discord">Discord</a></li>
<li><a rel="me" href="https://twitter.com/..." aria-label="X">X</a></li>
</ul>
</nav>
</hgroup>
<!-- pages -->
<nav>
<hgroup>
<h3>About</h3>
<ul>
<li><a href="/story">Story</a></li>
<li><a href="/help">Help</a></li>
<li><a href="/community">Community</a></li>
</ul>
</hgroup>
<hgroup>
<h3>Blog</h3>
<ul>
<li><a href="/getting-started">Getting Started</a></li>
<li><a href="/technical-notes">Technical Notes</a></li>
<li><a href="/news">What's New</a></li>
</ul>
</hgroup>
</nav>
</section>
Additional sections โ€” 15 collapsed lines
<section id="legal">
<!-- copyright -->
<p>&copy; 2026 Site, Inc. All rights reserved.</p>
<!-- legal documents -->
<nav aria-label="Legal Navigation">
<ul>
<li><a rel="privacy-policy" href="/privacy">Privacy Policy</a></li>
<li><a rel="terms-of-service" href="/terms">Terms of Service</a></li>
</ul>
</nav>
</section>
<section id="credit">
<!-- credit -->
<p>Designed and built by <a href="/about" rel="author">Stephcraft</a></p>
</section>
</footer>
footer.css
footer {
Tweaked <main> โ€” 4 collapsed lines
max-width: 720px;
margin-inline: auto;
padding-inline: 1em;
section { display: flow-root; }
section#footer {
margin-bottom: 1em;
Brand โ€” 9 collapsed lines
display: flex;
flex-wrap: wrap;
gap: 1em;
hgroup.brand > nav.social-media {
display: flex;
justify-content: center;
gap: 1em;
}
nav {
โ€‰

Row layout

display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
hgroup {

Column layout

display: flex;
flex-direction: column;
margin-bottom: 1em;
}
}
Additional sections โ€” 8 collapsed lines
section#legal {
nav {
display: flex;
justify-content: center;
gap: 1em;
margin-block: 1em;
}
}
p { text-align: center; }
ul, li { display: contents; }
โ€‰

Remove the default list styling

}

Aside

Website
Header

Related pages

Hello world

I am Stephcraft

You can contact me at @Stephcraft

index.html
<aside id='documents'></aside>
<main>
<section id='hero'><section>
<section id='about'></section>
<section id='contact'></section>
</main>
<aside id='table-of-contents'></aside>
main.css
body {

Apply a full bleed grid layout template

  • Each line is named to be referenced later
display: grid;
/*
[ 1fr ][ min/max ][ 1fr ]
[ left ][ content ][ right ]
[ full ] */
grid-template-columns:
[full-start left-start]
1fr
[content-start left-end]
minmax(auto, calc(720px + 1em * 2))
โ€‰

Set the page width

  • The Horizontal spacing should be defined in either calc() or gap
  • minmax(auto, 720px) is equivalent to max-width: 720px
[content-end right-start]
1fr
[full-end right-end];
}
main, header, footer {
grid-column: content;

Place <main> <header> <footer> in the column content

Tweaked <main> โ€” 5 collapsed lines
max-width: 720px;
/* margin-inline: auto; */
padding-inline: 1em;
display: flow-root;
box-sizing: border-box;
}
/* left <aside> */
aside:has(+ main) {
grid-column: left;

Place <aside> in the column left

justify-self: end;
โ€‰

Right align <aside> next to content

}
/* right <aside> */
main + aside {
grid-column: right;

Place <aside> in the column right

justify-self: start;
โ€‰

Left align <aside> next to content

}
aside {
grid-row: 1 / 1000;

Grow <aside> to take up all columns

  • 1 aligns alongside the content
  • 0 aligns at the top of the page
  • 1000 a large number ยท closest equivalent to auto
}
@media (max-width: calc(720px + 150px + 150px)) {

Remove <aside> on smaller screens ยท this one is removed first

  • Size of <main> ยท 720px + Size of both <aside> 150px + 150px
  • @media does not support var()
aside#table-of-contents {
display: none;
}
}
@media (max-width: calc(720px + 150px)) {

Remove <aside> on smaller screens ยท this one is removed last

  • Size of <main> ยท 720px + Size of this <aside> 150px
  • @media does not support var()
aside#documents {
display: none;
}
}

Media

Image

Website
index.html
<img src="image.png"/>
style.css
img {
display: block;
โ€‰

Images are inline by default causing a bottom offset defect

  • Inline elements follow the text baseline height
max-inline-size: 100%;
โ€‰

Ensure Images don't overflow the container

  • Equivalent to max-width
block-size: auto;

Ensure Images aspect ratio is maintained

  • Equivalent to height
}

Web.dev Docs โ€” Responsive images

Picture

Website

Portal 3

index.html
<picture>
<source srcset="image-portrait.png" media="(orientation: portrait)"/>

Image displayed in portrait orientation

<source srcset="image-landscape.png" media="(orientation: landscape)"/>

Image displayed in landscape orientation

<img src="image-landscape.png"/>
โ€‰

Fallback Image

</picture>

Web.dev Docs โ€” Picture element
MDN Web Docs โ€” Picture element

Video

Website

Minecraft

index.html
<video autoplay loop>
<source src="image-portrait.png" type="video/mp4" media="(orientation: portrait)"/>

Video displayed in portrait orientation

<source src="image-landscape.png" type="video/mp4" media="(orientation: landscape)"/>

Video displayed in landscape orientation

</picture>
style.css
video {
max-inline-size: 100%;
โ€‰

Ensure Video doesn't overflow the container

  • Equivalent to max-width
block-size: auto;

Ensure Video aspect ratio is maintained

  • Equivalent to height
}

Typography

Text units

The default font size is 16px

rem Default font size ยท 16px
em Relative font size

Fluid text size

Website

Hello world

Luxury-grade software craftsmanship across Minecraft modding, developer tooling, and interactive experiences, backed by 10 years of hands-on development.

style.css
body {
font-size: clamp(0.75rem, 0.75rem + 1vw, 1rem);
โ€‰

Fluid font size with clamp(min, formula, max) allows to dynamically scale text

  • The formula must use vw units to scale
  • The font size is between min and max

Web.dev Docs โ€” Clamping text

}

Utopia โ€” Fluid Type clamp generator

Text overflow

Website

Luxury-grade software craftsmanship across Minecraft modding, developer tooling, and interactive experiences, backed by 10 years of hands-on development.

Luxury-grade software craftsmanship across Minecraft modding, Developer tooling, and Interactive experiences, backed by 10 years of hands-on development.

Luxury-grade software craftsmanship

Unbelievable misunderstandings occasionally create unnecessary complications

index.html
<p class='ellipsis'>Luxury-grade software craftsmanship across Minecraft modding, developer tooling, and interactive experiences, backed by 10 years of hands-on development.</p>
โ€‰

Clip text and suffix with ...

<p>Luxury-grade software craftsmanship across <strong>Minecraft modding</strong>, <strong>Developer tooling</strong>, and <strong>Interactive experiences</strong>, backed by 10 years of hands-on development.</p>
โ€‰

strong text break on the same line

<p>Luxury-grade software <em>crafts<wbr/>man<wbr/>ship</em></p>
โ€‰

<wbr> word break opportunities

style.css
p.ellipsis {
white-space: nowrap;
โ€‰

Disable Text wrap

overflow: hidden;

Clip Text overflow

text-overflow: ellipsis;
โ€‰

Enable Text ellipsis

}
p strong {
white-space: nowrap;
โ€‰

Disable Text wrap for small terms on Desktop

}
@media (max-width: 200px) {
p strong {
white-space: normal;
โ€‰

Enable Text wrap for small terms on mobile

}
}
body {
overflow-wrap: anywhere;
โ€‰

Ensures Words wrap on mobile

}

Type scale system

Website

Title

Subtitle

Heading 3

Heading 4

Heading 5
Heading 6

Paragraph

index.html
<h1>Title</h1>
<h2>Subtitle</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<p>Paragraph</p>
style.css
h1 {
font-size: 2em;
margin-block: 0.67em; /* 2:3 */
}
h2..h6 โ€” 24 collapsed lines
h2 {
font-size: 1.5em;
margin-block: 0.83em; /* 5:6 */
}
h3 {
font-size: 1.17em; /* 7:6 */
margin-block: 1em;
}
h4 {
font-size: 1em;
margin-block: 1.33em; /* 4:3 */
}
h5 {
font-size: 0.83em; /* 5:6 */
margin-block: 1.67em; /* 5:3 */
}
h6 {
font-size: 0.67em; /* 2:3 */
margin-block: 2.33em; /* 7:3 */
}
p {
font-size: 1em;
margin-block: 1em;
}

Utopia โ€” Fluid Type scale generator
GitHub โ€” Default heading styles

Collection

Flex

Website
Notch
Gabe Newell
Hideo Kojima
Asha Sharma
index.html
<div class='flex'>
{data.map((tag) => (
<div class='tag'>{tag}</div>
))}
</div>
style.css
.flex {
display: flex;
flex-wrap: wrap;
โ€‰

Allow items to wrap on new lines
MDN Web Docs โ€” flex-wrap

}

CSS Tricks Docs โ€” Flexbox

Grid

Website
Half Life

Half Life

Left 4 Dead

Left 4 Dead

Death Stranding

Death Stranding

Borderlands

Borderlands

Warframe

Warframe

Call of Duty

Call of Duty

index.html
<div class='grid'>
{data.map(([image, title]) => (
<div class='card'>
<img src={image} alt={title}/>
<h3>{title}</h3>
</div>
))}
</div>
style.css
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
โ€‰

Allows responsive grid

  • repeat(auto-fit, โ€ฆ) Dynamic column count
  • minmax(150px, 1fr) Fit elements of minimum width 150px
  • min(150px, 100%) Limit element size to viewport width below 150px on mobile

Kevin Powell โ€” Breakpoint-Free CSS Grid Layouts

}

CSS Tricks Docs โ€” Grid

Conditional

index.html
<link rel="stylesheet" href="/style.css"/>
<link rel="alternate stylesheet" href="/desktop.css" media="(min-width: 800px)"/>
<link rel="alternate stylesheet" href="/mobile.css" media="(max-width: 800px)"/>

MDN Web Docs โ€” Link media queries

Stylesheet imports

style.css
@import "style.css";
@import "desktop.css" (min-width: 800px);
@import "mobile.css" (max-width: 800px);

MDN Web Docs โ€” CSS import media queries

Document styles

style.css
@media (min-width: 720px) {}
@media (max-width: 720px) {}
@media (hover: none) {}

MDN Web Docs โ€” CSS media queries

Container styles

style.css
.container {
container-type: inline-size;
}
@container (min-width: 400px) {}

MDN Web Docs โ€” CSS container queries

Tools

Testing

Dev Tools โ€” Device mode

Typography

Utopia โ€” Fluid Type clamp generator
Utopia โ€” Fluid Type scale generator

Resources

MDN Web Docs โ€” Responsive web design
MDN Web Docs โ€” CSS media queries
Web.dev โ€” Learn Responsive Design
Wikipedia โ€” Responsive web design

Additional Resources

Josh Comeau โ€” Full-Bleed Layout Using CSS Grid
Web.dev Docs โ€” Modern layouts
Web.dev Docs โ€” Responsive web design
Web.dev Docs โ€” Responsive typography
Web.dev Docs โ€” Responsive images
Web.dev Docs โ€” Component-driven responsive web design
W3Schools Docs โ€” Responsive Web Design
W3Schools Docs โ€” HTML and CSS Responsive Design