Gratulujeme! Úspěšně jste se přihlásili k odběru novinek Frontend Garden.
Ajaj. Při pokusu o přihlášení k odběru novinek došlo k chybě. Zkuste to prosím znovu.
Frontend Garden
  • Články
  • Slovník nové
  • Instagram
  • GitHub
20. červen 2024 —
  • CSS,
  • Kvalita kódu
— čtení na 10 min.

Vývoj efektivity zápisu CSS

CSS má za sebou dlouhou historii. Tušíte, co bylo před příchodem CSS na scénu webového vývoje a co přispívá k těžkopádnému škálování a udržování stylopisů?

Ondřej Konečný

Ondřej Konečný

Ondřej je designer a vývojář, který se zaměřuje na návrh a implementaci uživatelských rozhraní. Více o autorovi

V roce 1994 přišel Håkon Wium Lie na to, že je potřeba vytvořit jazyk, který umožní vizuálně upravovat dokumenty na webu. Hlavní myšlenka byla postavena na tom, že je potřeba oddělit obsah od prezentace. A tak se stalo, že se Håkon spolu s dalšími autory podílel na vytvoření první verze CSS, kterou postupem času implementovaly všechny prohlížeče. Po HTML se z CSS stal druhý standardizovaný jazyk pro W3 (World Wide Web). Ale nepředbíhejme. Nejprve se podívejme na to, jak to celé začalo.

Jak je vidět na snímku níže, po vložení stejného HTML se na dvou různých prohlížečích (Netscape a Mosaic) zobrazoval obsah rozdílně. Vývojáři prohlížeče Mosaic se totiž rozhodli přidat před seznam (dnes známý jako unordered list) odsazení seshora. Mysleli si, že to tak bude vypadat lépe. Jenže všichni to vnímali jako chybu a získávali potřebu mít kontrolu nad tím, jak se jejich obsah na webu zobrazí.

Archivní e-mailová komunikace zachycující rozdílnou interpretaci HTML — Zdroj: World Wide Web History Center

V polovině 90. let, kdy se začaly objevovat první webové stránky, bylo odlišení od výchozího nastavení zobrazení v prohlížečích opravdovým oříškem. V době, kdy se kaskádové styly teprve testovaly, byla možnost upravovat podobu zobrazení jedině pomocí HTML atributů. První webové prohlížeče jako ViolaWWW však neumožňovaly upravit vizuální podobu takřka vůbec.

Prohlížeč ViolaWWW — Zdroj: Wikipedie

Co bylo před tím, než přišlo CSS?

Postupem času začali autoři webových stránek tvořit první pokusy o to, čemu dnes říkáme webdesign. Častým příkladem webu z 90. let byla stránka Space Jam.

Stránka Space Jam z roku 1996 — Zdroj: spacejam.com

Na tomto webu je dobře vidět, jak se v této éře přistupovalo k barevnému odlišení textů a odkazů a jak se pracovalo s layoutem.

Veškeré barvy byly definovány v těle stránky, kde tvůrci pomocí HTML atributů nastavili základní pravidla pro zobrazení. Konkrétně atributy bgcolor, text, link, vlink a alink. Takto definované atributy pak odlišovaly barvy textů, odkazů a pozadí.

<body
  bgcolor="#000000"
  text="#ff0000"
  link="#ff4c4c"
  vlink="#ff4c4c"
  alink="#ff4c4c"
>

Dalším pěkným příkladem na tomto webu je layout . Ten se ve své době upravoval jen pomocí tabulek a struktura layoutu vznikala zanořováním tabulek do sebe. Tato technika se pak několik dalších let používala pro tvorbu všech layoutů webových dokumentů. Nejprve kruhový layout (příklad webu Space Jam) a následně Holy Grail Layout, který byl trendem ve webdesignu spoustu let.

Tabulková technika se dodnes doporučuje pro tvorbu newsletterů a PDF generovaných pomocí HTML, protože mnoho e-mailových klientů se rozhodlo své systémy neměnit.

Code newsletters like it’s still 1999.

