OOCSS je zkratka pro Object Oriented CSS. Je to koncept psaní kódu od Nicole Sullivan zaměřený na „komponentovou“ část CSS kódu.
Související
CSS objekt je opakující se vizuální komponenta, která může být abstrahována kouskem HTML a CSS, případně JS. Je znovupoužitelná na jiném místě projektu. Ideálně pak i na dalších projektech.
Cílem OOCSS je kromě zajištění znovupoužitelnosti kódu i zlepšení jeho spravovatelnost a také zmenšení objemu CSS souboru.
Myslím, že uplatnění objektových principů na psaní CSS je jistým způsobem nutnost. Alespoň u webů, psaní javascriptových aplikací totiž může být z pohledu organizace CSS úplně jiná písnička.
Ukažme si nejprve zjednodušený kód komponenty s tlačítkem:
/* Komponenta */
.button { … }
/* Elementy komponenty */
.button-icon { … }
/* Modifikátory komponenty */
.button-primary { … }
.button-login { … }
OOCSS má pět principů. Alespoň podle toho, jak jej vnímám já:
1) Nezávislost vzhledu na struktuře
Do CSS selektorů nikdy nedáváme HTML tagy. Mohou se totiž změnit a změny nechceme provádět na dvou místech – v HTML i CSS. Proto .button
raději než input.button
.
OOCSS je v tomto přísné, takže byste v komponentové části kódu opravdu neměli mít některé z uvedených typů selektorů:
/* Tohle je v objektovém CSS zakázáno: */
button { … }
input.button { … }
.comment img { … }
Selektor jako .comment img
může vypadat neškodně. Jenže co když třeba do komponenty váš kolega, kolegyně nebo třeba klient přes redakční systém přidá do struktury komponenty další obrázek?
Jediná rozumná výjimka je stylování základní typografické vrstvy projektu. Tam jsou samozřejmě selektory jako p
nebo h1
úplně v pořádku. V této vrstvě kódu ani OOCSS nevyužijete, objekty jsou určené pro vrstvu komponent uživatelského rozhraní.
2) Nezávislost obsahu na kontejneru
Do CSS selektorů nikdy nepromítáme strukturu HTML nebo přesněji stromu DOM. I ta se totiž může změnit:
/* Špatně: */
.login-form .button { … }
/* Dobře: */
.button { … }
.button-login { … }
Komponenta .button
s modifikátorem .button-login
je totiž snadněji přenositelná do jiné struktury HTML než komponenta v kontejneru (.login-form .button
). U komponenty v kontejneru opět platí, že úpravu struktury HTML budete muset promítat do CSS.
3) Co nejnižší specifičnost
V CSS nikdy nepoužíváme selektory identifikátorů (#id
), protože mají vysokou specifičnost. Atributy id=""
v HTML ale samozřejmě smysl mají – například pro kotvy uvnitř dokumentu nebo použití v javascriptových selektorech.
Klazule !important
je víceméně také zapovězená. Tu si necháváme pro debugovací nebo prostě vysoce specifické účely.
Kvůli zachování nízké specifičnosti se také snažíme co nejméně používat následující:
- selektorů potomka
.button .button-icon › .button-icon
- kombinované selektory
.button.button-primary › .button-primary
Více o specifičnosti v CSS:
4) Vývoj zaměřený na komponenty, znovupoužitelnost
Komponenty (neboli objekty) nezávislé na struktuře HTML lze snadno používat i na jiných projektech.
Tvoří pak samostatný celek, který importujeme:
@import "button.css";
@import "nav.css";
Zpřehledňují nám nejen kód samotný, ale i commity do repozitáře. O organizaci CSS do souborů jsem kdysi psal samostatný článek.
Na protokolu HTTP/1 bude obvykle výhodnější importované CSS opět slučovat. Mohou pomoci preprocesory nebo PostCSS. Na HTTP/2 potřeba slučování souborů do jednoho už tak moc neplatí.
5) Princip prefixování: objekt, element, modifikátor
Máme tři typy prvků:
- objekt – jinak též komponenta nebo blok (
.button
) - element – prvek uvnitř objektu, jinak též podobjekt (
.button-icon
pro ikonu uvnitř tlačítka) - modifikátor – vlastnost objektu (
.button-primary
pro hlavní call-to-action tlačítko)
Pro někoho už tohle patří do metodiky BEM. Já si ji ale vykládám jako pravidla pro způsob zápisu tříd.
Tím jsme ukončili procházku po pěti principech OOCSS. Teď ještě musím odbočit ke spolupráci kodérů s vývojáři. Někdy totiž není přísné uplnatnění principů OOCSS možné už z principu. Z principu designu.
OOCSS v praxi
Ukážu čtyři možnosti, jak v CSS napsat kód pro přihlašovací tlačítko. Jen ta poslední je v pořádku. Předpokládejme, že jde o komponentu, která nějak výchází ze základního tlačítka. To v CSS vypadá následovně:
.button {
text-align: center;
padding: .5em 1em;
}
Další předpoklad je, že přihlašovací tlačítko používat na různých místech projektu. Pak chci využít objektové CSS.
Špatně: závislý na kontejneru
V HTML by vypadalo takto:
<form class="login-form">
<button class="button"></button>
</form>
V CSS se mi pak, jak už jsem psal, vytváří závislot na konkrétním kontejneru a tato varianta tlačítka je tedy nepřenositelná. Proto je nesprávná.
.login-form .button { … }
Špatně: bez prefixování
HTML:
<button class="button login"></button>
Vymanili jsme se tedy ze závislosti na kontejneru. Prima. Jenže… Člověku, který HTML čte, nebude jasné, co vlastně login
znamená.
Je to nový objekt? Je to modifikátor původního objektu button
? Je to nějaká globální helper třída? Pak je obtížné z HTML vyvodit, jak komponentu používat nebo ve kterém souboru najít kód komponenty.
Špatně: přesun zátěže do CSS
HTML:
<button class="button-login"></button>
V CSS pak kromě původního .button
budu mít ještě kód pro přihlašovací verzi tlačítka:
.button-login {
text-align: center;
padding: .5em 1em;
background: blue;
color: white;
}
Jak vidíte, je to prakticky totožný kód, který jen přidává dvě nové vlastnosti. Problém je v tom, že vám CSS kód neúměrně a zbytečně bobtná.
Správně: pomocí modifikátoru
HTML:
<button class="button button-login"></button>
Z uvedeného kódu díky prefixování snadno poznáme, že jde o komponentu button
s modifikací. V CSS u modifikace jen přidáme kód, který nemá původní objekt:
.button-login {
background: blue;
color: white;
}
Objektový kód v neobjektovém designu
Netrvejte na komponentovém přístupu, pokud není design komponentově zaměřený.
CSS je zápis designu. CSS kodér, který používá objektový zápis dělá v designu systém. Jenže ne každý design je vymyšlený systematicky. Dnešní podklady designérů jen vzácně tvoří striktní systém typu atomického designu. Většinou se pohybují v rozmezí mezi částečně komponentovým přístupem a naprosto nekomponentovým, kdy každé tlačítko vypadá trochu jinak.
Milí kodéři, nesnažte se proto aplikovat přísné objektové přístupy tam, kde to není z principu možné. Obvykle ale můžete naštěstí alespoň základy principů OOCSS využít i tam, kde designéři na znovupoužitelnost designu nemysleli. Široce použitelné jsou hlavně principy nezávislosti vzhledu na struktuře, obsahu na kontejneru a zachování nízké specifičnosti.
Komentáře
Máte doplnění, komentář nebo jste našli chybu?
Pro přidání názoru se prosím
přihlaste nebo si zřiďte účet.