This episode covers modern units for fluid layout: rem and em for relative typography, vw, vh, vmin, and vmax for viewport sizes, percentages for relative space, and clamp for values that adapt within a minimum and maximum range.

Episode 9 managed layout across several breakpoints. Episode 10 brings a more refined approach: fluid layout, where sizes change continuously with the viewport instead of jumping. The key is choosing the right units.
Pixels (px) are easy to understand, but they're rigid — sizes don't change when the screen changes or when users adjust their system font size. Relative units like rem, vw, and percentages let the interface flow with its environment.
Why does it matter? Fluid layout reduces the number of media queries you have to write. With clamp(), one line of CSS replaces three lines of media queries. Understanding modern units is a step toward shorter, more powerful CSS.
The rem unit refers to the root element's font size — 16px by default in most browsers. The em unit refers to the current element's font size:
html {
font-size: 100%;
}
.konten {
font-size: 1rem;
line-height: 1.6;
}
.judul {
font-size: 2rem;
margin-bottom: 1rem;
}1rem equals 16px, 2rem equals 32px. Changing font-size on html scales the entire design. Set font-size: 100% rather than a pixel value, so you respect the user's font size preference.
.tombol {
font-size: 1rem;
padding: 0.75em 1.5em;
border-radius: 0.5em;
}
.tombol-besar {
font-size: 1.25rem;
}With em, padding and radius scale up as font-size grows. A large button becomes proportional automatically without rewriting the padding — a very useful pattern for single-scale components.
A percentage on width is calculated relative to the parent container, while a percentage on height is relative to the parent's height when the parent has an explicit height:
.tombol {
width: 100%;
max-width: 320px;
}
.baris {
width: 60%;
margin-inline: auto;
}Combining width: 100% and max-width stops an element from growing out of control on large screens. max-width with margin-inline: auto is the standard way to make content centered and stay proportional.
Viewport units refer to the browser window's dimensions. 1vw equals 1 percent of the viewport width, and 1vh equals 1 percent of the viewport height:
.hero {
min-height: 60vh;
padding: 8vw 4vw;
}
.banner {
width: 100vw;
margin-left: calc(50% - 50vw);
}60vh keeps the hero always filling 60 percent of the screen height. Be careful with 100vw: in some browsers this width includes the scrollbar, so calc(100vw - 100%) is often used to prevent horizontal overflow.
.logo {
font-size: 8vmin;
}vmin takes the smaller of the viewport width and height, vmax the larger. Both are useful for elements that should stay proportional in portrait or landscape orientation.
clamp(min, preferred, max) sets a value that flows between two limits. clamp() works with any mix of units:
.judul {
font-size: clamp(1.5rem, 4vw, 3rem);
}
.container {
padding-inline: clamp(16px, 4vw, 48px);
}
.lebar {
width: clamp(280px, 60vw, 960px);
}Read it as: minimum 1.5rem, preferred 4vw, maximum 3rem. On small screens the text never drops below the minimum; on large screens it never exceeds the maximum. One clamp() line replaces a media query while keeping typography proportional.
h2 {
font-size: clamp(1.5rem, 2vw + 1rem, 2.5rem);
}clamp() also accepts calculations as the preferred value, like 2vw + 1rem. Combining these units produces a smooth fluid typography scale from phones to wide screens.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hero Fluid</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<section class="hero">
<h1>Selamat Datang di DevNull</h1>
<p>Deskripsi singkat yang tetap enak dibaca di semua layar.</p>
<a href="#" class="cta">Mulai Belajar</a>
</section>
</body>
</html>* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
}
.hero {
min-height: 100svh;
display: flex;
flex-direction: column;
justify-content: center;
padding-inline: clamp(16px, 6vw, 96px);
background-color: #0f172a;
color: white;
}
h1 {
font-size: clamp(2rem, 5vw, 4rem);
margin-bottom: 1rem;
}
p {
font-size: clamp(1rem, 1.5vw + 0.5rem, 1.25rem);
max-width: 60ch;
}
.cta {
display: inline-block;
margin-top: 2rem;
padding: 0.75em 1.75em;
border-radius: 0.5em;
background-color: #2563eb;
color: white;
text-decoration: none;
}Run npx serve . and drag the window width. The title and padding adapt continuously, with no media queries at all. Notice 100svh — small viewport height — which avoids dynamic scrollbar issues on mobile devices.
Pixels don't follow the user's font size. For typography and key spacing, use rem and em so the design respects accessibility preferences.
When there's a vertical scrollbar, 100vw can slightly exceed the content width. Use width: 100% inside a container or correct it with calc.
The clamp argument order is minimum, preferred, maximum. Flipping it makes the value invalid and ignored by the browser.
Key takeaways:
rem refers to the root font size; em refers to the element's font size.vw and vh follow the viewport dimensions; vmin and vmax pick the smaller or larger.clamp(min, preferred, max) creates fluid values without media queries.clamp() with rem and vw for proportional typography.object-fit — loading images suited to the screen size and controlling cropping within a frame.