🎨 Responsive Design: Media & Container Queries
The Magic Wardrobe That Knows Your Size
Imagine you have a magic wardrobe. When you’re a tiny baby, it gives you tiny clothes. When you grow into a kid, it gives you kid-sized clothes. When you become a grown-up, it gives you grown-up clothes. It always knows what size you need!
CSS responsive design works exactly like this magic wardrobe!
Your website looks at the screen (phone, tablet, computer) and says: “Aha! This screen is small, so I’ll make the text bigger and stack things vertically!” Or: “This screen is wide, so I’ll put things side by side!”
🎭 The @media Rule: Your Magic Spell
The @media rule is like a magic spell that only works under certain conditions.
Think of it like saying: “IF it’s raining, THEN wear a raincoat.”
In CSS, we say: “IF the screen is small, THEN make the text bigger.”
/* The magic spell! */
@media (max-width: 600px) {
body {
font-size: 18px;
}
}
What this says: “When the screen is 600 pixels wide or less, make the text size 18 pixels.”
🧙♂️ The Spell Structure
@media (condition) {
/* Your styles go here */
/* They only work when
the condition is true! */
}
📺 Media Types: Who’s Watching?
Before we check screen size, we can ask: “What KIND of device is this?”
There are three main types:
| Type | What It Means | Example |
|---|---|---|
screen |
Phones, tablets, computers | Your phone |
print |
When someone prints the page | Paper printout |
all |
Everything (default) | Any device |
/* Only for screens */
@media screen {
body { background: blue; }
}
/* Only when printing */
@media print {
body { background: white; }
}
Real Example: When you print a webpage, you might want to hide the navigation menu and make text black. That’s when @media print helps!
📏 Width & Height: Measuring the Window
The most common questions we ask are about size!
Width Features
/* Screen is EXACTLY 600px wide */
@media (width: 600px) { }
/* Screen is 600px or LESS */
@media (max-width: 600px) { }
/* Screen is 600px or MORE */
@media (min-width: 600px) { }
Height Features
/* Screen height is 800px or less */
@media (max-height: 800px) {
.header { height: 50px; }
}
🎯 Common Breakpoints
Think of these as size labels like S, M, L, XL on clothes:
graph TD A["📱 Phone<br>320-480px"] --> B["📱 Large Phone<br>481-768px"] B --> C["📊 Tablet<br>769-1024px"] C --> D["💻 Desktop<br>1025px+"]
Example: Stack cards on phones, show them side-by-side on tablets:
.card-container {
display: flex;
flex-direction: column;
}
@media (min-width: 768px) {
.card-container {
flex-direction: row;
}
}
🔄 Orientation: Portrait vs Landscape
Is your phone standing up tall like a portrait painting? Or lying on its side like a landscape photo?
/* Phone is upright (taller than wide) */
@media (orientation: portrait) {
.gallery {
grid-template-columns: 1fr;
}
}
/* Phone is sideways (wider than tall) */
@media (orientation: landscape) {
.gallery {
grid-template-columns: 1fr 1fr;
}
}
Fun Fact: When you rotate your phone, the website can automatically rearrange itself! It’s like magic! 🎩
📐 Aspect Ratio: The Shape of Things
Aspect ratio is the relationship between width and height.
Think of it like comparing shapes:
- A square is 1:1 (same width and height)
- A widescreen TV is 16:9 (very wide)
- A portrait photo might be 3:4
/* Square screens */
@media (aspect-ratio: 1/1) {
.hero { height: 100vw; }
}
/* Widescreen displays */
@media (min-aspect-ratio: 16/9) {
.video {
width: 100%;
height: auto;
}
}
/* Tall, narrow screens */
@media (max-aspect-ratio: 3/4) {
.sidebar { display: none; }
}
🔗 Combining Media Queries: The Power of “AND” & “OR”
Sometimes you need multiple conditions! Like saying: “IF it’s raining AND cold, THEN wear a warm raincoat.”
Using AND (comma means OR)
/* AND: Both must be true */
@media screen and (min-width: 600px)
and (orientation: landscape) {
.nav { flex-direction: row; }
}
/* OR: Either can be true (use comma) */
@media (max-width: 400px),
(orientation: portrait) {
.sidebar { display: none; }
}
Using NOT
/* NOT: Everything except print */
@media not print {
.no-print { display: block; }
}
🎪 Complex Example
/* Tablets in landscape mode */
@media screen
and (min-width: 768px)
and (max-width: 1024px)
and (orientation: landscape) {
.content {
padding: 20px;
columns: 2;
}
}
📦 The @container Rule: Even Smarter Boxes!
Here’s where it gets really cool! 🚀
Media queries ask: “How big is the whole screen?”
Container queries ask: “How big is MY parent box?”
Why Does This Matter?
Imagine a card component. Sometimes it’s in a wide sidebar. Sometimes it’s in a narrow sidebar. With @container, the card can adapt to its own space, not the whole screen!
graph LR A["Same Card"] --> B["Wide Sidebar<br>Shows image + text"] A --> C["Narrow Sidebar<br>Shows only text"]
Setting Up a Container
Step 1: Tell CSS which box is the “container”
.card-wrapper {
container-type: inline-size;
container-name: card;
}
Step 2: Write rules based on container size
@container card (min-width: 300px) {
.card {
display: flex;
flex-direction: row;
}
}
@container card (max-width: 299px) {
.card {
display: block;
}
}
Container Type Options
| Type | What It Measures |
|---|---|
inline-size |
Width only (most common) |
size |
Width AND height |
normal |
No container queries |
📐 Container Query Units: Relative Magic
Just like we have vh (viewport height) and vw (viewport width), containers have their own units!
| Unit | Meaning | Example |
|---|---|---|
cqw |
1% of container width | width: 50cqw |
cqh |
1% of container height | height: 50cqh |
cqi |
1% of inline size | padding: 2cqi |
cqb |
1% of block size | margin: 1cqb |
cqmin |
Smaller of cqi/cqb | font-size: 5cqmin |
cqmax |
Larger of cqi/cqb | gap: 2cqmax |
🎨 Practical Example
.card-wrapper {
container-type: inline-size;
}
.card-title {
/* Text grows with container! */
font-size: clamp(1rem, 5cqi, 2rem);
}
.card-image {
/* Image is 40% of container */
width: 40cqw;
}
Why This Is Amazing: Your text and images scale perfectly to fit whatever container they’re in! No more hardcoded pixel values! 🎉
🎯 Putting It All Together
Here’s a real-world example combining everything:
/* Container setup */
.widget-area {
container-type: inline-size;
container-name: widget;
}
/* Base styles */
.widget {
padding: 2cqi;
font-size: clamp(14px, 3cqi, 18px);
}
/* Small container */
@container widget (max-width: 250px) {
.widget {
text-align: center;
}
.widget-icon { display: none; }
}
/* Large container */
@container widget (min-width: 400px) {
.widget {
display: grid;
grid-template-columns: auto 1fr;
gap: 1rem;
}
}
/* Screen-level responsive */
@media (max-width: 480px) {
.widget-area {
width: 100%;
}
}
🌟 Summary: Your Responsive Toolkit
| Tool | What It Does | When to Use |
|---|---|---|
@media |
Checks screen/device | Layout changes based on screen |
| Media Types | Checks device type | Different styles for print/screen |
| Width/Height | Measures viewport | Common breakpoints |
| Orientation | Portrait or landscape | Rotation-aware layouts |
| Aspect Ratio | Width:height ratio | Video/image containers |
| Combining | Multiple conditions | Complex responsive logic |
@container |
Checks parent size | Component-level responsiveness |
| Container Units | Relative to container | Fluid sizing within components |
🚀 You Did It!
You now understand how CSS adapts to any screen, any device, any situation!
Remember:
- Media queries = magic spells for the whole screen
- Container queries = magic spells for individual boxes
- Both together = ultimate responsive power! 💪
Your websites can now be like that magic wardrobe — always giving users exactly what fits them best! ✨
