Smysluplné CSS: stylujte, jak se má

15. srpna 2016

V současné době máme svět smysluplného značkování přímo před sebou, stačí po něm sáhnout. HTML5 zavedl novou přepychovou sadu sémanticky smysluplných elementů a atributů, ARIA definovala celou dodatečnou platformu, jak popisovat bohatě vybavený internet, a na scéně se objevily mikroformáty, aby poskytly ještě standardizovanější pojmy, s ještě jemnějšími nuancemi než dřív. Je to zlatý věk pro bohatě vybavené smysluplné značkování.

Přesto značkování pořád až příliš často zůstává spletí divů, a CSS jsou neproniknutelná bažina tříd, které mají s těmi divy jen málo společného. Noříme div dovnitř jiného div dovnitř dalšího div, a každému elementu div přidělíme zásobník tříd — když se ale na takové CSS podíváme, skýtají třídy jen nepatrný vhled, co vlastně se snažíme definovat. A i když budeme mít značkování sémantické a smysluplné, skončíme s tím, že je redefinujeme s třídami CSS, které jsou ze své podstaty libovolné. Nemají žádný skutečný význam.

Před těmito vzory jsme byli varováni už dávno:

Web stižený classitidou charakterizuje typická vyrážka. Každá setsakramentská značka má zduřený bolák, vlastní třídu. Classitida jsou osypky značkování, zatemňují význam, protože každou stránku zbytečně zatěžují.

Jeffrey Zeldman, Navrhování s webovými standardy (Designing with Web Standards), 1. vydání.

V podobném duchu přidala svůj názor i W3C poznámkou:

CSS dávají atributu “class” takovou moc, že je možné si představit, že autoři budou navrhovat svůj vlastní “dokumentový jazyk” založený na elementech, s nimiž není sdružena téměř žádná prezentace (jako jsou DIV a SPAN v HTML), a jimž se přiřazuje informace o stylu prostřednictvím atributu “class”… Varujeme autory před tímto postupem, protože strukturální elementy dokumentového jazyka často mívají uznávané a schválené významy, zatímco autorsky definované třídy možná ne. (zvýraznění je mé)

Proč vlastně se v CSS tak nemilosrdně zneužívají třídy, a proč pořád zasypáváme značkování autorsky definovanými třídami? Proč nemohou být CSS stejně sémantické a smysluplné jako značkování? Proč by nemohlo být obojí ještě sémantičtější a smysluplnější, a postupovat kupředu ruku v ruce?

Budujme lepší objekty

Dávno již tomu, co jsme překonali ranou fázi CSS, začali budovat stále rozsáhlejší weby a systémy, a usilovali vyvinout nějaké zdravé konvence, abychom zvládali stále víc nabobtnávající soubory kaskádových stylových předpisů. A najednou, kde se vzalo, tu se vzalo, přišly objektově orientované CSS.

Naše systémy pro bezpečně budované složité, znovu využitelné komponenty vytvořily problém metastazované classitidy — a to až do té míry, že současné značkování je až příliš často psané tak, že je slouhou CSS, místo aby to bylo právě naopak. Jestliže se pokoušíme psát sémantické, přístupné značkování, pořád jsme nuceni přilepovat autorsky definované významy, abychom uspokojovali nároky CSS. Obojí, značkování i CSS, odrážejí dobu, kdy jsme mohli definovat objekty pouze s tím, co jsme tehdy měli: divy a třídy. A když jsme byli na pochybách, přidali jsme další, nebo obojí. Bylo bezpečnější, zejména u starších prohlížečů, orientovat se na co nejobecnější objekty, jaké jsme uměli najít.

Dnes už můžeme takový přístup opustit. Můžeme definovat lepší objekty. Můžeme vytvářet sémantické, popisné a smysluplné CSS, které budou rozumět tomu, co popisují, a budou tak bohatě vybavené a přístupné, jako nejlepší moderní značkování. Umíme definovat slona, nemusíme říkat .sloup a .had.

Vyjasněme pár věcí

Než se však pustíme do definice lepších objektů, vraťme se k tomu, co jsme právě řekli a vyjasněme si, co je vlastně na současných objektech špatné. Trochu přitom vypomůže karikaturista Gary Larson.

Larson jednou nakreslil karikaturu s názvem Odvrácená strana (Far Side). Je na ní muž držící v jedné ruce kýbl s barvou, ve druhé štětku, a na vše, co kolem sebe vidí, píše, co to je. Přes vstupní dveře domku načmárá “Dveře”, na strom v zahrádce napíše “Strom”, a kočku jasně popíše slovem “Kočka”. Když má všechno označené, spokojeně řekne: “To by mělo pár věcí vyjasnit”.

