CSS Container Queries: Masa Depan Desain Responsif (2026)

Developer 30 Mei 2026 · OTPZap Team

Bertahun-tahun developer wishlist "responsive berdasarkan parent container, bukan viewport". Tahun 2026, akhirnya: container queries stable di semua major browser. Tapi banyak developer masih default ke media query untuk semua, padahal container query lebih cocok untuk many situations.

Artikel ini bahas container queries dari basic sampai advanced pattern, plus kapan pakai yang mana antara container query vs media query.

Masalah Yang Container Query Solve

Selama ini, responsive design pakai media query yang base on viewport size. Problem: component reusable yang dipake di multiple location, ukurannya beda-beda walau viewport sama.

Contoh: card component dipake di:

Media query ngga help karena viewport sama untuk ketiga case. Solusi sebelum container query: pakai prop atau JavaScript untuk handle ini, ngga clean.

Container query: card adapts berdasarkan ukuran parent-nya, bukan viewport. Layout yang berbeda untuk setiap konteks, dari CSS murni.

Syntax Basic

Setup container:

.parent {
  container-type: inline-size;
  /* atau "size" untuk both width + height */
  container-name: card-container; /* optional, untuk multiple container */
}

Style berdasarkan size container:

@container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 1rem;
  }
}

@container (min-width: 700px) {
  .card {
    grid-template-columns: 200px 1fr 200px;
  }
}

/* Dengan named container */
@container card-container (min-width: 400px) {
  .card { padding: 2rem; }
}

Card yang sama, di parent berbeda, render layout berbeda. Tanpa JavaScript.

Pattern Praktis

1. Card Component Adaptive

<div class="card-wrap">
  <article class="card">
    <img src="..." alt="...">
    <div class="content">
      <h3>Title</h3>
      <p>Description...</p>
    </div>
  </article>
</div>
.card-wrap {
  container-type: inline-size;
}

.card {
  display: grid;
}

/* Compact: stacked vertically */
.card .content { padding: 1rem; }

/* Wide: horizontal layout */
@container (min-width: 400px) {
  .card {
    grid-template-columns: 200px 1fr;
  }
}

@container (min-width: 700px) {
  .card {
    grid-template-columns: 300px 1fr;
  }
  .card .content { padding: 2rem; font-size: 1.1rem; }
}

2. Sidebar Widget

Widget yang adapt: kalau sidebar tetap, layout vertical. Kalau sidebar collapse jadi top bar, layout horizontal.

aside {
  container-type: inline-size;
}

.widget {
  display: flex;
  flex-direction: column;
}

@container (min-width: 600px) {
  .widget {
    flex-direction: row;
    justify-content: space-between;
  }
}

3. Form Field Layout

Form yang otomatis adjust label position berdasarkan available width:

.form {
  container-type: inline-size;
}

.field {
  display: grid;
  gap: 0.5rem;
}

@container (min-width: 500px) {
  .field {
    grid-template-columns: 200px 1fr;
    align-items: center;
  }
}

Form di modal sempit: label di atas. Form di halaman lebar: label di samping.

4. Navigation Menu

nav {
  container-type: inline-size;
}

.menu {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

@container (min-width: 600px) {
  .menu {
    flex-direction: row;
    gap: 2rem;
  }
}

@container (max-width: 599px) {
  .menu-toggle {
    display: block; /* Show hamburger */
  }
  .menu {
    display: none;
  }
  .menu.open {
    display: flex;
  }
}

Container Query Units

Selain container query, container query juga kasih units baru:

Use case: text yang scale based on container, bukan viewport:

.parent {
  container-type: inline-size;
}

.title {
  font-size: clamp(1.5rem, 5cqw, 3rem);
  /* Scale berdasarkan container width, dengan min/max */
}

Title 5% lebar container, dengan minimum 1.5rem dan maximum 3rem.

Container Query vs Media Query: Kapan Pakai Yang Mana

Pakai Media Query Untuk:

Pakai Container Query Untuk:

Performance Considerations

1. Browser Cost

Container queries trigger layout recalculation saat container size berubah. Untuk most case, cost minimal. Tapi excessive container query di nested level deep bisa impact performance.

Best practice: limit container hierarchy ke 2-3 level. Setiap component butuh container biasanya cuma 1 level.

2. Layout Containment

container-type: inline-size implicitly apply contain: layout style inline-size. Element jadi containing block. Ada side effect:

Most case ini desirable, tapi kalau lo punya komponen yang relies on positioning ke ancestor lain, test carefully.

Browser Support 2026

Coverage 95%+ di 2026. Untuk older browser, fallback ke media query atau JavaScript.

Pitfalls Common

1. Lupa Set container-type

Most common mistake. Lo write @container rule tapi lupa set parent jadi container. Rule ngga apply.

/* Salah - parent ngga jadi container */
@container (min-width: 400px) {
  .card { ... }
}

/* Benar */
.parent {
  container-type: inline-size; /* WAJIB */
}
@container (min-width: 400px) {
  .card { ... }
}

2. Apply ke Self Element

Container query ngga bisa style element yang itself container. Element jadi container, lo style descendantnya.

/* Salah - .self adalah container, di-apply ke dirinya */
.self {
  container-type: inline-size;
}
@container (min-width: 400px) {
  .self { padding: 2rem; } /* NGGA WORK */
}

/* Benar - container styling diluar @container, descendant didalam */
.self {
  container-type: inline-size;
  padding: 1rem;
}
@container (min-width: 400px) {
  .self > .child { padding: 2rem; } /* WORK */
}

3. Width 0 Issue

Element dengan display: contents atau ngga ada width meaningful, container ngga work as expected. Container butuh width yang resolvable.

4. Naming Collision

Multiple ancestor jadi container, query bisa match ancestor yang ngga lo expect. Pakai container-name untuk specificity.

Penutup

Container queries akhirnya solve masalah long-standing di responsive design: component yang adapt ke konteks, bukan ke viewport. Browser support sekarang stable, syntax mature, performance acceptable.

Di 2026, kalau lo build component-based design system, container queries should be default tool. Pakai media query untuk page-level layout, container query untuk component-level adaptation.

Yang ngga perlu: rewrite seluruh stylesheet existing untuk pakai container query. Apply gradual untuk component baru atau component yang current pattern-nya awkward dengan media query.

Plus: explore container query units (cqw, cqh, dll). Mereka unlock pattern fluid typography dan spacing yang sebelumnya butuh JavaScript ResizeObserver.