This episode covers advanced responsive techniques: adaptive layouts with container queries using the @tailwindcss/container-queries plugin, fluid typography with clamp(), and layout composition driven by state and container size.

Viewport-based media queries have a limitation: a card in the sidebar and the same card in the main content can't respond to their own size. Container queries solve this — styling reacts to the parent's size, not the screen size. Episode 16 covers container queries, fluid typography, and modern layout composition.
These techniques become important when a component is reused in very different contexts. One ProductCard component can look great in a 3-column grid and in a narrow sidebar, without writing a second component.
Install the official plugin:
npm install -D @tailwindcss/container-queriesRegister it in the config, then mark an element as a container:
module.exports = {
plugins: [require("@tailwindcss/container-queries")],
};<div class="@container">
<div class="grid grid-cols-1 @md:grid-cols-2">
<div>Kartu 1</div>
<div>Kartu 2</div>
</div>
</div>@md:grid-cols-2 activates when the container is at least 28rem — not when a particular viewport hits. That means the same card automatically adapts whether it sits in a sidebar or in full content.
A container follows the nearest size up the tree. For precise control, name your containers:
<div class="@container/layout">
<aside class="@container/sidebar">
<div class="@sm:flex-col @lg:flex-row">Konten adaptif</div>
</aside>
</div>Named containers ensure a child responds to the right container — this @container/layout pattern matters when containers are nested.
Text that "flows" with the viewport is made with clamp():
<h1 class="text-[clamp(1.5rem,4vw,3rem)] font-bold">
Judul yang membesar mengikuti lebar layar
</h1>clamp(1.5rem, 4vw, 3rem) means: minimum 1.5rem, preferred 4vw, maximum 3rem. On small screens the text won't shrink below the floor; on large screens it won't grow past the ceiling — without a single media query.
For breakpoint combinations, fluid typography often pairs with Tailwind's scale:
<h1 class="text-3xl text-[clamp(1.875rem,4vw,3rem)]">
Judul halaman
</h1>text-3xl is a static fallback, then the text-[clamp(...)] class refines it in supporting browsers. The fallback keeps text readable on older browsers.
Modern layouts often combine multiple sources of truth: container size, viewport, and interaction state. An example component that responds to all three:
<article
class="group @container p-4
@lg:grid @lg:grid-cols-[160px_1fr]
gap-4"
>
<img
class="aspect-square w-full rounded-lg
group-hover:scale-105 transition"
src="foto.jpg"
alt="Contoh"
/>
<div class="mt-4 @lg:mt-0">
<h2 class="text-xl font-semibold">Judul</h2>
<p class="text-sm text-gray-600">Deskripsi singkat.</p>
</div>
</article>The two-column grid appears when the container is wide; the image scales up slightly when the card is hovered. This combination of @container, group-hover, and transition shows the power of state-driven composition — every variant works without JavaScript.
Tip
Container queries and media queries don't cancel each other out. Media queries answer "how big is the screen?", container queries answer "how big is the container?". Use both in their roles: page layout with media queries, reusable components with container queries.
Episode 16 expanded your responsive toolkit: container queries with the @tailwindcss/container-queries plugin, fluid typography using clamp(), and layout composition driven by a combination of container, state, and breakpoints.
Key takeaways:
@md: prefix activates based on container size, not viewport.clamp(min, preferred, max) makes text flow without media queries.@container, group-hover, and transition for state-driven layouts.Next, in episode 17, we'll cover accessibility & internationalization — focus rings and contrast, reduced motion support, and handling RTL and layout localization with Tailwind.