Všichni jsme tím spokojeným mužem z Larsonovy karikatury, co má všechno tak pěkně popsané. Bez sebemenšího zaváhání píšeme <table class=“table“> a <form class=“form“>. Když se podíváte na Github, najdete spoustu příkladů <main class=“main“>. Ale proč? Nemůžete mít více než jeden element main, takže už přece víte, jak se na něj odkázat přímo. Nové elementy v HTML5 už jsou skoro deset let staré. Je neomluvitelné, že je nepoužíváme správně. Je neomluvitelné, že neočekáváme, že je kolegové vývojáři znají a chápou.

Proč znovu vynalézáme kolo, když zavádíme sémantické významy, které už jsou definované ve specifikaci našich vlastních tříd? Proč je duplikujeme nebo jimi kalíme vodu?

Konečný uživatel si možná nevšimne, když k elementu form přilepíte třídu form, nebo je mu to jedno, vám by to ale jedno být nemělo. Nemělo by vám být lhostejné, že značkování nabobtnává a uživatelovy prožitky se zpomalují. Měli byste dbát na čitelnost. A pokud jste placeni za zhotovování materiálů tohoto druhu, měli byste dbát na to, abyste se zařadili do skupiny profesionálů, kteří nepíší redundantní šlichtu. I předsmrtný chrapot zastánců layoutu založeného na tabulkách zněl: “co bych se staral”.

Začněme značkovat sémanticky

Prvním krokem k sémantickým, smysluplným CSS je začít se sémantickým, smysluplným značkováním. Třídy jsou libovolné, HTML ne. V HTML má každý element velmi specifický, smluvně dohodnutý význam, a stejně tak jeho atributy. Dobré značkování je už ze své podstaty expresivní, deskriptivní, sémantické a smysluplné.

Pokud by se stalo, že by sémantika HTML5 nestačila, je zde ARIA, konkrétně navržená tak, aby zaplňovala takové mezery. ARIA je až příliš často špatně chápána jako “aby k tomu měli přístup postižení ”, ve skutečnosti — ve shodě se svým názvem — je o přístupných bohatě vybavených internetových aplikacích (Accessible Rich Internet Applications). Což znamená, že je přeplněná rozšířenou sémantikou.

Uveďme příklad. Jestliže chcete definovat záhlaví, které bude na stránce nahoře, mohli byste si definovat vlastní třídu .page-header, která by ale nenesla žádný skutečný význam. Mohli byste použít element header, ale protože budete určitě mít víc elementů header, ne pouze jeden, patrně by to nefungovalo. Ve specifikaci ARIA však už máme [role=banner], což rozhodně vyjadřuje “Tohle je záhlaví nahoře na stránce”.

Jakmile máte <header role=“banner“>, přidávat třídu navíc je prostě redundantní a vnáší nepořádek. V CSS přesně víme, o čem mluvíme, zde není žádná možná dvojznačnost.

A nejde jen o ty obrovité vysokoúrovňové elementy sloužící jako význačné orientační body (role ladnmark). ARIA poskytuje způsob, jakým lze sémanticky označit také malé elementy na atomické úrovni, jako je role upozornění (alert).

Varování: neházejte role ARIA na elementy, které už mají stejnou sémantiku. Proto například nepište <button role=“button“>, protože sémantika už je přítomna v samotném elementu. Dělejte to jinak. Na elementech, které mají vypadat a chovat se jako tlačítka, uveďte [role=button] a patřičně je nastylujte:

button,
[role=button] {

}

Cokoliv značkujete tak, že sémanticky odpovídá tlačítku, dostane také stejné stylování. Když budete uplatňovat sémantické značkování, budou CSS jasně začleňovat elementy podle toho, co jste s nimi zamýšleli, ne na základě nějakého libovolného seskupování. Když budete uplatňovat sémantické značkování, zůstanou komponenty znovu využitelné. Dobré značkování se nemění z projektu na projekt.

Dobrá, ale proč?

Proto:

  • Jestliže už píšete sémantické, přístupné značkování, dramaticky redukujete přecpanost, a značkování je čistší, štíhlejší a odlehčené. Lidem se snadněji čte a bude se — ve většině případů — rychleji načítat a rychlejší bude i jeho rozbor. Odstraníte autorsky definovanou suť a zanecháte prohlížeči jen jemu známé elementy. Každý element je zde z nějakého důvodu a má nějaký význam.
  • Pokud naproti tomu nyní pořád ještě zápolíte s polévkou plnou divů a tříd, pak co do přístupnosti značně zabodujete, protože teď budete uplatňovat role a značkování, které napomáhá asistenčním technologiím. Kromě toho budete mít standardizované značkovací vzory, takže budou lépe znovu použitelné a konsistentnější.
  • Pro znovu využívané elementy důrazně doporučujeme konsistentní vizuální jazyk. Konsistentní vizuální jazyk je klíčem k úspěšné uživatelské zkušenosti, a potěšíte také designéry, když se vyvarujete situací se silnou negativní emocionální reakcí (tzv. uncanny valley), v nichž elementy vypadají nebo fungují téměř tak, jako něco důvěrně známého, ale ne úplně. U vás to bude jinak, pokud to vypadá jako kachna a kváká jako kachna, vy skutečně zajistíte, že to skutečně bude kachna, ne něco jako kralik.kachna.
  • Mezi CSS a HTML není žádné přepínání kontextu, protože co dělají, jasně popisují na základě jazyka založeného na standardech.
  • Budete mít konsistentnější značkovací vzory, protože správná cesta je mít vše jasné a jednoduché, když jsou věci obtížné, jste na špatné cestě.
  • Nebudete muset tolik přemýšlet o vhodných názvech. Nechte se vést specifikací.
  • Umožní vám odstřihnout se od CSS frameworku, který je zrovna in.

