Základní kámen úrazu začínajícího kodéra či webdesignéra: jak dosáhnout toho, aby každý element měl stanovenou (a dobře vypočtenou) velikost a jak ji vůbec spočítat, aby byl daný element správně vykreslen? Víte, že na vině v chybné interpretaci box modelu je W3 konsorcium samo? Jak dosáhnout téměř stejných výsledků napříč prohlížeči?
Box model je (měl by být) znám snad každému. Je to dokola omílané téma, základní kámen vědění. Setkáte se s ním na každém webu nebo blogu, který se tématicky zabývá webdesignem. Přesto však v něm spousta lidí chybuje, a proto je dobré si ho připomenout. Základní kámen úrazu totiž tkví v rozhodnutí W3C - world wide web konsorcia a nikoliv ve vývojářích Internet Exploreru, jak se mnozí chybně domnívají. Konsorcium tak udělalo z box modelu doslova noční můru všem začátečníkům - a pro ně je tento článek určen.
Základní informace: box model je matematický model, dle kterého se počítají rozměry blokových elementů (div, p…). Týká se to atributů width, height, border a padding (atributu margin nikoliv).
Historie
Na počátku (rok 1994 - 1995) prohlížeč Netscape implementuje u elementu img atributy width, height a border, a to nejprve tak, že rozměry elementu určují atributy width a height, okraje (border, padding a margin) se připočtou k těmto rozměrům. To je správný - a také dnešní - postup při výpočtu rozměrů elementu, nazvěme si ho validním modelem. (Poznámka: padding byl doplněn později v roce 1996 konsorciem W3, ale v rámci zjednodušení jej uvádím naráz spolu s ostatními atributy). Názorněji to zobrazuje následující obrázek:
Rozměry elementu tedy spočítáme následovně (výška se spočítá obdobně):
Šířka pole pro text: definovaná, 200 px
Šířka odstavce = 200 px + (2 x 5 px) + (2 x 5 px) = 220 px
V roce 1995 se však atributy u elementu table v prohlížeči Netscape začínají počítat jinak, a to tak, že celkový rozměr elementu určují jak atributy width a height, tak i okraje (border a padding). Tomuto říkejme nevalidní model a opět to názorněji zobrazuje následující obrázek:
Rozměry elementu v tomto případě spočítáme následovně (výška se spočítá obdobně):
Šířka odstavce: definovaná, 200 px
Šířka pole pro text = 200 px - (2 x 5 px) - (2 x 5 px) = 180 px
Rozdíl je myslím patrný. V prvním případě jsme si určili šířku odstavce (šířku pole pro text) 200 px a poté zvolili nějaké okraje (to není pro nás důležité, text bude v odstavci širokém 200 px). V druhém případě však - i když také nastavíme šířku odstavce na 200 px - bude výsledná šířka pro samotný text menší (zde o 20 px), což má za následek různé zobrazení v prohlížečích a deformaci textu uvnitř odstavce. Ba navíc, rozdíl v celkové velikosti elementu (odstavce) činí celých 40 px.
Roku 1996 vydává konsorcium W3 doporučení, dle kterého by se mělo zacházet s atributy width, height, padding a border dle validního modelu, nicméně vcelku pozdě. V roce 1997 totiž vychází Netscape 4.0, který chtěl počítat rozměry stejně, jak je počítá u tabulek (aby se vše počítalo stejně). Používá tedy nadále nevalidní model. Ve stejném roce byl vydán Internet Explorer 4.0, který přebral implementaci z Netscape 4.0, používá tedy také nevalidní model. Důvody jsou zřejmé, webové stránky již byly vytvářeny dle nevalidního modelu a cílem bylo nabídnout zobrazení minimálně stejné, jako měl Netscape a na které už byli uživatelé zvyklí. Zde je nutné zdůraznit, že tržní podíl Netscape 4.0 byl jen o něco málo větší než podíl Internet Exploreru 4.0 a pouze cca 2 % uživatelů používala v této době jiný prohlížeč než Netscape nebo Internet Explorer!
Psal se rok 1998 a prohlížeče byly jednotné - používaly nevalidní model (poznámka: označení nevalidní je pouze pomůckou pro rozdělení a lepší pochopení modelů a jejich rozdílů). 98 % uživatelů* tedy používalo prohlížeče, které se chovaly jednotně a zobrazovaly stránky dle stejného modelu (dá se říct, že se tedy chovaly standardně). I přesto však konsorcium W3 ve stejném roce vydává druhé CSS doporučení: používat validní model.
* Malá poznámka: oněch 98 % není zcela přesných. Přesněji to bylo tak, že 98 % uživatelů používalo prohlížeč s nevalidním modelem (Netscape/IE) nebo vůbec žádným (tj. starší verze Netscape nebo IE, které CSS vůbec nepodporovaly).
V roce 1998 vychází Opera 3.5 a ta implementuje dle konsorcia W3 validní model. O rok později, v roce 1999, se Netscape dočká nového vykreslovacího jádra (Gecko) a implementuje také validní model. O další rok později (2000) vychází IE 5.0 a ten dovoluje nastavit webmasterům libovolný box model pomocí atributu box-sizing. V roce 2001 na svět přišel IE 6.0 a obsahoval dva vykreslovací režimy: standardní (validní model) a zpětně kompatibilní (nevalidní model neboli také quirk mód). V roce 2003 Opera 7.0 rozeznává také tyto dva režimy a implementuje po vzoru IE 6.0 atribut box-sizing (Mozilla implementovala stejný atribut pod názvem -moz-box-sizing v roce 2000). box-sizing je implementován i v IE 8.0.
Jak je vidno z předchozího odstavce, celou vinu nese konsorcium, které i přes jednotu prohlížečů prosazovalo validní model. Vznikla tak situace, kdy se minoritní moderní prohlížeče podřídily doporučení konsorcia (a patřičně se tím marketingově chválily - tu dobu máme všichni v paměti), a na druhé straně byl majoritní Internet Explorer, jehož vývojáře zajímala hlavně zpětná kompatibilita. Ač nechci nikoho obhajovat, Internet Explorer vinu nenese a byl tedy neprávem nařčen (a historicky znemožněn) z nedodržování standardů. Ostatním - minoritním - prohlížečům o nic nešlo, neměly co ztratit. Kdyby tehdejší boj vyhrál Netscape (s Internet Explorerem), situace by byla stejná a pouze by byl za viníka označen Netscape.
Historii jsem čerpal z Chamurappiho článku V kaskádovém ringu na jeho Webylonu.
Poznámka: netvrdím, že je dobré, když Internet Explorer zůstal u nevalidního modelu, ani zde nikoho neobhajuju - názor ať si každý udělá sám.
Identifikace problému
Problém tedy v dnešní době nastává u prohlížeče Internet Explorer 6 ve quirk režimu, ve kterém vykresluje dle nevalidního modelu. Internet Explorer 7 a 8 již standardně vykresluje ve validním režimu, pokud webmaster, manuálně uživatel nebo seznam stránek v kompatibilním zobrazení neřeknou jinak.
Problém se projevuje v počítání rozměru elementů (viz obrázky nahoře). U quirk módu (nevalidního modelu) se do šířky elementu započítává width, padding a border. U standardního režimu (validní model) se do šířky elementu započítívá pouze jeho šířka, tedy width.
Řešení
Řešením je donutit Internet Explorer (hlavně 6, lépe i 7 a někdy také Operu), aby použil standardní režim vykreslování, tedy validní režim. Toho docílíme tak, že:
- použijeme striktní DOCTYPE
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01">
nebo
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- a (kvůli chybě v IE 6) DOCTYPE umístíme hned na první řádek
- Pokud používáte XHTML: Petr Pixy Staníček dále upozorňuje: IE 6 obsahuje ještě jednu závažnou chybu: pokud XHTML dokument začíná XML deklarací (což by měl, pokud používá jiné kódování než UTF-8), IE to špatně pochopí, nepovažuje jej za striktní a zpracovává jej v quirk režimu. Tuto chybu ovšem již nelze napravit. Příklad:
Používáte-li XHTML, můžete využít pro IE 6 hack s podtržítkem, ten je však použitelný pouze tehdy, vykresluje-li IE 6 dokument v quirk režimu. Více na JakPsátWeb.cz: Hackování šířky a výšky.<?xml version="1.0" encoding="iso-8859-2"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
Více o režimech prohlížečů a kdy je který aktivován v článku DOCTYPE a režimy prohlížečů od Petra Pixyho Staníčka.
Matrjoška
Dalším řešením (obejitím problému s CSS box modelem) je použití Matrjošky. Nejedná se ruskou panenku, ale o způsob práce s paddingem. Řešení spočívá v tom, že text obalený elementem (např. DIVem), kterému jste chtěli nastavit padding, obalíte ještě jedním elementem (DIVem), kterému tento padding nastavíte. Lépe pochopitelné na příkladu. Místo původního jednoho DIVu:
<div style="width: 200px; padding: 5px;">
text
</div>
použijete následující dva DIVy:
<div style="width: 200px;">
<div style="padding: 5px;">
text
</div>
</div>
Výsledek bude totožný jak v quirk, tak i ve standardním režimu.
CSS reset
Pokud vytváříte webové stránky, kódujete šablony nebo programujete rozsáhlé webové projekty, měli byste resetovat výchozí CSS nastavení použitého prohlížeče, tzn. většinou nastavit všechny hodnoty na nulu, což vám dá jistou garanci, že vaše stránky nebo váš projekt bude ve všech moderních prohlížečích vypadat stejně. CSS reset je kousek kódu, který vám ulehčí život a udělá vaše stránky, projekty nebo webové aplikace mnohem kompatibilnější napříč všemi prohlížeči.
Identifikace problému
Každý prohlížeč má nastaveny výchozí hodnoty u každého elementu. To znamená, že např. Internet Explorer má nastavený větší padding u samotného elementu body než Firefox nebo Opera (pouze příklad). Dalším příkladem mohou být rozdílné okraje (margin) u odstavců. Výsledkem tedy je, že každý prohlížeč bude vaši stránku/projekt zobrazovat částečně odlišně, nenastavíte-li jim implicitně atributy jako border, line-height, margin nebo padding.
Řešení
Řešením je všechny známé elementy, které se chovají různě v prohlížečích, resetovat na společné hodnoty. Například vynulovat border, margin nebo padding. Nevytvářejte si vlastní, ale použijte raději webmastery osvědčené a uživateli vyzkoušené CSS resety, je jich celá řada, stačí si vybrat.
Nejpoužívanější CSS reset je od Erica Meyerse, jehož vždy aktuální verzi najdete na jeho stránce. Používejte ho však pouze na nově vytvářené stránky, jinak by se vám mohly ty stávající rozhodit a asi byste měli na delší dobu o zábavu postaráno. Obecně použití CSS resetu mohu vřele doporučit. Další typy CSS resetů naleznete na stránce help-developer.com.
/* v1.0 | 20080212 */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
/* remember to highlight inserts somehow! */
ins {
text-decoration: none;
}
del {
text-decoration: line-through;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: collapse;
border-spacing: 0;
}
To je prozatím vše, snad tento článek někomu pomohl blíže se seznámit s problematikou CSS box modelu, proč je s ním tolik problémů, jak je vyřešit a jak předejít většině dalších problémů při vytváření stylopisu. V některém z dalších článků se zaměřím na pár speciálních případů kolem CSS. Nakonec ještě přikládám, jak se vykreslují jednotlivé vrstvy - tedy hierarchii CSS box modelu. Originál vytvořil Jon Hicks.