5 důvodů, proč považuji CSS za opravdu zpackané

13. února 2015

Přicházím nyní jako generál po bitvě, abych světu vyjevil, oč mohly být CSS lepší, kdyby…

Jaké by vlastně měly webové standardy být?

  • jasné, srozumitelné a logické – aby se v nich každý vyznal
  • jednoduché, účelné a kompatibilní – aby se s nimi snadno pracovalo

Pravidla, která tato kritéria nesplňují, jsou obtížně aplikovatelná a zejména začátečníky uvádějí ve zmatek. Jelikož však nežijeme v dokonalém světě, tak ani webové standardy nejsou vždycky optimální. Chtěl bych teď na několika případech dokumentovat, že i CSS jsou zatíženy některými dle mého soudu nedomyšlenými věcmi.

1. Rozměry prvků

Jak známo, v CSS se za šířku (width) považuje šířka obsahu prvku, okrajové části – výplň (padding) a ohraničení (border) – se už nezapočítávají. To samé platí i pro výšku (height), ani do ní se výplň a ohraničení nezapočítávají.

box-model

Je to dost nepraktické, neboť webdesignéři potřebují k vizuálnímu uspořádání prvků na stránce znát jejich plnou šířku a výšku! Tuto skutečnost si nakonec uvědomili i ve W3C a standardizovali vlastnost box-sizing, díky níž lze do šířky a výšky prvku konečně připočítat i padding a border.

Poznámka: Pokud je obsahem prvku další blokový prvek, zvětší se celková šířka a někdy i výška prvku o jeho margin, více o tom v následující kapitole.

2. Vertikální odsazení

Vlastnost margin určuje velikost vnějšího okraje prvku, čili odsazení. Zmatek spočívá v tom, že vertikální margin se vždy nechová úplně stejně jako horizontální. Zatímco horizontální margin blokových prvků se počítá maximálně jen k hraně rodičovského prvku, tak ten vertikální může hranici rodičovského prvku volně „přetékat“ a představuje v takovém případě vzdálenost ne od dalšího prvku v pořadí struktury, ale od dalšího obsahu. Znázorněno je to na následujícím obrázku: V horizontálním směru se okraje skládají, ve vertikálním se prolínají. Pro prvky na obrázku platí CSS deklarace div, p {margin: 3em; background: rgba(248,90,4,.3)}.

margin

Teprve když se rodičovskému prvku nastaví nenulový padding nebo border (o tom v další kapitole), velikost okrajů prvků se sjednotí (samozřejmě za předpokladu, že budou zadány shodné rozměry). Padding a border představují jakousi překážku, o kterou se margin zarazí a už nemůže„přetéct“ rodičovský prvek.

Jestli podané vysvětlení zní složitě, je to právě vinou komplikovanosti uspořádání a výpočtu okrajů prvků.

V minulosti představovalo vertikální centrování bloků obtížně řešitelný problém. Vlastnost vertical-align se tehdy nevztahovala na bloky (pokud nebyly uvnitř tabulky), tabulkové hodnoty vlastnosti display nepodporoval IE 6. Nic z toho by však nevadilo, kdyby pro zarovnání bloku na střed bylo možné použít margin, konkrétně jeho hodnotu auto, díky níž se velikost vnějších okrajů prvku dopočítá automaticky. Ve vertikálním směru se však nedopočítává rovnoměrně, což má za následek to, že prvek zůstane pitomě přimáčklý k hornímu kraji rodičovského prvku, místo aby zaujal pozici v jeho středu. Opět tedy vzniká situace, kdy se vertikální margin chová jinak než horizontální.

3. Nijaký rámeček

Vlastnost border-style má řadu zbytečných hodnot, z nichž naprosto neužitečné jsou dvě: none a hidden. V podstatě mezi nimi není žádný rozdíl, obě šířku rámečku zcela vynulují, což se dá smysluplněji provést i pomocí border-width. Smysluplnější by to bylo v tom, že při přidávání rámečku by pak v mnoha případech stačilo zadat pouze jeho šířku. Nezkušení kodéři někdy právě takto postupují, zadají jen šířku a pak se diví.

Dá se říct, že o nic hrozného nejde, ale kdyby se všechny CSS vlastnosti standardizovali takto nevhodně, byl by z toho pak v CSS zmatek nad zmatek.

4. Oblé rohy

Jedna z výborných věcí na CSS je to, že jednotlivé vlastnosti jsou systematicky a výstižně pojmenovány. Díky tomu není těžké poznat, k čemu která vlastnost slouží. Říká to už svým názvem. Některé vlastnosti jsou však výjimkou, například border-radius. Z názvu této vlastnosti by snad mohlo vyplývat, že určuje jakousi vzdálenost od ohraničení prvku, ale nic to nenapovídá o jejím účelu. Navíc border-radius nemá s ohraničením příliš co dělat, funguje i při border-style: none;. A to proto, že vyjadřuje vzdálenost od určitého bodu až úplně ke kraji (angl. edge) prvku, ne pouze k rámečku. Přesnější název vlastnosti by asi byl corner-radius. To už by možná mohlo někomu něco říct.