Tady máte jiný, zajímavější scénář. Typické značkování formuláře někdy vypadá takhle (nebo ještě hůř):

<form class="form" method="POST" action=".">
<div class="form-group">
<label for="id-name-field">What’s Your Name</label>
<input type="text" class="form-control text-input" name="name-field" id="id-name-field" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Enter" />
</div>
</form>

V CSS pak vidíte styly přiřazované všem těm třídám. Takže máme zásobník tříd popisujících, že tohle je formulář a v něm dvě vstupní pole. Pak přidáváme dvě třídy, jimiž sdělujeme, že tlačítko, které odesílá formulář, je tlačítko, a že reprezentuje primární akci, kterou je možno s tímto formulářem podniknout.

Běžné versus optimální formulářové značkování
Jak to děláme Jak bychom to měli dělat Proč
.form form Většina formulářů bude — nebo by přinejmenším měla — dodržovat konsistentní návrhové vzory. Pro ty ostatní uložte dodatečné identifikátory. Důvěřujte svým návrhovým vzorům.
.form-group form > p nebo fieldset > p W3C doporučuje pro zalamování formulářových elementů značku odstavec (paragraph). To je předvídatelný, doporučený vzor pro zalamování formulářových elementů.
.form-control nebo .text-input [type=text] Už víte, že se jedná o vstup textu.
.btn a .btn-primary nebo .text-input [type=submit] Odeslání formuláře je ze své podstaty primární akce.

 

Některé běžné versus optimální vzory značkování formuláře

Ve světle všech těchto poznatků zde máte nové, vylepšené značkování.

<form method="POST" action=".">
<p>
<label for="id-name-field">What’s Your Name</label>
<input type="text" name="name-field" id="id-name-field" />
</p>
<p>
<button type="submit">Enter</button>
</p>
</form>

Funkcionalita je přesně stejná.

Nebo se zamyslete nad tímto CSS. Měli byste být schopni přesně vidět, co popisuje, i co přesně dělá:

[role=tab] {
display: inline-block;
}
[role=tab][aria-selected=true] {
background: tomato;
}

[role=tabpanel] {
display: none;
}
[role=tabpanel][aria-expanded=true] {
display: block;
}

Poznamenejme, že stav [aria-hidden] je sémantičtější než utilitní třída .hide, a že by se zde také mohl použít, příhodnější se však jeví stav aria-expanded. Ani jeden ze stavů však nemusí být nutně svázaný s tabpanely.

V některých případech zjistíte, že momentální potřebě nevyhovuje ve specifikaci žádný element, ani atribut. A přesně kvůli tomuto problému byly navrženy mikroformáty a mikrodata, aby ho pomohly vyřešit, takže často budete moci zapojit do svých služeb je. Ještě jednou zopakuji, že zachováváte standardizované, sémantické značkování, a vaše CSS je reflektují.

Na první pohled se může zdát, že tohle selže přesně v tom scénáři, pro který byly budovány konvence pro pojmenovávání struktur CSS a pro který se měly nejlépe hodit: rozsáhlé projekty, velké týmy. Nutně to ale tak být nemusí. Vzory CSS pro pojmenovávání tříd kladou rigidní požadavky na značkování, jaké musí po nich následovat. Jinak řečeno, CSS diktují, jaký bude finální HTML. Významná odlišnost je v tom, že při technice smysluplných CSS stylování odráží značkování, ne naopak. Ani jedno není ze své podstaty lépe či hůře škálovatelné. Obě přicházejí s jistými očekáváními.

Jeden z možných protiargumentů by mohl být, že bude příliš obtížné zajistit, aby nejvhodnější značkovací vzory dobře pochopili všichni členové týmu. Na druhé straně, jestliže existuje nějaká základní úroveň vědomostí, jakou bychom měli očekávat od všech webových vývojářů, nepochybně do ní patří solidní znalosti samotného HTML uplatňované v praxi, ne učit se nazpaměť tajemná pravidla pro pojmenovávání tříd. Pokud nic jiného, tak vzory, které mají členové týmu dodržovat, budou jasné, už zřízené a dobře zdokumentované v samotné specifikaci, a opakovatelné. Dobré značkování a dobré CSS se vzájemně posilují.

