A reszponzív webdesign közel húsz éven keresztül szinte kizárólag egyetlen alapelvre épült: a viewport méretére.
Ha kisebb lett a böngészőablak, megváltozott az elrendezés. Ha nagyobb lett, új elemek jelentek meg, több oszlop fért el, vagy módosultak a margók és térközök. A fejlesztők a media query-k segítségével reagáltak a képernyő méretére, és ez hosszú időn keresztül kiválóan működött.
A módszernek azonban mindig volt egy alapvető problémája: a komponensek valójában nem a böngésző szélességétől függnek.
Egy komponens számára nem az a lényeges kérdés, hogy a monitor 1920 vagy 2560 pixel széles-e. Sokkal fontosabb, hogy az adott komponens mennyi helyet kapott az aktuális elrendezésen belül.
Egy kártyaelem például egy széles monitoron is megjelenhet egy keskeny oldalsávban, miközben ugyanaz a komponens egy tableten akár a teljes képernyő szélességét elfoglalhatja.
A hagyományos media query-k erre nem tudnak megfelelő választ adni. A Container Query-k viszont pontosan erre a problémára születtek.
Mi volt a probléma a media query-kkel?
Vegyünk egy egyszerű példát:
.card {
padding: 1rem;
}
@media (min-width: 768px) {
.card {
display: flex;
}
}
Első ránézésre minden rendben van.
A kártya egy bizonyos képernyőméret felett vízszintes elrendezésre vált.
De mi történik akkor, ha ugyanaz a komponens egy keskeny dashboard widgetben jelenik meg? Vagy egy oldalsávban? Vagy egy modális ablakban?
A viewport lehet hatalmas, miközben maga a komponens csak 300 pixelnyi helyet kap.
A media query ezt nem látja.
A Container Query viszont igen.
A Container Query alapelve
A Container Query nem a böngésző méretét figyeli.
Ehelyett egy kijelölt konténer méretére reagál.
Első lépésként létre kell hoznunk egy konténert:
.card-grid {
container-type: inline-size;
}
Ezután a benne található elemek már vizsgálhatják a konténer szélességét:
@container (min-width: 600px) {
.card {
display: flex;
}
}
A böngésző ilyenkor nem azt kérdezi:
„Mekkora az ablak?”
Hanem azt:
„Mekkora hely áll rendelkezésre ennél a komponensnél?”
A konténertípusok megértése
inline-size
.component {
container-type: inline-size;
}
Ez a leggyakrabban használt megoldás.
A konténer szélességét figyeli, ezért a legtöbb esetben ez lesz a megfelelő választás.
Ha bizonytalan vagy, szinte mindig ezt érdemes használni.
size
.component {
container-type: size;
}
Ez a szélességet és a magasságot is figyelembe veszi.
Nagyobb rugalmasságot biztosít, ugyanakkor bonyolultabb layout-számításokat eredményez. Általában csak speciális esetekben indokolt használni.
Névvel ellátott konténerek
.dashboard {
container-type: inline-size;
container-name: dashboard;
}
Később célzottan erre a konténerre hivatkozhatunk:
@container dashboard (min-width: 900px) {
.widget {
display: grid;
}
}
Ez különösen összetett alkalmazásoknál hasznos.
A komponensalapú gondolkodásmód
A Container Query-k nem csupán új szintaxist jelentenek.
Egy teljesen más tervezési filozófiát vezetnek be.
A hagyományos megközelítés így szólt:
„Mit csináljon az oldal 768 pixel alatt?”
A modern megközelítés inkább ezt kérdezi:
„Mikor kezd rosszul kinézni ez a komponens?”
Ez elsőre apró különbségnek tűnik, de alapjaiban változtatja meg a reszponzív tervezést.
Minden komponens saját töréspontokat kap.
Minden komponens önállóan dönt a viselkedéséről.
Minden komponens hordozhatóvá válik.
Példa egy valóban önálló komponensre
.card-wrapper {
container-type: inline-size;
}
.card {
display: block;
}
@container (min-width: 500px) {
.card {
display: flex;
gap: 1rem;
}
}
@container (min-width: 800px) {
.card {
gap: 2rem;
}
}
Figyeljük meg, hogy itt egyetlen media query sincs.
A komponens kizárólag a rendelkezésére álló hely alapján dönt.
Ezáltal ugyanaz a kód tökéletesen működik oldalsávban, fő tartalomterületen vagy dashboard widgetként is.
Hogyan válasszuk ki a töréspontokat?
A Container Query-k egyik legnagyobb előnye, hogy megszabadítanak az önkényes töréspontoktól.
A klasszikus frontend fejlesztésben gyakran találkozunk ilyen értékekkel:
480px
768px
1024px
1440px
Ezek történelmi okokból alakultak ki, és gyakran nincs közük magához a komponenshez.
Container Query használatakor célszerű inkább ezt a folyamatot követni:
- Készítsd el a komponenst.
- Folyamatosan szűkítsd a rendelkezésre álló helyet.
- Figyeld meg, mikor kezd szétesni.
- Ott hozz létre egy töréspontot.
- Ismételd meg a folyamatot.
Így a töréspontok a komponens valós igényeiből születnek.
Container Query-k és Design Systemek
A Design Systemek világában a Container Query-k különösen nagy jelentőséggel bírnak.
Korábban gyakran kellett dokumentálni:
„Ez a komponens csak legalább 768 pixel széles területen használható.”
A Container Query-k ezt a problémát jelentősen csökkentik.
A komponens maga dönti el, hogyan jelenjen meg.
Nem a környező oldal, hanem a saját rendelkezésére álló tér alapján alkalmazkodik.
Ez jelentősen javítja az újrafelhasználhatóságot.
Container Query-k és CSS változók
A modern CSS egyik legerősebb kombinációja a Container Query-k és a Custom Property-k együttes használata.
.card-wrapper {
container-type: inline-size;
}
.card {
--card-padding: 1rem;
padding: var(--card-padding);
}
@container (min-width: 700px) {
.card {
--card-padding: 2rem;
}
}
Ilyenkor nem magukat a tulajdonságokat módosítjuk, hanem a komponens belső design tokenjeit.
Nagy rendszereknél ez rendkívül jól skálázható megoldást jelent.
Teljesítmény és gyakorlati tanácsok
Sokan aggódtak amiatt, hogy a Container Query-k jelentős teljesítményveszteséget okoznak majd.
A modern böngészőmotorok azonban kifejezetten erre a feladatra lettek optimalizálva.
Ettől függetlenül érdemes néhány szabályt betartani:
- Csak ott hozz létre konténert, ahol valóban szükséges.
- Lehetőleg
inline-sizetípust használj. - Kerüld a túlzottan mély konténerhierarchiákat.
- A reszponzív logikát tartsd a komponens közelében.
- Összetett rendszereknél használj elnevezett konténereket.
Ezekkel a szabályokkal a rendszer hosszú távon is könnyen karbantartható marad.
Átállási stratégia meglévő projektek esetén
Fontos hangsúlyozni, hogy a Container Query-k nem követelik meg a teljes projekt újraírását.
A legjobb stratégia általában fokozatos bevezetés.
- A meglévő media query-k maradhatnak.
- Az új komponensek már Container Query-ket használjanak.
- A problémás régi komponenseket fokozatosan cseréljük.
- A töréspontokat költöztessük közelebb a komponensekhez.
- Hagyjuk, hogy a rendszer természetes módon fejlődjön.
Ez a megközelítés minimális kockázat mellett biztosítja az előnyöket.