Když už tak kouzlím s názvy vlastností, napadlo mě, že ani názvy jednotlivých rohů nejsou zrovna ideální. Než napíšu border-bottom-right-radius, tak udělám nějaký překlep. A napsal jsem vůbec ta slova ve správném pořadí? Oč jednodušší by bylo pojmenovat jednotlivé rohy písmeny jako v geometrii.

Nevhodný název však je na vlastnosti border-radius spíše jen drobná nepříjemnost. Mnohem vážnější problém představuje propojení přilehlých stran rámečku, které mají odlišnou barvu. Obvykle se takto ztvárněným rámečkem vytváří iluze vyvýšeniny nebo prohlubně (např. tlačítka nebo propadlé kolonky). Jakmile je však takový objekt zakulacen pomocí vlastnosti border-radius, plastický efekt se pokazí, jak ukazuje následující příklad s obrázkem:

button {
	font-weight: bold;
	background: red;
	border: outset red;
	border-radius: 1em;
}
cudlikPro zachování zmíněného efektu je proto nutné, aby oblý roh byl řešen barevným přechodem, což bohužel specifikace neřeší.

Druhým zásadním problémem jsou tabulky s nastavením border-collapse. Takovou kompaktní tabulku, bez mezer mezi buňkami, nelze zakulatit, protože specifikace nedovoluje na ni aplikovat border-radius. Toto omezení, byť se může zdát logické, je naprosto zbytečné. Ve skutečnosti neexistuje důvod, proč by vnější rohy mřížky nemohly být zaobleny.

Dalším zbytečným omezením je nepovolení záporných hodnot. Záporný border-radius by umožnil dělání oblých rohů vypouklých směrem dovnitř.

5. Vykrádání historie prohlížečů

Zavedení pseudotřídy :visited přineslo uživatelům přehled, které odkazy už navštívili. A nejen jim! Také provozovatelé webu získali tímto způsobem přístup k historii uživatelem navštívených stránek. Mohli toho využít například k cílené reklamě. Nebo zneužít ke zdokonalení phishingových útoků! Prohlížeče se samozřejmě snaží soukromí svých uživatelů chránit, jenže v tomto případě jsou naprosto bezmocné, protože způsobů, jak detekovat navštívené odkazy existuje příliš mnoho.

Jedinou možností, jak se s touto situací důsledně vypořádat, bylo přestat pseudotřídu :visited podporovat, nebo aspoň omezit jen na ty odkazy, které nevedou pryč z domény. K tomu se ovšem nikdo neodhodlal, a tak se nakonec zvolilo jiné řešení, které není tak přímočaré – zamezilo se detekci stylu navštíveného odkazu. Pokud tedy někdo v javascriptovém kódu použije např. querySelectorAll(":visited"), bude se to chovat, jako by žádné navštívené odkazy nebyly. To samé nastane při stylování – při použití pseudotřídy :visited bude sice možné navštívené odkazy barevně odlišit, ale jinak vše bude vypadat, jako by žádný navštívený odkaz neexistoval. Je to proto, aby nedošlo k detekovatelnému ovlivnění dalších prvků (jejich rozměrů, pozice apod.) na stránce. Tato opatření nejsou čistá a elegantní, ale zachovávají bezesporu užitečné rozlišení odkazů.

Nic dalšího?

Kdybych měl tu možnost, asi bych CSS dost radikálně změnil. Trnem v oku je mi například předimenzovanost vlastnosti content, pomocí níž je možné dodatečně vkládat nejen textový obsah, ale i atributy nebo rovnou celý HTML kód obrázek. Je mi však jasné, že můj pohled na CSS je pouze jeden z mnoha úhlů pohledu a že ne všechny moje výhrady budou ostatní sdílet, a proto nikomu své názory nevnucuji. Přesto si však myslím, že je dobré se nad tím, co používáme, občas trochu zamýšlet, a tak jsem z CSS vybral alespoň několik věcí, které považuji podle kritérií, jež jsem uvedl hned na začátku, objektivně za špatné.

Štítky: CSS

Mohlo by vás také zajímat

Nejnovější

4 komentářů

  1. Marek Králík

    Úno 13, 2015 v 19:40

    CSS je zpackané, ale autor článku se ani povrchově nedostal k jádru problému a místo toho sesmolil pár jeho subjektivních dojmů. Až mám tendenci odstranit interval z rss čtečky. Pište články, které mají aspoň nějakou odbornost, nebo raději nepublikujte nic.

    Odpovědět
    • Marek Machač

      Úno 17, 2015 v 11:01

      Děkujeme za zpětnou vazbu. Doufám, že nám přízeň zachováte. Aktuálně chystáme seriál o programování, který bude užitečný i pro odborníky v oboru.

      Odpovědět
  2. Michal Polák

    Úno 17, 2015 v 11:22

    Zatímco tento článek není užitečný očividně pro nikoho.

    Odpovědět
  3. Yuhů

    Úno 18, 2015 v 17:00

    Kéž by vlastností content šel vkládat celý HTML kód, jak autor naznačuje pod nadpisem „Nic dalšího“.

    Jinak je to zajímavá skladba problémů.

    Odpovědět

Napsat komentář: Marek Králík Zrušit odpověď na komentář

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