Naznačovat, že nemůžeme psát dobré značkování a dobré CSS, protože někteří členové týmu nerozumí základním HTML strukturám a sémantice, je jen výmluva. Naše odvětví může — a mělo by — očekávat víc. Kdybychom o CSS layoutu říkali, že je pro nezkušené vývojáře příliš obtížné ho pochopit, budovali bychom dnes stále ještě weby v tabulkách. Je to trapný argument.

Patrně nejobtížnější částí smysluplných CSS je pochopit, kdy zůstávají třídy nápomocné a žádoucí. Cílem je používat třídy tak, jaký byl jejich původní záměr: pro libovolné seskupování elementů. Vlastní třídy budete nejčastěji vytvářet v jednom z těchto mála případů:

  • Když neexistují elementy, atributy neb standardizované datové struktury, které byste mohli použít. V některých případech se opravdu může jednat o objekt, s jakým ani specifikace HTML, ani ARIA, ani mikroformáty vůbec nepočítaly. Nemělo by se to stávat často, možné to ale je. Až ale budete definovat .jednorozec, ujistěte se, že nepřilepujete roh koni.
  • Když chcete libovolně seskupovat lišící se značkování do jednoho vizuálního stylu. V tomto případě si přejete, aby objekty, které nejsou stejné, vypadaly takové, jaké jsou. Ve většině případů budou patrně sémanticky stejné, máte ale nějaký platné důvody, proč je chcete diferencovat.
  • Budujete nějaký utilitní mixin.

Další starost možná budou činit obrovité zásobníky selektorů. V některých případech může pomoci vybudovat nějakou obalovou třídu, ale, řečeno obecně, byste neměli mít obrovitý zásobník selektorů, protože elementy samy o sobě jsou elementy sémanticky různé a neměly by sdílet až tak mnoho stylů. Důvod pro smysluplné CSS spočívá v tom, že ze svých CSS víte, že ten button nebo [role=button] se aplikuje na všechna tlačítka, ale že položkou primární akce na formuláři je vždy [type=submit].

V současné době máme k dispozici tolik mocných atributů, že bychom neměli potřebovat obrovité zásobníky selektorů. Když se vyskytují, indikuje to ledabylé uvažování nad tím, čím věci vlastně jsou a jak bylo původně zamýšleno je používat v rámci celého systému.

Je na čase, abychom zdokonalili své CSS. Můžeme sice zůstat dogmaticky připoutáni ke vzorům, které byly vyvinuty kdysi tam, odkud jsme už odešli, nebo se můžeme posunout kupředu s CSS a značkováním, které odpovídají definovaným specifikacím a standardům. Dnes můžeme používat skutečné objekty, nemusíme vytvářet jejich abstraktní reprezentace. Podporu od prohlížečů máme. Standardy a odkazy jsou k dispozici. Můžeme začít už dnes. Zdržují nás jen naše staré návyky.

O autorovi

Tim Baxter

Tim Baxter je designér, vývojář, „obsahový kovboj“ (content wrangler), produktový manažer nebo stratég, záleží na tom, co si musel zrovna ten den obléknout. Často se potuluje po komunitě Django, na Github, nebo na Twitteru.

Celý článek v originálním znění najdete na Meaningful CSS: Style Like You Mean It

Přeložil: RNDr. Jan Pokorný

Štítky: CSS

Mohlo by vás také zajímat

Nejnovější

3 komentářů

  1. viktor

    Srp 16, 2016 v 19:31

    na tomto som si od roku 2003 asi ako jediny html koder na sk zakladal.. :) vyhradne na tomto

    Odpovědět
  2. darkWolf

    Říj 4, 2016 v 10:16

    Gratuluju, tak po tomhle článku už víme, že Tim Baxter je idiot a že podporuje Explorer 11. Po nás ostatních ovšem chtějí, aby se web zobrazil v použitelném tvaru i v Exploreru 6, který část klientů z nějakého nepochopitelného důvodu stále používá a dosud se nedozvěděla, že existuje něco jako Windows 7+.

    Odpovědět
  3. Aelomart

    Úno 5, 2018 v 10:53

    I have just finished reading the article you wrote.
    While much has been written on this topic, your article expresses both the positive and negative aspects of this important topic.
    Thank you for your thorough research and clear writing.

    But I like to add to this

    Add intro text to the top of the form
    Adding a short piece of intro text can help clear up any outstanding issues. Intro text should include:

    The reason why someone will fill out the form.
    Instructions. If and only if you are nervous about switching to marking optional instead of required. For example, “all fields are required, except ones marked as optional.”

    Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *