Na navigaci | Klávesové zkratky

Translate to English… Ins Deutsche übersetzen…

SASS, LESS, Stylus nebo čisté CSS? (2)

Vyplatí se používat CSS preprocesory? A pokud ano, který zvolit? Pokračuji v rozboru tří nejznámějších konkurentů.

CSS preprocesor je nástroj, který vám ze zdrojového kódu zapsaného ve vlastní syntaxi vygeneruje CSS pro prohlížeč. Mezi nejznámější patří SASS, LESS a Stylus. Mají řešit praktické nedostatky samotného CSS.

předchozí části jsme si ukázali, jak preprocesory nainstalovat. Dnes se jim podívám na zoubek.

Syntaxe

Ač jednotlivé nástroje používají odlišnou syntax, všechny rozumí klasickému CSS. To je nesmírně důležité! Můžete kopírovat existující CSS fragmenty a budou fungovat. Ačkoliv…

SASS používá dvě různé syntaxe, jedna se nazývá SASS (stejně jako preprocesor), nepoužívá středníky ani složené závorky {} a místo toho odsazuje mezerami či tabulátory:

// SASS
#main
    color: blue
    font-size: 0.3em

Druhou syntaxí je SCSS, která vypadá jako klasické CSS a měla být i plně kompatibilní (budu ji pro SASS používat v dalších příkladech). Stejnou syntax má i LESS:

// SCSS, LESS a CSS
#main {
    color: blue;
    font-size: 0.3em;
}

Stylus také rozumí CSS syntaxi, nicméně upozorňuje, že nejde o 100% kompatibilitu, především proto, že hodně bazíruje na odsazování. V jeho syntaxi lze vynechat složené závorky, středníky a dokonce i dvojtečky:

// Stylus
#main
    color blue
    font-size 0.3em

Ale pozor! Důležité je, že tyto znaky můžeme vynechat. Pokud vám zápis připadá příliš hutný, klidně si dvojtečky doplňte. Nechcete odsazovat? Vražte tam složené závorky. Velmi podobně funguje NEON. V tomto se zásadně liší od úsporné SASS syntaxe, kde vynechání závorek a středníků je povinnost. Což ji činí z praktického hlediska nepoužitelnou a chápu, proč tvůrci o kompatibilitu s CSS usilovali, ale udělali to nešťastně zavedením další, nekompatibilní, ukecané syntaxe SCSS.

Když už se totiž rozhodnu preprocesor používat, ocením, když mi zjednoduší i syntaxi (alespoň nepovinné středníky), což bohužel umí jen Stylus. Jeho syntax je nejpružnější a nejúspornější.

V kontrastu přísnosti LESS a SASS je zajímavé, že všechny tři preprocesory podporují // řádkové komentáře.

Když udělám chybu

Pokud uděláte v dokumentu chibu, preprocesory vás na ni upozorní chybovou hláškou. A v tomto směru se jednotlivé nástroje zásadně liší. Pokud třeba zapomenu ve výše uvedeném kódu uzavírací }, oznámí SASS:

Syntax error: Invalid CSS after "font-size: 0.3em;": expected "}", was ""
        on line 4 of test.scss

Stylus:

      if (err) throw err;
                     ^
ParseError: stdin:4
   1| #main {
   2|   color: blue;
   3|   font-size: 0.3em;
 > 4|

unexpected "eos"

a LESS:

ParseError: missing closing `}` in test.less:9:17
8
9 unexpected "eos"undefined

Nutno dodat, že LESS měl šťastnější chvilku. Pokud bych zapomněl středník, skončí to u obvyklejšího

ParseError: Syntax Error on line 2 in test.less:2:1
1 #main {
2       color: blue
3       font-size: 0.3em

Výmluvné chybové hlášky jsou pro mě důležité a v tomto směru s přehledem vede SASS. Ačkoliv se to z ukázky tak nejeví, hodně se snaží i Stylus. Běžně však špatně spočítá číslo řádku a hlásí chybu o pár řádků výš, než skutečně je. LESS se nejčastěji zmůže na nicneříkající Syntax Error on line XY.

Občas jsem narážel na chyby v samotném preprocesoru. Pokud se mi je podařilo izolovat, snažil jsem se je nahlásit (LESS, Stylus), ale ne vždy to šlo. Zde se nejvíc projevila vyspělost jednotlivých nástrojů. Zatímco nejstarší SASS se mi z rovnováhy nepodařilo vyvést nikdy, druhé dva nástroje obsahují chyb bohužel požehnaně.

Co všechno umí?

Drtivou většinou užitečných vychytávek najdeme u všech tří nástrojů, byť třeba nemusí být uvedeny v dokumentaci. V množství asi vede SASS, ale takto se to hodnotit nedá. Třeba nested properties nepotřebuji, naopak property lookup a generátor data URI ve Stylusu vypadá užitečně. Tedy do chvíle, než zjistíte, že převádí buď všechny obrázky, nebo žádný.

Nechci sepisovat výčet jednotlivých vlastností ani srovnávat jejich zápis, to najdete v dokumentaci nebo ve srovnávacím článku na NetTuts. Zaměřím se místo toho na fundamentální rozdíly a největší z nich se týkají tzv. mixinů.

Mixiny

Mixiny jsou z mého pohledu nejdůležitější vychytávkou preprocesorů, protože mění způsob, jak píšeme HTML kód. Vysvětlím. Asi nejznámější „mixin“ je tzv. clearfix, která se stará o to, aby z bloku nevytékaly plovoucí prvky. Obvykle vypadá nějak takto:

.clearfix:after {
    clear: both;
    content: ".";
    display: block;
    height: 0;
    visibility: hidden;
    font-size: 0;
}

(Poznámka: existují jednodušší i složitější varianty clearfixu. Kupodivu mně vždycky fungovalo nastavit bloku overflow: auto a clearfix jsem nepotřeboval. Ale v tuto chvíli jde jen o příklad.).

Clearfix pak aktivujeme v HTML:

<div id="content" class="clearfix">
    <div style="float: left;">....</div>
    ...
</div>

Ale to neděláš dobře, Jaromíre. Clearfix by se měl aplikovat na straně stylů, přímo pro #content, nikoliv v HTML. Jenže komu by se chtělo kazit si krásný stylopis kopírováním ošklivého hacku? Mnoho kodérů raději sáhne do HTML.

S preprocesory však netřeba nic kopírovat a vystačíme si s jedinou instrukcí. Nejprve si clearfix uložíme jako tzv. mixin a poté ho v definici #content zavoláme:

SASS:

// definice mixinu (zkráceno)
@mixin clearfix {
    &:after { clear: both; ... }
}

#content {
    @include clearfix; // vložení mixinu
}

LESS:

.clearfix() {
    &:after { clear: both; ... }
}

#content {
    .clearfix;
}

Stylus:

clearfix()
    &:after { clear: both; ... }

#content
    clearfix()

Zmizí tak nutkání zasahovat do zdrojového kódu. A to je velmi důležité.

Jak vidno, syntaxe SASS je opět nejukecanější. Za zmínku stojí, že LESS umožňuje volat jako mixin i jakoukoliv třídu nebo ID.

Parametrické mixiny

Ještě zajímavější je to ve chvíli, kdy mixinům předáme parametry:

SASS:

@mixin border-radius($arg) {
    -webkit-border-radius: $arg;
    -moz-border-radius: $arg;
    border-radius: $arg;
}

#content {
    @include border-radius(2px);
}

LESS:

.border-radius(@arg) {
    -webkit-border-radius: @arg;
    -moz-border-radius: @arg;
    border-radius: @arg;
}

#content {
    .border-radius(2px);
}

Stylus:

border-radius(arg)
    -webkit-border-radius: arg
    -moz-border-radius: arg
    border-radius: arg


#content
    border-radius(2px)

Ve Stylusu můžeme použít i zapis s dvojtečkou:

#content
    border-radius: 2px

Což je velmi zajímavé! Když totiž později vendor prefix odstraníme, nebo když naopak zjistíme, že určité vlastnosti potřebujeme vendorovou variantu dodat, nemusíme změnit ani čárku v samotném stylu. Wow.

Jenže… co když mixin zavoláme s více parametry? Například uvedeme border-radius: 2px 3px. Překvapivě Stylus bude 3px v tichosti ignorovat. Proč tomu tak je?

V CSS existují dva způsoby, jak uvést více argumentů, lišící se v oddělovači:

  • oddělené mezerama: border: 1px solid black
  • oddělené čárkama: rgb(10, 20, 30)

Totéž se rozlišuje i v preprocesorech. Ve Stylusu platí, že volání mixinu border-radius: 2px 3px je ekvivalentní k border-radius(2px, 3px) (a dává mi to smysl), obojí představuje předávní dvou argumentů. Naopak border-radius(2px 3px) bez čárky předává argument jeden. Náš mixin očekává pouze jeden parametr a druhý tiše bez jakéhokoliv varování zahodil. Oprava spočívá v použití užitečného klíčového slova arguments namísto předaného argumentu arg.

SASS a LESS naopak předání více argumentů, než je mixinem očekáváno, vnímají jako fatální chybu. V případě SASS to v důsledku vede k podivným blokům $shadow-1, …, $shadow-10 patrným v galerii Compass, zatímco LESS se s problémem snaží vypořádat konstrukcí when(). Nic z toho mi nepřipadá ideální.

Pokračování zase příště.

Komentáře

  1. Sniper http://www.bugie.cz #1

    avatar

    Mozna jsem hnidopich, ale v sekci kdyz udelate chybu v prvni vete „Pokud uděláte v dokumentu chibu, preprocesory…“ to mekke i je zamer nebo chyba? Jinak clanek suprovej.

    před 5 lety
  2. zetcha #2

    avatar

    Pokud uděláte v dokumentu chibu ← a tu jsme udělali :-)

    před 5 lety
  3. zetcha #3

    avatar

    Sniper byl rychlejší. :-)

    před 5 lety
  4. Trta #4

    avatar

    Ja naopak považuju nested properties za klíčovou vlastnost css preprocesorů, která spolu s mixins pomáhá udržet ve stylopisech pořádek. Mohl bys prosím naťuknout, z jakého důvodu ti nested p. nepřišly užitečné?

    před 5 lety | reagoval [6] David Grudl
  5. Jan Panschab #5

    avatar

    No jo, ale jak se vypořádat s Intellisense (našeptávání/doplňování) a syntax highlighting v IDE? Bez Intellisense si už psaní stylů nedokážu představit. Např. v Netbeans přestává Intellisense fungovat jakmile se zbortí syntaxe.

    před 5 lety
  6. David Grudl http://davidgrudl.com #6

    avatar

    #4 Trto, nested properties != nested rules

    před 5 lety | reagoval [7] trta
  7. trta #7

    avatar

    #6 Davide Grudle, Ahso! Jdu se posypat žhavým popelem a polít lávou :)

    před 5 lety
  8. Jakub Vrána http://php.vrana.cz #8

    Já už začínám tušit, jaký bude poslední díl tohoto seriálu: Napsal jsem vlastní preprocesor CSS, protože ostatní –stály za starou bačkoru– mi nevyhovovaly.

    před 5 lety
  9. arron #9

    Ono v zásadě takový NEON by se nejspíš dal do CSS celkem slušně transformovat…spolu s některými features z Nette (%variable%) by to mohlo celkem jednoduše umět to zásadní.

    před 5 lety
  10. gagga #10

    avatar

    K čemu je to tedy dobré? :) Když napíšu kvalitní stylopis tak prostě nepotřebuji nic zkracovat apod. A dokonce ani nepotřebuji užívat hacky apod.

    před 5 lety
  11. HonzaMac #11

    avatar

    Prosím o uveřejnění posledního dílu. Napjatě čekám co z toho bude …

    před 5 lety
  12. Samuel #12

    Ešte stojí za to kuknúť na compass, založené na sass, ale vie to trochu viac vecí, napr. sprites, generovanie url, mnoho predkódených mixinov.

    před 5 lety
  13. ic http://icweb.eu #13

    avatar

    Ještě mě tak napadlo… podporuje některý z nich media queries (z CSS3)? Tedy podle pravidla Mobile First nabízí media queries možnost rozdělit si styly do několika souborů a ty se načítají jen po splnění určité podmínky (třeba šířka zobrazené plochy). Príma je že ostatní css soubory pro desktopy se ani nenačítají a tak šetří mobilní data. Nevýhoda je právě ten zápis do více souborů (často stejných věcí do více soubrů) a to, že less (ostatní neznám) v tomhle vůbec nepomůže. Je dost možné, že to někdy přijde jako nová funkce, ale dost by se mi hodila už teď.

    před 5 lety | reagoval [14] David Grudl
  14. David Grudl http://davidgrudl.com #14

    avatar

    #13 ici, podporuje to pouze SASS.

    před 5 lety
  15. David Grudl http://davidgrudl.com #15

    avatar

    Doplnil jsem článek o závěrečné tři odstavce, aby byl problém s předáváním argumentů uzavřený.

    před 5 lety

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.