Na tomto příkladu je vidět, jak přišli autoři k výsledku kruhového layoutu, který byl v té době populární. Tím se chtěli společnosti odlišit od konkurence, a proto vznikaly první pokusy o vizuální změny výchozího nastavení.

Ukázka kruhového layoutu — Zdroj: spacejam.com

Umístění obrázků do kruhového layoutu je pak řešeno opět pomocí atributů tabulek — konkrétně pak align a valign a taky pomocí HTML tagů <br>.

<table width=500 border=0>
  <tr>
    <td colspan=5 align=right valign=top></td>
  </tr>
  <tr>
    <td colspan=2 align=right valign=middle>
      <br>
      <br>
      <br>
      <center>
        <a href="cmp/pressbox/pressboxframes.html">
          <img
            src="img/p-pressbox.gif"
            height=56
            width=131
            alt="Press Box Shuttle"
            border=0
          >
        </a>
      </center>
    </td>
    <!-- … -->
  </tr>
  <!-- … -->
</table>

Tímto způsobem se několik let (v případě progresivních vývojářů, kteří experimentovali s CSS, jen prvních pár let) tvořil webdesign.

Nástup CSS

Kaskádové styly byly v té době revoluční. Eric Meyer — který se spojil s ostatními vývojáři — začal v roce 1998 popisovat, jak je možné implementovat a používat styly. Postupem času se tak CSS dostalo na první webové stránky a začalo se plně využívat pro designování webů. Třeba tímto (pro mnohé z nás mírně odstrašujícím) způsobem:

<STYLE type=”text/css”>
  BODY {
    font-family: serif;
    background-color: silver;
  }
  H1 {
    font: x-large Verdana, sans-serif;
    color: olive;
    border-bottom: thin black solid;
  }
  .sidebar UL LI {
    list-style-type: none;
    margin-left: 0;
    margin-right: 0.5em;
  }
  .sidebar UL LI A {
    color: #ffcccc;
  }
  .body {
    background: white;
  }
  IMG.icon {
    border: outset gray 3px;
    padding: 0;
  }
</STYLE>

Následně pak přicházely další deklarace, vlastnosti nebo hodnoty, a CSS se tak stalo dalším nepostradatelným jazykem pro vývoj webů.

Na začátku to byla velká revoluce. Už nebylo potřeba pro změnu barvy nadpisu přepisovat hodnoty atributů na všech stránkách, ale stačila jedna drobná změna v kaskádových stylech a změny se projevily všude na webu.

Vývojáři začali CSS používat, ale nikdo se nezabýval potřebou styly nějak strukturálně organizovat a udržovat. Psaní CSS bez jakékoli organizace nebo myšlenky pro udržitelnost už nebylo dostačující. Neexistovaly žádné postupy, jak udržovat kaskádové styly a jak se vyrovnat s mnohdy nekonzistentním designem velkých webů (což trvá v některých případech dodnes). A tak začaly vznikat komplikace…

Two CSS properties walk into a bar.

A barstool in a completely different bar falls over.

Problémy s CSS

Jaké komplikace můžou vznikat při psaní CSS? Hlavně pro začátečníky může být psaní stylů oříškem. Na jednu stranu jsou kaskádové styly díky své přímočarosti velmi jednoduché na pochopení, na druhou stranu je dost komplikované styly udržovat, upravovat a strukturovat. Problémů se může objevit mnoho.

Frustrated Programming — Zdroj: GIPHY

Hluboké zanořování selektorů a vysoká specificita

Pojďme si tuto problematiku představit na příkladu. Vývojář se rozhodne v existujícím projektu přidat unordered list, ze kterého chce vytvořit seznam s modrou barvou odkazů a velikostí písma 20 px. Pro výběr použije selektor .seznam.

HTML vloží na web — hluboko do struktury HTML, kam patří a kde se má zobrazit:

<ul class="seznam">
  <li><a href="prvni.html">Odkaz 1</a></li>
  <li><a href="druhy.html">Odkaz 2</a></li>
  <li><a href="treti.html">Odkaz 3</a></li>
</ul>

… a CSS zapíše následujícím způsobem:

.seznam li a {
  font-size: 20px;
  color: blue;
}

