Day 8: Responsive Design
What You Will Learn Today
- The principles of responsive design
- The viewport meta tag
- Media queries and breakpoints
- The mobile-first approach
- Responsive images and media
- The
clamp()function for fluid typography - Container queries
What is Responsive Design?
Responsive design is an approach to web design that ensures your pages look great on every screen size -- from phones to ultra-wide monitors.
flowchart LR
subgraph Devices["Different Devices"]
Mobile["Mobile<br>up to 767px"]
Tablet["Tablet<br>768 - 1023px"]
Desktop["Desktop<br>1024px+"]
end
style Mobile fill:#22c55e,color:#fff
style Tablet fill:#f59e0b,color:#fff
style Desktop fill:#3b82f6,color:#fff
The Three Pillars
| Pillar | Description |
|---|---|
| Fluid Layouts | Use %, fr, and flexible units instead of fixed widths |
| Media Queries | Apply different styles based on screen characteristics |
| Flexible Media | Images and videos that resize automatically |
The Viewport Meta Tag
This tag is a prerequisite for responsive design.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Required: Without this meta tag, mobile browsers will render the page at a desktop width and scale it down, making your media queries useless.
Media Queries
Basic Syntax
@media (max-width: 768px) {
.container {
padding: 16px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1200px;
}
}
Common Breakpoints
/* Smartphones */
@media (max-width: 767px) { ... }
/* Tablets */
@media (min-width: 768px) and (max-width: 1023px) { ... }
/* Desktops */
@media (min-width: 1024px) { ... }
/* Large screens */
@media (min-width: 1280px) { ... }
| Breakpoint | Target Device |
|---|---|
| 640px | Small smartphones |
| 768px | Tablets |
| 1024px | Laptops |
| 1280px | Desktops |
| 1536px | Large displays |
The Mobile-First Approach
Write styles for the smallest screen first, then layer on enhancements for larger screens using min-width queries.
/* Mobile (default styles) */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
/* Tablets and up */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktops and up */
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
}
flowchart LR
Mobile["Mobile<br>1 column"] -->|"768px"| Tablet["Tablet<br>2 columns"]
Tablet -->|"1024px"| Desktop["Desktop<br>3 columns"]
style Mobile fill:#22c55e,color:#fff
style Tablet fill:#f59e0b,color:#fff
style Desktop fill:#3b82f6,color:#fff
Why mobile-first? Mobile users make up the majority of web traffic. Starting with the minimal layout and progressively enhancing it is more efficient and produces cleaner CSS.
Responsive Images
img {
max-width: 100%;
height: auto;
}
Responsive Video Embeds
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
height: 0;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Modern approach: The
aspect-ratioproperty simplifies this significantly.
.video-wrapper {
aspect-ratio: 16 / 9;
width: 100%;
}
.video-wrapper iframe {
width: 100%;
height: 100%;
}
Responsive Navigation
/* Mobile: vertical stack */
.nav-links {
display: flex;
flex-direction: column;
gap: 8px;
}
/* Desktop: horizontal row */
@media (min-width: 768px) {
.nav-links {
flex-direction: row;
gap: 24px;
}
}
Responsive Typography with clamp()
The clamp() function sets a value that scales fluidly between a minimum and maximum.
h1 {
/* Minimum 2rem, preferred 5vw, maximum 4rem */
font-size: clamp(2rem, 5vw, 4rem);
}
p {
font-size: clamp(1rem, 2.5vw, 1.25rem);
}
| Argument | Purpose |
|---|---|
| Minimum | The value will never go below this |
| Preferred | Scales with the viewport |
| Maximum | The value will never exceed this |
Best practice:
clamp()lets you create smoothly scaling typography without any media queries at all.
Container Queries
Instead of responding to the viewport size, container queries respond to the size of a parent container.
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
gap: 16px;
}
}
@container (min-width: 600px) {
.card {
font-size: 1.125rem;
}
}
Note: Container queries are supported in all modern browsers and are especially useful for reusable components that may appear in containers of varying widths.
Practice: Responsive Landing Page
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--color-primary: #3b82f6;
--max-width: 1200px;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.6;
color: #1e293b;
}
img {
max-width: 100%;
height: auto;
}
/* Header */
.header {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
padding: 16px;
}
/* Hero */
.hero {
text-align: center;
padding: 48px 16px;
}
.hero h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
margin-bottom: 16px;
}
/* Card Grid */
.cards {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
padding: 32px 16px;
max-width: var(--max-width);
margin: 0 auto;
}
/* Footer */
.footer {
background: #1e293b;
color: #94a3b8;
text-align: center;
padding: 32px 16px;
}
/* Tablet and up */
@media (min-width: 768px) {
.header {
flex-direction: row;
justify-content: space-between;
padding: 16px 32px;
}
.hero {
padding: 80px 32px;
}
.cards {
grid-template-columns: repeat(2, 1fr);
gap: 24px;
padding: 48px 32px;
}
}
/* Desktop and up */
@media (min-width: 1024px) {
.cards {
grid-template-columns: repeat(3, 1fr);
}
}
Summary
| Concept | Description |
|---|---|
| Responsive Design | Adapts to any screen size |
| Media Queries | Conditional styles with @media |
| Mobile-First | Build from small to large with min-width |
clamp() |
Fluid values with min, preferred, and max |
| Container Queries | Styles based on parent container size |
max-width: 100% |
Makes images responsive |
Key Takeaways
- The viewport meta tag is essential
- Use the mobile-first approach with
min-widthqueries clamp()enables media-query-free responsive sizingauto-fit+minmax()creates flexible grids automatically
Exercises
Exercise 1: Basics
Create a grid that displays 1 column on mobile, 2 on tablet, and 3 on desktop.
Exercise 2: Intermediate
Build a navigation that stacks vertically on mobile and displays horizontally on desktop.
Challenge
Create an entirely responsive page using only clamp(), auto-fit, and minmax() -- no media queries allowed.
References
Next up: In Day 9, you will learn about Transitions and Animations -- how to bring your designs to life with smooth, performant motion using pure CSS.