1. Mobile-First Media Queries
What is a Media Query?
A media query is a CSS feature that allows us to apply different CSS styles based on the conditions of the device or viewport.
In simple words:
“If this condition is true, apply these CSS rules.”
For example:
@media (min-width: 768px) {
.container {
display: flex;
}
}
Enter fullscreen mode Exit fullscreen mode
This means:
If the viewport width is 768px or greater, apply the styles inside the media query.
Media queries are mainly used to create responsive websites that adapt to different screen sizes such as mobile phones, tablets, laptops, and desktops.
What is Responsive Web Design?
A responsive website automatically adapts its layout and appearance according to the available screen size.
For example:
Mobile:
[ Card 1 ]
[ Card 2 ]
[ Card 3 ]
Enter fullscreen mode Exit fullscreen mode
Desktop:
[ Card 1 ] [ Card 2 ] [ Card 3 ]
Enter fullscreen mode Exit fullscreen mode
The same website can use different layouts depending on the viewport size.
Basic Syntax of a Media Query
@media media-type and (condition) {
/* CSS rules */
}
Enter fullscreen mode Exit fullscreen mode
Example:
@media screen and (max-width: 600px) {
body {
background: lightblue;
}
}
Enter fullscreen mode Exit fullscreen mode
There are three important parts:
@media
↓
media type
↓
condition
↓
CSS rules
Enter fullscreen mode Exit fullscreen mode
However, the media type is optional, so this is also very common:
@media (max-width: 600px) {
body {
background: lightblue;
}
}
Enter fullscreen mode Exit fullscreen mode
Media Types
A media type specifies the type of output device or presentation.
1. screen
Used for screens such as:
- Mobile phones
- Tablets
- Laptops
- Desktop monitors
Example:
@media screen and (max-width: 600px) {
body {
font-size: 14px;
}
}
Enter fullscreen mode Exit fullscreen mode
2. print
Used when the webpage is being printed or viewed in print preview.
For example, we may want to hide navigation when printing:
@media print {
nav {
display: none;
}
}
Enter fullscreen mode Exit fullscreen mode
3. speech
Used for speech-based presentation, such as speech synthesizers and screen-reading technologies.
@media speech {
/* speech-related styles */
}
Enter fullscreen mode Exit fullscreen mode
This is less commonly used in everyday responsive development.
4. all
Represents all media types.
@media all {
/* styles */
}
Enter fullscreen mode Exit fullscreen mode
In normal responsive development, we usually don’t need to explicitly write all.
Important Media Features
Media queries can check many different conditions.
The most commonly used ones are:
min-width
max-width
min-height
max-height
orientation
prefers-color-scheme
hover
pointer
resolution
Enter fullscreen mode Exit fullscreen mode
min-width
min-width means:
“The viewport width must be greater than or equal to this value.”
Example:
@media (min-width: 768px) {
.container {
display: flex;
}
}
Enter fullscreen mode Exit fullscreen mode
This applies when:
768px or more → YES
767px or less → NO
Enter fullscreen mode Exit fullscreen mode
Think of it as:
width >= 768px
Enter fullscreen mode Exit fullscreen mode
max-width
max-width means:
“The viewport width must be less than or equal to this value.”
Example:
@media (max-width: 768px) {
.container {
padding: 10px;
}
}
Enter fullscreen mode Exit fullscreen mode
This applies when:
768px or less → YES
769px or more → NO
Enter fullscreen mode Exit fullscreen mode
Think of it as:
width <= 768px
Enter fullscreen mode Exit fullscreen mode
What is Mobile-First Design?
Mobile-first design means we first write the default CSS for smaller screens and then progressively add styles for larger screens.
The basic pattern is:
/* Mobile / default styles */
.container {
display: block;
}
/* Larger screens */
@media (min-width: 768px) {
.container {
display: flex;
}
}
Enter fullscreen mode Exit fullscreen mode
The idea is:
Mobile
↓
Base CSS
↓
Tablet / larger screen
↓
min-width
↓
Desktop
Enter fullscreen mode Exit fullscreen mode
So mobile-first development generally uses min-width media queries.
Example of Mobile-First Design
Suppose we have three cards.
On mobile, we want them stacked:
.container {
display: flex;
flex-direction: column;
gap: 20px;
}
Enter fullscreen mode Exit fullscreen mode
On larger screens, we want them in a row:
@media (min-width: 768px) {
.container {
flex-direction: row;
}
}
Enter fullscreen mode Exit fullscreen mode
The result is:
Mobile:
[ Card 1 ]
[ Card 2 ]
[ Card 3 ]
Enter fullscreen mode Exit fullscreen mode
Larger screen:
[ Card 1 ] [ Card 2 ] [ Card 3 ]
Enter fullscreen mode Exit fullscreen mode
Why Mobile-First?
Mobile-first design starts with the smallest and simplest layout and progressively enhances it for larger screens.
Advantages include:
- Better mobile experience
- Simpler base CSS
- Easier responsive design
- Less unnecessary CSS
- Works well with modern responsive development
Instead of starting with a complicated desktop layout and trying to remove things for mobile, we start simple and add features as more space becomes available.
min-width vs max-width
Mobile-first
/* Default = mobile */
.card {
width: 100%;
}
@media (min-width: 768px) {
.card {
width: 50%;
}
}
Enter fullscreen mode Exit fullscreen mode
The direction is:
Small → Large
Enter fullscreen mode Exit fullscreen mode
Desktop-first
/* Default = desktop */
.card {
width: 25%;
}
@media (max-width: 768px) {
.card {
width: 100%;
}
}
Enter fullscreen mode Exit fullscreen mode
The direction is:
Large → Small
Enter fullscreen mode Exit fullscreen mode
Both approaches are valid, but mobile-first is a very common and useful approach for responsive websites.
and
The and operator means both conditions must be true.
Example:
@media (min-width: 768px) and (max-width: 1200px) {
.container {
padding: 30px;
}
}
Enter fullscreen mode Exit fullscreen mode
This means:
width >= 768px
AND
width <= 1200px
Enter fullscreen mode Exit fullscreen mode
So:
700px → ❌
768px → ✅
900px → ✅
1200px → ✅
1300px → ❌
Enter fullscreen mode Exit fullscreen mode
Using Multiple Conditions with ,
A comma acts like OR between media queries.
Example:
@media (max-width: 600px), (orientation: portrait) {
.container {
padding: 10px;
}
}
Enter fullscreen mode Exit fullscreen mode
This means the styles apply if:
width <= 600px
OR
orientation is portrait
Enter fullscreen mode Exit fullscreen mode
If either condition is true, the styles can apply.
not
The not keyword negates a media query.
For example:
@media not print {
/* styles */
}
Enter fullscreen mode Exit fullscreen mode
This means the styles apply when the presentation is not print.
not is useful to know, but in everyday responsive development, min-width and max-width are used much more frequently.
orientation
The orientation feature checks whether the viewport is portrait or landscape.
Portrait
@media (orientation: portrait) {
.container {
padding: 10px;
}
}
Enter fullscreen mode Exit fullscreen mode
Portrait generally means the viewport is taller than it is wide.
┌──────────┐
│ │
│ │
│ │
│ │
└──────────┘
Enter fullscreen mode Exit fullscreen mode
Landscape
@media (orientation: landscape) {
.container {
padding: 30px;
}
}
Enter fullscreen mode Exit fullscreen mode
Landscape generally means the viewport is wider than it is tall.
┌──────────────────┐
│ │
│ │
└──────────────────┘
Enter fullscreen mode Exit fullscreen mode
Other Useful Media Features
prefers-color-scheme
Detects whether the user prefers a light or dark color scheme.
@media (prefers-color-scheme: dark) {
body {
background: black;
color: white;
}
}
Enter fullscreen mode Exit fullscreen mode
hover
Checks whether the user’s primary input device supports hovering.
@media (hover: hover) {
button:hover {
transform: scale(1.05);
}
}
Enter fullscreen mode Exit fullscreen mode
pointer
Can be used to detect pointer characteristics.
@media (pointer: coarse) {
button {
padding: 20px;
}
}
Enter fullscreen mode Exit fullscreen mode
This can be useful for touch-based interfaces where larger controls are easier to use.
Media Queries Are Not Only for Width
Media queries can change almost any CSS property.
For example:
h1 {
font-size: 2rem;
}
@media (min-width: 768px) {
h1 {
font-size: 3rem;
}
}
Enter fullscreen mode Exit fullscreen mode
You can also change:
display
flex-direction
grid columns
font-size
padding
margin
width
height
gap
visibility
position
and many other CSS properties
Enter fullscreen mode Exit fullscreen mode
Important Rule About Breakpoints
Do not blindly memorize:
768px = tablet
1024px = laptop
1200px = desktop
Enter fullscreen mode Exit fullscreen mode
These are commonly used values, but they are not strict device definitions.
Choose breakpoints based on when your layout actually needs to change.
For example, if your cards become too cramped at 850px, you might use:
@media (min-width: 850px) {
/* layout changes */
}
Enter fullscreen mode Exit fullscreen mode
The design should determine the breakpoint.
Simple Mental Model for Media Queries
Think of a media query like a CSS if statement:
IF condition is true
↓
apply these CSS rules
Enter fullscreen mode Exit fullscreen mode
For example:
@media (min-width: 768px) {
.container {
display: flex;
}
}
Enter fullscreen mode Exit fullscreen mode
Means:
IF viewport width >= 768px
↓
make .container a flex container
Enter fullscreen mode Exit fullscreen mode
2. Fluid Typography
Fluid typography means creating text whose size can smoothly grow or shrink according to the viewport size.
Traditional responsive typography might look like this:
h1 {
font-size: 32px;
}
@media (min-width: 768px) {
h1 {
font-size: 48px;
}
Enter fullscreen mode Exit fullscreen mode
This creates fixed steps:
Mobile → 32px
Desktop → 48px
Enter fullscreen mode Exit fullscreen mode
Fluid typography allows the size to change gradually:
32px
↓
34px
↓
36px
↓
39px
↓
42px
↓
45px
↓
48px
Enter fullscreen mode Exit fullscreen mode
The main CSS concepts used for fluid typography are:
rem
vw
clamp()
Enter fullscreen mode Exit fullscreen mode
rem
rem stands for root em.
It is relative to the font size of the root <html> element.
Browsers commonly use:
html {
font-size: 16px;
}
Enter fullscreen mode Exit fullscreen mode
Therefore:
1rem = 16px
2rem = 32px
3rem = 48px
4rem = 64px
Enter fullscreen mode Exit fullscreen mode
Example:
h1 {
font-size: 3rem;
}
Enter fullscreen mode Exit fullscreen mode
With a 16px root font size:
3rem = 48px
Enter fullscreen mode Exit fullscreen mode
Why Use rem?
rem provides scalable and consistent sizing.
For example:
body {
font-size: 1rem;
}
h1 {
font-size: 3rem;
}
p {
font-size: 1rem;
}
Enter fullscreen mode Exit fullscreen mode
Instead of hardcoding every value in pixels, the sizes are based on the root font size.
rem is especially useful for:
- Typography
- Spacing
- Scalable layouts
- Accessibility-friendly sizing
vw
vw means viewport width.
1vw = 1% of the viewport width
Enter fullscreen mode Exit fullscreen mode
For example, if the viewport width is:
1000px
Enter fullscreen mode Exit fullscreen mode
then:
1vw = 10px
Enter fullscreen mode Exit fullscreen mode
If the viewport width is:
500px
Enter fullscreen mode Exit fullscreen mode
then:
1vw = 5px
Enter fullscreen mode Exit fullscreen mode
Therefore, vw naturally changes when the viewport width changes.
Example of vw
h1 {
font-size: 5vw;
}
Enter fullscreen mode Exit fullscreen mode
The font size changes according to the viewport width.
However, using only vw can be problematic.
On a very small screen, the font may become too small.
On a very large screen, it may become extremely large.
For example:
Small screen
5vw → potentially too small
Huge screen
5vw → potentially too large
Enter fullscreen mode Exit fullscreen mode
This is why clamp() is extremely useful.
clamp()
clamp() allows us to define a minimum value, preferred value, and maximum value.
The syntax is:
clamp(minimum, preferred, maximum)
Enter fullscreen mode Exit fullscreen mode
Example:
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
Enter fullscreen mode Exit fullscreen mode
This means:
Minimum → 2rem
Preferred → 5vw
Maximum → 4rem
Enter fullscreen mode Exit fullscreen mode
In simple words:
Let the font size scale according to
5vw, but never let it become smaller than2remor larger than4rem.
How clamp() Works
Suppose:
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
Enter fullscreen mode Exit fullscreen mode
Assuming:
1rem = 16px
Enter fullscreen mode Exit fullscreen mode
we have:
2rem = 32px
4rem = 64px
Enter fullscreen mode Exit fullscreen mode
So the range is:
Minimum = 32px
Maximum = 64px
Enter fullscreen mode Exit fullscreen mode
Now imagine different viewport sizes.
Small viewport
5vw = 16px
Enter fullscreen mode Exit fullscreen mode
But the minimum is 32px.
Therefore:
font-size = 32px
Enter fullscreen mode Exit fullscreen mode
Medium viewport
5vw = 40px
Enter fullscreen mode Exit fullscreen mode
40px is within the allowed range.
Therefore:
font-size = 40px
Enter fullscreen mode Exit fullscreen mode
Large viewport
5vw = 60px
Enter fullscreen mode Exit fullscreen mode
60px is still within the allowed range.
Therefore:
font-size = 60px
Enter fullscreen mode Exit fullscreen mode
Very large viewport
5vw = 100px
Enter fullscreen mode Exit fullscreen mode
But the maximum is 64px.
Therefore:
font-size = 64px
Enter fullscreen mode Exit fullscreen mode
So the result is approximately:
Viewport Font Size
Small 32px ← minimum
Medium 40px
Large 60px
Very Large 64px ← maximum
Enter fullscreen mode Exit fullscreen mode
The Three Parts of clamp()
Remember:
clamp(2rem, 5vw, 4rem)
↑ ↑ ↑
MIN IDEAL MAX
Enter fullscreen mode Exit fullscreen mode
First value → Minimum
2rem
Enter fullscreen mode Exit fullscreen mode
The value should not go below this.
Second value → Preferred
5vw
Enter fullscreen mode Exit fullscreen mode
The value tries to scale fluidly according to the viewport.
Third value → Maximum
4rem
Enter fullscreen mode Exit fullscreen mode
The value should not exceed this.
Why Use clamp() for Typography?
Without clamp(), we might write many media queries:
h1 {
font-size: 32px;
}
@media (min-width: 600px) {
h1 {
font-size: 36px;
}
}
@media (min-width: 900px) {
h1 {
font-size: 42px;
}
}
@media (min-width: 1200px) {
h1 {
font-size: 48px;
}
}
Enter fullscreen mode Exit fullscreen mode
With clamp():
h1 {
font-size: clamp(2rem, 5vw, 3rem);
}
Enter fullscreen mode Exit fullscreen mode
The browser can calculate an appropriate size between the minimum and maximum.
Does clamp() Replace Media Queries?
No.
clamp() can reduce the need for media queries when we only need to change a value smoothly.
For example:
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
Enter fullscreen mode Exit fullscreen mode
This can replace several typography-specific breakpoints.
However, media queries are still needed when the layout or behavior itself needs to change.
For example:
Mobile:
[ Menu Button ]
Desktop:
[ Home | About | Projects | Contact ]
Enter fullscreen mode Exit fullscreen mode
We still need a media query to change the layout or visibility.
So remember:
clamp()
→ controls a fluid value
media query
→ changes CSS rules based on a condition
Enter fullscreen mode Exit fullscreen mode
rem vs vw vs clamp()
rem
font-size: 2rem;
Enter fullscreen mode Exit fullscreen mode
Means:
Scale relative to the root font size.
vw
font-size: 5vw;
Enter fullscreen mode Exit fullscreen mode
Means:
Scale relative to the viewport width.
clamp()
font-size: clamp(2rem, 5vw, 4rem);
Enter fullscreen mode Exit fullscreen mode
Means:
Scale fluidly using
5vw, but stay between2remand4rem.
Fluid Typography Example
A modern responsive heading could be:
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
Enter fullscreen mode Exit fullscreen mode
A paragraph could use:
p {
font-size: clamp(1rem, 1.5vw, 1.25rem);
}
Enter fullscreen mode Exit fullscreen mode
A section’s spacing can also be fluid:
section {
padding: clamp(1rem, 5vw, 5rem);
}
Enter fullscreen mode Exit fullscreen mode
So clamp() is not limited to fonts. It can be used for many CSS properties that accept suitable numeric values.
Mobile-First + Fluid Typography Together
These two concepts work together very well.
For example:
/* Base/mobile styles */
.hero-title {
font-size: clamp(2rem, 5vw, 4rem);
}
.container {
display: grid;
grid-template-columns: 1fr;
}
/* Larger screens */
@media (min-width: 768px) {
.container {
grid-template-columns: 1fr 1fr;
}
}
Enter fullscreen mode Exit fullscreen mode
Here:
clamp()
→ controls the fluid heading size
media query
→ changes the layout
Enter fullscreen mode Exit fullscreen mode
We don’t have to choose between them.
Final Comparison
MEDIA QUERY
↓
"When this condition is true,
change my CSS rules."
Example:
@media (min-width: 768px)
rem
↓
"Scale relative to the root font size."
Example:
2rem
vw
↓
"Scale relative to the viewport width."
Example:
5vw
clamp()
↓
"Keep a value between a minimum
and maximum while allowing it
to scale fluidly."
Example:
clamp(2rem, 5vw, 4rem)
Enter fullscreen mode Exit fullscreen mode
Quick Cheat Sheet
Media Query
@media (min-width: 768px) {
/* styles */
}
Enter fullscreen mode Exit fullscreen mode
Mobile-first
/* Mobile/default */
.element {
...
}
/* Larger screens */
@media (min-width: 768px) {
.element {
...
}
}
Enter fullscreen mode Exit fullscreen mode
rem
font-size: 2rem;
Enter fullscreen mode Exit fullscreen mode
rem = relative to the root font size.
vw
font-size: 5vw;
Enter fullscreen mode Exit fullscreen mode
vw = 1% of viewport width.
clamp()
font-size: clamp(2rem, 5vw, 4rem);
Enter fullscreen mode Exit fullscreen mode
MINIMUM → PREFERRED → MAXIMUM
2rem 5vw 4rem
Enter fullscreen mode Exit fullscreen mode
Most important idea:
Media queries decide WHEN CSS rules change.
remandvwprovide relative sizing, whileclamp()allows a value to scale fluidly within a safe minimum and maximum range.
답글 남기기
댓글을 달기 위해서는 로그인해야합니다.