Oops? Barva odkazů je červená, písmo je velikosti 16 px a navíc tučně. Podívá se do DevTools a zjistí, že je selektor už přetížen jiným selektorem, který brání ve vykreslení správného výsledku:

body #content .page ul li a {
  font-size: 16px;
  color: red;
  font-weight: bold;
}

Jakou má teď vývojář možnost? Nezbývá nic jiného, než zvýšit specificitu nově vytvořeného selektoru, upravit přetěžující selektor a nebo použít !important. Možností je samozřejmě víc, ale principiálně jde stále o boj se specificitou.

Praxe je v drtivé většině taková, že se do úprav již hotového selektoru málokdo pustí a !important víme, proč nepoužívat. Proto nezbývá jiná možnost než zvýšit specificitu přidáním třídy seznam (spolu se zbytkem selektoru) k našemu unordered listu.

body #content .page ul.seznam li a {
  font-size: 20px;
  color: blue;
}

Vzniká tak nový element, který se nedá nijak dál použít a je odsouzen k tomu, aby zůstal jen tam, kde je. Pokud bude potřeba použití jinde, nezbývá než přidat další kus kódu. Specificita se zkrátka vyplácí držet zkrátka už od prvního řádku kódu.

Výpočet specificity

V CSS se šablony stylů vybírají podle důležitosti a selektory mají podle typu definice různé hodnoty.

Po posouzení důležitosti pravidla mu kaskáda přisuzuje specificitu; pokud se na stejný prvek vztahují dva selektory CSS, vyhrává ten s vyšší specificitou.

Ukázka výpočtu CSS specificity

Jako vývojáři občas děláme chybu a pokoušíme se cílit na prvek HTML více než jednou. Obvykle také zvyšujeme hodnotu specificity přidáním nebo úpravou selektoru. Krátkodobě to funguje skvěle, ale obvykle se to dříve nebo později vymkne kontrole. A to způsobuje problémy právě se specificitou. Podívejme se ještě na následující příklad, kde je vidět, jak se zvyšuje hodnota specificita selektorů.

Můžete zkusit vybrat prvek navigace v DevTools, abyste viděli, jak jsou ostatní selektory ignorovány.

Zobrazení CSS specificity přímo v DevTools po najetí na selektor myší

Závorkové peklo alias Nesting Hell

Vývojářům, kteří psali CSS, chyběla spousta funkcí (podmínky, cykly, ...), které nabízí jiné programovací jazyky. Proto se od roku 2005 objevily na scéně preprocesory jako Sass či LESS, které přispěly k efektivnějšímu kódování. Ruku v ruce však přinášely řadu neduhů, se kterými se museli vývojáři vypořádat –⁠ jedním z nich je tzv. Nesting Hell.

Preprocesory (a od prosince 2023 částečně i nativní CSS) umožňují vnořování selektorů, pomocí kterých je možné zapsat několik jeho úrovní na pár řádků a odpadá nutnost zapisovat víceúrovňová pravidla znovu dokola. Často se však nedbá na to, co nám preprocesory přeloží do výsledného CSS a díky funkcím jako @extend vzniká velké množství kódu navíc, které zhoršují rychlost načítání.

Rozluštění takového kódu a jeho následná úprava tak byla v některých případech takřka nemožná. Následující kód vypadá hrozivě, není to však vůbec nic výjimečného a při refaktorování CSS se s něčím takovým setkáme docela často.

