Egyedi CSS vagy Utility class?
Mikor milyen módszerrel érdemes egy komponenst megvalósítani?
2021.11.26 — Posted by Webb & Flow
Törekedni kell arra, hogy az elkészült HTML kód a lehető legrövidebb legyen, azonban emellett arra is figyelni kell, hogy a weblap kiszolgálása során az összes letöltendő kód (HTML + CSS + JS) se legyen túl hosszú.
A következő példában felépítünk egy doboz komponenst, amiben van egy kép, alatta egy title, egy description, az alatt pedig egy link.
A komponensek fejlesztése során két irányba indulhatunk:
Egyedi CSS kód
Ebben az esetben a komponenshez minden szükséges CSS kódot egyedileg írunk meg, a HTML kódban csak annyi kódot írunk, hogy egyértelműen beazonosítható legyen, hogy melyik elem micsoda.
HTML kód
<div class="my-custom-box-with-image">
<img src="...">
<div class="title">
Ez a title
</div>
<div class="description">
Ez a description
</div>
<a href="...">
Tovább
</a>
</div>
Látszik, hogy maga a HTML kód viszonylag rövid, mert csak egy-egy class-al beazonosítom a különböző elemeket a komponensemen belül. Emiatt viszont a CSS kódomat úgy kell megírnom, hogy az összes, ahhaz a konkrét komponenshez tartozó kód egy logikai egységet alkot. A CSS szelektorok szintaktikája miatt pedig ez egy elég hosszú CSS kódot eredményezhet:
.my-custom-box-with-image {
border: 1px solid blue;
padding: 1rem;
}
.my-custom-box-with-image img {
width: 100%;
}
.my-custom-box-with-image .title {
font-size: 1.5rem;
margin-top: 1rem;
margin-bottom: 1rem;
}
.my-custom-box-with-image .description {
font-size: 0.75rem;
}
.my-custom-box-with-image a {
color: green;
}
Reszponzivitás
Amennyiben reszponzív a komponens, például mobilon kisebbnek kell lennie a title-nek, akkor a klasszikus módon (opcionálisan a mobile first elveket betartva) megírhatjuk a különböző képernyő méretekre vonatkozó eltéréseket.
Ehhez kizárólag a CSS kódon kell változtatni:
/* alap esetben minden méreten 1rem legyen a betűméret */
.my-custom-box-with-image .title {
font-size: 1rem;
margin-top: 1rem;
margin-bottom: 1rem;
}
@media (min-width: 992px) {
/* 992px-től felfele 1.5rem legyen a betűméret */
.my-custom-box-with-image .title {
font-size: 1.5rem;
}
}
Előnyök
- ha az adott komponens sok helyen van használva, és előre tudjuk, hogy gyakran kell majd a komponens kinézetén változtatni, akkor ez jobban támogatja a fejlesztést, mert elég csak a CSS fájlt módosítani, és a HTML kód módosítása nélkül azonnal az egész oldalon megjelenik a módosított design
- mivel viszonylag nehéz ebből a komponensből kiindulva egy új, hasonló komponenst csinálni, így nehezebben alakulnak ki komponens mutációk, illetve azonos célú, nagyon hasonló kinézetű komponensek
- nem kell a HTML kódot módosítani, ha módosítani akarunk a reszponzív viselkedésen
Hátrányok
- ha egy hasonló komponenst kell csinálni, amit ebből a komponensből kiindulva szeretnénk fejleszteni, akkor először az összes CSS kódot duplikálni kell, átírni a selector-okat, és elvégezni a módosításokat
- mindenképpen kell tudni CSS-t is fejleszteni, ha el akarunk kezdeni kísérletezni az adott komponens módosításával
- könnyen előfordulhat, hogy több különböző komponensben, ahol például a title kinézhetne ugyanúgy, mindegyik külön-külön title-t definiál, különböző kinézettel
- tudni kell CSS kódot módosítani, ha módosítani akarunk a reszponzív viselkedésen
Utility class
Ebben az esetben a CSS kódban nem az egész komponenst fejlesztjük le, csak az egyes építő kockákat. Az építő kockákhoz tartozó CSS class-okat utility class-nak hívjuk, mert tipikusan nem magához az elemhez, hanem annak egy tulajdonságához írjuk meg.
HTML kód
<div class="padding-1 border-blue">
<img src="..." class="width-100">
<div class="font-size-1-5 margin-top-1 margin-bottom-1">
Ez a title
</div>
<div class="font-size-0-75">
Ez a description
</div>
<a href="..." class="text-green">
Tovább
</a>
</div>
és az ehhez tartozó CSS kód
.padding-1 {
padding: 1rem;
}
.border-blue {
border: 1px solid blue;
}
.width-100 {
width: 100%;
}
.font-size-1-5 {
font-size: 1.5rem;
}
.font-size-0-75 {
font-size: 0.75rem;
}
.margin-top-1 {
margin-top: 1rem;
}
.margin-bottom-1 {
margin-bottom: 1rem;
}
.text-green {
color: green;
}
Amennyiben Bootstrap-et használunk, az már eleve ad több utility class-t is, amit fel lehet használni, így kevesebb saját CSS kódot kell megírni, és betölteni a weblap kiszolgálásakor.
HTML kód
<div class="p-3 border-blue">
<img src="..." class="img-fluid">
<div class="font-size-1-5 my-3">
Ez a title
</div>
<div class="font-size-0-75">
Ez a description
</div>
<a href="..." class="text-green">
Tovább
</a>
</div>
így már csak a következő egyedi CSS kódra van szükség
.border-blue {
border: 1px solid blue;
}
.font-size-1-5 {
font-size: 1.5rem;
}
.font-size-0-75 {
font-size: 0.75rem;
}
.text-green {
color: green;
}
Reszponzivitás
Amennyiben reszponzív a komponens, akkor a utility class-okat is érdemes reszponzívan megírni, és a HTML kódban a megfelelő class-okat beírni.
HTML kód
<div class="p-3 border-blue">
<img src="..." class="img-fluid">
<div class="font-size-1 font-size-lg-1-5 my-3">
Ez a title
</div>
<div class="font-size-0-75">
Ez a description
</div>
<a href="..." class="text-green">
Tovább
</a>
</div>
és a szükséges CSS kód
/* alap esetben minden méreten 1rem legyen a betűméret */
.font-size-1 {
font-size: 1rem;
}
@media (min-width: 992px) {
/* ha ez a class be van állítva a HTML kódban, akkor 992px-től 1.5rem legyen a betűméret */
.font-size-lg-1-5 {
font-size: 1.5rem;
}
}
Előnyök
- könnyen lehet új komponenst készíteni, ami belül már létező építőkockákat használ
- amennyiben az építőkockák halmazát nem kell bővíteni, tisztán HMTL kód módosítással is rengeteg játszóterünk van a komponens módosításához
- erősen támogatja a módszer, hogy kevés építőkocka alakuljon ki, így például a title különböző dobozokban ugyanúgy nézzen ki
- nem kell a CSS kódot módosítani, ha módosítani akarunk a reszponzív viselkedésen
Hátrányok
- ha weblap szinten módosítani kell a komponenst, akkor mindenhol módosítani kell a HTML kódot, ahol használva van, és amennyiben statikus weblapról van szó, újra kell az összes érintett oldalt generálni
- ezt a ConyCMS leegyszerűsítni a HTML Sablonok és Item Sablonok, illetve Script-et használatával
- nagyon könnyen kialakulhat a már meglévő építőkockákból egy új olyan komponens, amihez nagyon hasonló már készült korábban, ezért több odafigyelést igényel a tervezés során, hogy elkerüljük a felesleges mutációk bevezetését
- tudni kell HTML kódot módosítani, ha módosítani akarunk a reszponzív viselkedésen, és ehhez kell, hogy előre ki legyenek alakítva a reszponzív utility class-ok a CSS kódban
Mikor melyik módszert használjam?
Nem lehet egyértelműen azt mondani, hogy vagy az egyik, vagy a másik módszer a jó, minden esetben az adott weblap, vagy akár az adott komponens felhasználási igényeit mérlegelve kell dönteni, hogy melyik a jó megoldás.
Gyakori, hogy vegyesen készülnek wenlapok, azaz vannak olyan komponensek, amik egyedileg le vannak fejlesztve, és vannak olyanok, amik csak utility class-okkat vannak megvalósítva.
Az építőkockák önmagukban is lehetnek összetett komponensek, amik szintén elkészülhettek akár az egyik, akár a másik módszerrel, így akár egy komponensen belül is előfordulhat, hogy vegyesen van a két módszer alkalmazva.
Olyan eset is előfordulhat, hogy elkészül egy komponens egyedi CSS kóddal, és utána utility class-okkal kiegészítve a HTML kódját készítünk egy mutációt.
A Bootstrap vegyesen alkalmazza a két módszert, definiál rengeteg kész, azonnal felhasználható komponenst, amiknél bizonyos mutációkat a kifejezetten az adott komponenshez megírt utility class-okkal érhetünk el (például egy alert doboz színe), plusz kiegészíthetjük az univerzális utility class-okkal is (például egy p-* class, ha nagyobb belső térközt szeretnénk),
Ökölszabályként a következő szempontok szerint dönthetünk:
- Egyedi CSS kód a jobb, ha
- sok, azonos template-ű oldalon van felhasználva ugyanaz a komponens, és várhatóan gyakori lesz az utólagos módosítás (nem az átadás-átvétel alatt, hanem már az éles weblapon)
- teljesen egyedi építőkockákból állnak a komponensek, tehát nincs rá esély, hogy az egyik komponensben használt egyik elemet fel lehet egy másik komponensben használni
- nem számít, ha több kódot kell betöltenie a böngészőnek (főleg egyszerűbb weblapok esetén, ahol nincs sok komponens)
- ha tudjuk, hogy a reszponzív viselkedést majd később, már az éles weblapon kell kikísérletezni
- Utility class a jobb, ha
- sikerül a komponens standardizálást odáig elvinni, hogy az építőelemeket is tudjuk standardizálni, és azokat több különböző komponensben is felhasználni
- ha számít, hogy mennyi kódot kell betölteni a weblap kiszolgáláskor