.Checkbox--toggle {
  padding: $chekcbox-toggle-diameter / 10 0;
    .Checkbox {
      &-input {
        &:checked {
          & + .Checkbox-label {
            @extend .Checkbox-toggle — active;
          }
        }
      &:not(:checked) {
        &:focus {
          & + .Checkbox-label {
            &::before {
              background-color: $checkbox-toggle-active-handle-bg;
            }
          }
        }
      & + .Checkbox-label {
        background-color: rgba($checkbox-toggle-bg, 0.46);
      }
    &[disabled], &[readonly] {
      & + .Checkbox-label {
        @extend .Checkbox-toggle — disabled;
      }
    }
  }
  &-label {
    @extend .Checkbox-toggle;
  }
}

Jak asi bude vypadat výsledný zkompilovaný selektor? Netroufl jsem si zveřejnit výsledek tohoto selektoru, ale z následujícího obrázku si můžete vytvořit představu, jak takové výstupy vypadají.

Výsledný překompilovaný CSS soubor z projektu jednoho mého klienta

Takovému zanořování selektorů bychom se měli vyvarovat. Dobrým zvykem je používat zanoření selektorů maximálně do druhé, s výjimkou do třetí úrovně. Kód zůstává dobře čitelným a nezpůsobí nám nikdy nekončící bolesti hlavy.

.button {
  padding: 10px;
  
  @include breakpoint(tablet) {
    padding: 8px;
  }
  
  &:hover {
    background: blue;
  }
  
  &.is-active {
    color: red;
  }
  
  &-icon {
    max-width: 16px;
  }
  
  &-text {
    font-size: 0.875rem;
  }
}

Ukázka střídmého zanořování kódu v SCSS

Zápis je dobře čitelný a vývojář hned pochopí, co se děje, jak může zápis dál rozšiřovat a pracovat s ním. Dobře tuto problematiku popsal Martin Michálek na svém webu Vzhůru dolů.

Kaskáda — pořadí zápisu pravidel a struktura souborů

CSS je zkratka pro Cascading Style Sheets, a proto hraje kaskáda důležitou roli při práci se styly. Musíme dávat pozor na pořadí, ve kterém selektory zapisujeme a to díky mechanismu kaskády. Kaskáda je algoritmus, podle kterého prohlížeč rozhoduje o tom, které styly použije. Rozhoduje, jak jsou pravidla aplikována, v jakém pořadí a co se stane, když dojde ke konfliktu dvou nebo více pravidel.

Kaskáda ve své metaforické podobě — Zdroj: GIPHY

Kaskáda je jednou z nejvýkonnějších částí CSS, ale může být také velmi frustrující. Je jedním z důvodů, proč jsme všichni v pokušení přidávat !important do našich stylů. Osobně si myslím, že je to jeden z nejsložitějších algoritmů na pochopení, přesto je základem pro psaní CSS.

Když mluvíme o kaskádě, máme na mysli kombinaci pravidel, které jsou vzájemně propojeny a je důležité chápat jejich návaznost. V zásadě se jedná o tato čtyři pravidla:

  1. Pořadí a pozice jednotlivých pravidel - Pokud existují konfliktní hodnoty pro vlastnost v šabloně stylů, které odpovídají selektorům stejné specificity (i původu se stejnou prioritou), použije se poslední deklarace v pořadí stylů.
  2. Specificita pravidel (selektorů) - Algoritmus určuje, který CSS selektor bude použit na základě skóre specifičnosti. Při porovnávání specificity selektorů převažuje deklarace s vyšší specificitou.
  3. Důležitost pravidel (selektorů) - Některá pravidla CSS mají vyšší váhu než jiná, zejména ta, která používají typ pravidla !important.
  4. Původ - Kaskáda zvažuje, odkud CSS pochází. Může se jednat o interní šablony stylů prohlížeče (user-agent), styly zavedené rozšířeními prohlížeče nebo operačním systémem či autorské styly webu.

Podívejte se pozorně na předchozí příklad:

Z předchozího příkladu můžeme vzít následující body:

  • Pokud mají selektory dvou deklarací stejnou váhu (specificitu), pak prohlížeč použije tu, která je v kódu definovaná později.
  • Na pořadí CSS deklarací záleží.
  • Nezáleží na pořadí, v jakém jsou uvedeny třídy v HTML.
  • !important přepíše všechny selektory.

Tato extrémní závislost mezi strukturou HTML způsobuje, že kód je obzvláště křehký: i když je čistý, prostá chyba jej může zcela zničit. To je také důvod, proč komunita začala navrhovat best practices, jak se těmto problémům vyhnout. Ale o tom až někdy později…

Shrnutí

CSS má za sebou dlouhý vývoj a díky neustálému vylepšování (na kterém pracují ti nejzkušenější v oboru) se daří rozvíjet jeho funkcionality a možnosti. Drží si tak stabilní místo vedle svých kolegů pro vývoj webových dokumentů a aplikací.

👉🏻
Pokračování příště! Zajímá vás, jak předejít komplikovanému zápisu CSS a ušetřit tak čas a energii nejenom sobě ale i kolegům v týmu? Dozvíte se v příštím díle!

Související odkazy

  • Modular CSS: Best practices to improve your coding workflow (Noble Pixels)
  • Combining the Powers of SEM and BIO for Improving CSS (Ryan Yu, CSS Tricks, 2018)
  • No seriously: Don’t use @extend (Tiffany B. Brown, March 2017)
  • Extending In Sass Without Creating A Mess (David Khourshid, Smashing Magazine, 2015)
  • Specificity (MDN, 2023)
  • The cascade (web.dev, 2021)

Článek původně vyšel na Medium.com. Na návrh autora byl přenesen v upravené podobě na Frontend Garden, kde jej s radostí vítáme. 🍀


Ondřej Konečný

Ondřej Konečný

Ondřej je designer a vývojář, který se zaměřuje na návrh a implementaci uživatelských rozhraní. Více o autorovi

Další články od autora:

  • Kind of Rebeccapurple. Příběh vzniku nového loga CSS
  • Jak funguje CSS Box Model
Více k tématu:
  • CSS
  • Kvalita kódu

Sdílejte

Líbí se vám článek? Podpořte jej sdílením!

X (Twitter) Facebook LinkedIn

Komentujte

Chcete k článku něco doplnit? Našli jste chybu? Napište e-mail.

Adam Kudrna

Nejnovější články

CSS — čtení na 6 min.

Kind of Rebeccapurple. Příběh vzniku nového loga CSS

CSS má nové logo – a nese hluboký příběh. Jak komunita rozhodla o barvě rebeccapurple a proč je víc než jen odstín? 💜

  • Ondřej Konečný
    Ondřej Konečný
Kind of Rebeccapurple. Příběh vzniku nového loga CSS
WebExpo — čtení na 3 min.

Pozvánka na WebExpo 2025 + SLEVA NA VSTUPENKU

Rok se s rokem sešel, přichází měsíc květen a s ním WebExpo 2025, které se po nejistých letech usadilo v tomto jarním termínu. Jaké bude?

  • Adam Kudrna
    Adam Kudrna
Pozvánka na WebExpo 2025 + SLEVA NA VSTUPENKU
JavaScript — čtení na 10 min.

Jak předcházet chaotické organizaci npm skriptů

Řešíte, jak organizovat skripty napříč projekty přehledně a konzistentně? Inspirujte se systémem, který zjednoduší práci vám i kolegům.

  • Tomáš Litera
    Tomáš Litera
Jak předcházet chaotické organizaci npm skriptů

Odběr novinek

Zadejte svůj e-mail a nenechte si ujít další nové články!

Odesláním formuláře souhlasíte se .
Zpracování osobních údajů probíhá za účelem zasílání newsletteru. Můžete se spolehnout, že vaše osobní údaje nebudeme s nikým sdílet. Z newsletteru se můžete kdykoli odhlásit. Stejně tak můžete kdykoli požádat o úplné smazání svých osobních údajů z naší databáze.
Zkontrolujte svoji e-mailovou schránku a potvrďte své přihlášení kliknutím na odkaz.

Všechna témata

  • Bootstrap
  • CSS
  • Design
  • Dokumentace
  • HTML
  • ITCSS
  • JavaScript
  • Kariéra
  • Kvalita kódu
  • Nástroje
  • No-code
  • Přístupnost
  • PWA
  • Reportáž
  • Rozhovor
  • Rychlost
  • Sass
  • Spolupráce
  • Typografie
  • Variable fonts
  • WebExpo
  • ✏️ Napište článek
  • Autoři
  • Cookies
  • Instagram
  • GitHub

Obsah na tomto webu je publikován pod licencí Creative Commons CC BY-NC 4.0.
Frontend Garden vysázel, zastřihuje a okopává (s ♥️) Adam Kudrna.
Založeno v květnu 2019.