Už je hezky, odložte své tabulky 2
V minulé části jsme si ukázali výhody a především nevýhody, které přináší používání tabulek k formátování
WWW stránek. Jako nástroj, který je nejen nahradí, ale přináší i mnoho daleko mocnějších nástrojů k formátování, jsme si
představili kaskádové styly (CSS). Nikoli jako nástroj všemocný a samospasitelný - předvedli jsme si i některé jeho nedostatky,
pramenící především z nekompatibility některých prohlížečů, a přiblížili si několik základních tipů, jak si přechod na
CSS usnadnit. Dnes budeme pokračovat praktickými ukázkami toho, jak pomocí CSS vytvořit některé konstrukce, doposud řešené
jen pomocí tabulek.
Stručný obsah článku:
- Opáčko na úvod - optimalizovat, nebo neoptimalizovat?
- Tabulky vs. CSS poprvé: tabulky
- Tabulky vs. CSS podruhé: zarovnávání
- Tabulky vs. CSS potřetí: svislé zarovnávání
- Tabulky vs. CSS počtvrté: rámečky
- Zcela zásadní intermezzo o rozměrech
- Tabulky vs. CSS popáté: Jednoznačné vítězství. Kontumačně.
- Tabulky vs. CSS pošesté: Impérium vrací úder
Opáčko na úvod - optimalizovat, nebo neoptimalizovat?
V závěru minulého dílu jsem vám doporučil prohlédnout si tuto ukázku.
Pokud máte prohlížeč, který podporuje CSS2, uvidíte, že možnosti formátování pomocí stylů jsou skutečně velmi bohaté a
pestré. Jistě byste dokázali vymyslet desítky dalších možností, jak zajímavě "zalomit" tuto jednoduchou stránku.
Na druhé straně, pokud takový prohlížeč nemáte, máte prostě smůlu. Anebo - nemáte?
Kompatibilita a ošetření všech možných prohlížečů je jedním z hlavních dilemat webdesignéra dneška. A čím sofistikovanější
design své stránky připravíte, tím marnější bývají pokusy doladit stránku pro co největší soubor browserů. A je nutno
říci, že většinou to končí rezignací typu "tohle stejně nikdo nepoužívá" a takzvanou "optimalizací"
pro MSIE pod Windows. Co na tom, že jinde jsou stránky nejen nepěkné, ale mnohdy dokonce zcela nečitelné a nepoužitelné.
Co na tom, že handicapovaní čtenáři si s vaší stránkou ani neškrtnou. Co na tom, že vyhledávače se v ní nevyznají. Minule
jsme si ukázali - snad dostatečně -, že lepším a slušnějším řešením je dobře strukturovat stránku a poskytnout kvalitní
design těm prohlížečům, které jej stejně kvalitně dokáží zobrazit. A všechny ostatní smůlu nemají - naopak, mají štěstí.
Můžete si totiž být stoprocentně jisti, že všechny browsery zobrazí vaši stránku čistě, korektně, čitelně a přehledně.
Každý prohlížeč, i ten nejhloupější, dobře a s přehledem zobrazí stránku s čistým, stupidním HTML 1 - což je přesně to,
co vám vznikne, když obsahu stránky udělíte pouze strukturu a veškeré formátování uděláte vedle, v souboru se styly. Prohlížečů,
které podporují CSS, je dnes mezi uživateli od 75-90% (podle toho, jak moc do hloubky možností CSS půjdete). S tou menšinou
se vážně netrapte. Oni buďto dobře vědí, proč používají právě tak jednoduchý browser, anebo jej - spíše dříve než později
- upgradují.
A teď už vzhůru dolů k tématu.
Tabulky vs. CSS poprvé: tabulky
Kdyby vám někdo tvrdil, že s CSS už tabulky nepotřebujete a že "slušně" udělaná stránka nemá obsahovat jedinou
značku <TABLE>, vezměte na něj potěh, zažeňte jej na dvorek a vypusťte psa. Je to blb a nic jiného si nezaslouží
(a nemyslím toho psa). Kdyby byly tabulky k ničemu, asi by byly ze specifikace HTML vypuštěny, jako mnoho jiných, skutečně
přežitých značek. Namísto toho byly v nové verzi HTML 4 ještě více rozšířeny, posíleny a doplněny mnoha užitečnými funkcemi.
Proč to?
Nenechejte se zmást. Tabulky jsou jedna věc a formátování věc druhá. Ano, formátovat stránku pomocí tabulek už je pasé
a dá se dělat lépe a příjemněji pomocí stylů. Ale tabulky jako takové, die Tabellen an sich, nahradíte něčím jiným
jen stěží. A hlavně není důvod. Chcete-li na stránce prezentovat hospodářské výsledky své firmy za minulý měsíc, výsledky
fotbalového turnaje typu každý-s-každým nebo třeba ceny výrobku v různých variantách, nebude nic vhodnějšího, než použít
tabulku. Jak jsem uvedl, tabulky ve 4. verzi HTML přinášejí mnohá rozšíření a vylepšení - jejich popis je však tématem
na samostatný článek. Ale nebojte se jich a nesnažte se zbytečně nahradit tabulky něčím jiným, kostrbatým - tam, kde to
není nutné.
Tabulky vs. CSS podruhé: zarovnávání
Často se používá tabulek kvůli zarovnání textu - doleva, doprava, na střed horizontálně i vertikálně. V CSS má každý kontejner
vlastnost text-align, která určuje způsob zarovnání jeho obsahu - a to podle hodnoty tohoto atributu, která je
left, right, center nebo justify. Poslední hodnotu v tabulkách nenajdete: justify zajišťuje, že text
v boxu bude natažen od levého kraje k pravému, stejně jako to znáte z textových editorů nebo DTP programů. Záleží ovšem
na prohlížeči, jak text do kraje dotáhne - většina to pohříchu dělá pouze roztahováním mezislovních mezer, takže v užší
sazbě s delšími slovy to může dopadnout velmi tristně.
Nejčastěji a nejjednodušeji se tato vlastnost aplikuje u značky odstavce <P>, kdy v souvislém textu odstavcům podle
potřeby definujeme způsob zarovnání. Následuje jednoduchá ukázka zarovnání odstavců. (Ve všech ukázkách budu pro názornost
vkládat CSS definice přímo do kódu stránky. V reálu je ale lepší - jak jsme si ukázali minule - ukládat styly do samostatných
souborů.)
<STYLE type="text/css">
.doleva { text-align: left}
.doprava { text-align: right}
.stred { text-align: center}
.uplne { text-align: justify}
...
<p class="doleva">...</p>
<p class="doprava">...</p>
<p class="stred">...</p>
<p class="uplne">...</p>
Příklad je zde
To je ale pouze text, resp. "plovoucí" (inline) objekty. Chceme-li zarovnat komplexnější objekty, přestává
legrace. Doleva či doprava není obvykle problém, ale to nejčastější a nejpoužívanější, tedy vycentrování - to je už horší.
Ne tedy v CSS podle specifikace, tam je to prosté. Horizontální vystředění objektu zajistíme, pokud mu nastavíme automatické
okraje, tj. margin: auto. Bylo by to pěkné, kdyby to fungovalo. Bohužel, většina prohlížečů zatím tuto funkci
nemá implementovánu. Dá bůh, že v příštích verzích to již bude napraveno. Nezbývá proto, než tento nedostatek nějak obejít
- už jsme si řekli, že v CSS se všechno dá udělat několika různými způsoby: když jeden nefunguje, zkusíme jiný.
Nejprostší způsob, pokud chceme zarovnat vše na stránce, je využít faktu, že celý dokument, tedy <BODY> je také kontejner.
Lze mu tedy přiřadit text-align: center. A nechceme-li zarovnat na střed celou stránku, ale jen její část,
můžeme si vytvořit kontejner se zarovnáním na střed, kterým "obalíme" tu část, která se má centrovat. A to ve
většině prohlížečů funguje - ačkoli by správně nemělo, neboť parametr text-align má mít vliv pouze na plovoucí
(inline) objekty - tedy nikoli na bloky. V Mozille už to je odstraněno, ale margin: auto tam
ještě není. Takže v Mozille zatím nic nevycentrujete...
#obalka { text-align: center }
#obsah { width: 50%; margin: auto }
...
<DIV id="obalka">
<DIV id="obsah">
Text...
</DIV>
</DIV>
Příklad je zde
Tabulky vs. CSS potřetí: svislé zarovnávání
Tak to je - napadá mě spousta slov, ale žádné slušné - to je ...ehm... problém. Obdobně jako u horizontálního zarovnávání
platí pravidlo pro margin: jsou-li margin-top i margin-bottom oba shodně auto, mají mít stejnou velikost,
prvek by tedy měl být vykreslen ve středu omezujícího kontejneru. Bohužel, už tradičně to nikde nefunguje. Navíc zde není
ani žádná finta podobná horizontálnímu text-align. Co z toho plyne? Nic menšího, než že budeme-li opravdu nutně
muset něco vertikálně vystředit, musíme zatím stále použít tabulku - tedy značku <TABLE>, která jediná má vertikální
zarovnávání. Až bude v prohlížečích implementován ten nešťastný margin: auto, můžeme zahodit i tuto berličku.
Naštěstí svislé centrování tak často nepotřebujeme.
Tabulky vs. CSS počtvrté: rámečky
A teď pro změnu něco veselejšího. Doposud byly v HTML k dispozici jen ošklivé jakoby 3-D rámečky tabulek (<TABLE border="n">).
Pokud jsme chtěli třeba tenký černý rámeček, bylo nutné to obejít vložením dvou tabulek do sebe - vnější černá s jednobodovým
cellpadding, vnitřní bílá. O nějakém sofistikovanějším rámování ale nemohla být ani řeč. Leč hurá: jestli CSS něco umí
opravdu dobře, tak jsou to rámečky.
Každý blok může mít vlastnost border (border-top, -right, -bottom a -left) s množstvím různých
parametrů. Není problém orámovat box čtyřbodou tečkovanou linkou, není problém vytvořit zapuštěné 3-D tlačítko, není problém
vytvořit linku vlevo podél odstavce. Nastavit lze každou ze čtyř stran rámečku samostatně. K dispozici máme:
- Šířku rámečku (border-width); může být thin, medium, thick (tenká, střední, tlustá) nebo nabývat libovolné
hodnoty číslo+jednotka (1px, 0.5cm atd.)
- Barvu (border-color); libovolná barva definovaná buďto jménem (black, silver, red atd.) nebo číselně (#FFD860)
- Styl (border-style); může být solid (plná čára), dotted (tečkovaná), dashed (čárkovaná)
double (dvojitá čára), groove a ridge (3D vystupující či zapuštěný rámeček) a inset nebo
outset (3D vystupující nebo zapuštěný celý blok - jako u tlačítek) - a pro úplnost ještě skryté rámečky hidden
a none. Ne všechny prohlížeče už umí všechny typy rámečků - např. MSIE pod Windows neumí tečkovanou ani čárkovanou
čáru... Ale situace se stále zlepšuje.
S tím už se dají dělat lecjaké divy. Příklad je zde
Tip: Využívejte tzv. "shorthandů" - tedy zkratek, které CSS nabízí k zestručnění definic stylů. Místo
postupného definování border-left-style: ..., border-left-color: ..., border-top-style: ... atd. můžete použít
společnéborder-style, border-color, které definují danou vlastnost pro všechny strany současně. Navíc je zde ještě
kratší zkratka border, která nastaví pro všechny strany všechny vlastnosti najednou - např. border: 1px solid
black. (Neplatí to jen pro border, shorthandy má v CSS většina vlastností).
Tip 2: Často je navíc praktické spojit použití zkratek s kaskádováním CSS - chceme-li např. boxu nastavit nahoře,
vpravo a dole černý jednobodový rámeček a vlevo čtyřbodový červený, máme dvě možnosti - buďto definovat rámeček pro každou
stranu zvlášť, nebo nadefinovat nejprve všechny nejednou a potom jednu stranu předefinovat:
{... border: 1px solid black; border-left: 4px solid red } - a je to. Prohlížeč si nejprve všechny definice setřídí,
z těch, které popisují stejnou vlastnost, ponechá jen jednu (podle priorit a pravidel kaskádování) a teprve pak objekt
vykreslí, úplně stejně, jako kdybychom definovali jednu vlastnost po druhé.
Zcela zásadní intermezzo o rozměrech
Už při hraní si s rámečky můžete narazit na problém, který je příčinou většiny potíží s CSS a který vás bude provázet při
stylování stránek od prvního k poslednímu okamžiku. Ale předem upozorňuji, že si hned ukážeme jednoduchou fintu, jak na
něj vyzrát. Jak jsme si už předvedli, kaskádové styly toho umí hodně - to prohlížeče mají potíže s jejich implementací.
Že každý podporuje jinou část standardů CSS2, by zas tolik nevadilo, protože by se dal najít vhodný průnik, tedy taková
část CSS, kterou zvládnou všechny vhodné prohlížeče. Problém je v tom, že to každý dělá jinak. Přesněji řečeno, každý
si upravuje definice CSS po svém a dělá tu svou chybu jiným způsobem. Ale zatím žádný to, co umí, nedělá zcela bez chyby.
A tou největší chybou je špatné počítání rozměrů objektů. Specifikace CSS říká, že každý blok tvoří několik do sebe postupně
vnořených oblastí: nejvíce uvnitř je samotný obsah bloku, kolem něj je oblast padding (odstup od rámu),
kolem něj border (rámeček) a kolem něj (průhledná) oblast margin (odstup od okolí) - viz první obrázek.
Šířka/výška bloku pak udává šířku/výšku obsahu, ostatní rozměry se k ní musí přičítat. Celková šířka plochy,
kterou box zabírá, je tedy width+padding+border+margin. Ale hned ten nejpoužívanější prohlížeč, tj. MSIE pod Windows,
toto pravidlo ignoruje. Počítá do šířky/výšky i velikosti padding a border - přičítá se pouze hodnota margin.

Jiné prohlížeče to mohou dělat zase jinak - každopádně jsme tady u pudlova jádra. K dispozici máme
formátovací nástroje, pomocí nichž umístíme objekty na stránce na pixel přesně, ale prohlížeče, které normy nepochopily,
nám je zase rozhodí (ale na pixel přesně). Nezáleží přitom na tom, zda jsou objekty na stránce plovoucí, absolutně či
relativně pozicované, zda rozměry udáváte v pixelech, bodech, centimetrech nebo procentech. Pokud odladíte stránku v MSIE
pod Windows, v ostatních prohlížečích budou všechny objekty o padding a border větší, než jste chtěli. A naopak.
Lze tomu zabránit? Popravdě řečeno, nelze - leda byste se snažili přesvědčit výrobce svého prohlížeče,
aby dělal svou práci pořádně. Ale i když té chybě nezabráníme, můžeme ji obejít. Určitě už vám došlo, že pokud je padding
a border nulový, bude blok ve všech prohlížečích zobrazen stejně, chyba se neprojeví. K tomu přidám další informaci: když
bloku neurčíte rozměr, použije se výchozí hodnota auto, což v případě width znamená, že blok bude vykreslen
v maximální možné šířce. Když tyto dva fakty spojíme, máme řešení:
Pokud chcete vytvořit blok přesně dané šířky, který bude vykreslen správně ve všech (korektně i chybně
počítajících) prohlížečích, nastavte mu v CSS hodnoty padding: 0 a border: 0. Tím zajistíte, že
se vykreslí v přesné šířce. Dovnitř něj pak umístěte druhý blok, jemuž již nenastavíte žádnou šířku (width: auto),
ale padding a border již můžete dát libovolný - tento vnitřní blok bude ve všech browserech roztažen na maximální šířku
tak, aby zcela zaplnil vnější omezující "obálku".
#obalka {width: 350px; padding: 0 }
#obsah { padding: 8px; border: 2px solid black; background: white}
...
<DIV id="obalka">
<DIV id="obsah">
Obsah...
</DIV>
</DIV>
Příklad je zde - v levém sloupci jsou ukázky bloků s různými okraji a rámečky při
stejné hodnotě width; ve druhém pak shodné bloky, bez určení šířky, které jsou každý uzavřen v "obálce",
která šířku definuje (pro názornost mají obálky nastavený červený rámeček). Všimněte si, že v pravém sloupci jsou nyní všechny
boxy stejně široké bez ohledu na to, jak mají nastavené okraje a rámečky a jaký použijete prohlížeč. Což se o levém sloupci
rozhodně říci nedá.
Tabulky vs. CSS popáté: Jednoznačné vítězství. Kontumačně.
Co je na CSS nejsilnější? Rozhodně absolutní pozicování. Tak silný nástroj webdesignéři doposud v rukou neměli a během
usilovného rozřezávání obrázků a slepování tabulek závistivě pošilhávali ke kolegům v DTP. Nyní se situace obrátila -
sám po dlouholetých zkušenostech v DTP bych za možnosti kaskádových stylů v DTP platil zlatem (ačkoli bych řekl, že nebude
trvat tak dlouho, než i v této oblasti zavládne éra XML a všechny podobné prosby tak budou vyslyšeny). Můžete být opravdový
expert a tabulky sekat na stránky jen tak z voleje přímo v HTML - to, co dokáže CSS s absolutním pozicováním, však nezvládnete
ani náhodou. Pokud chcete vytvořit stránku pevně daných rozměrů, s přesně usazenými prvky, vítězí CSS na celé čáře a tabulky
odcházejí schlíple bez boje.
CSS vám umožňuje jakýkoli prvek na stránce umístit na bod přesně do místa, kde jej chcete mít. Navíc ve spojení s nějakým
skriptovacím jazykem (Javascript, VBScript, ECMA) nabízí takové možnosti dynamiky do vašich stránek, které jste dosud
mohli tvořit pouze ve flashi - zde si ovšem vystačíte pouze se samotným prohlížečem a řádově menším objemem dat. Nevýhodou
je pak to, že začnete-li stránku pozicovat absolutně, musíte ji tak udělat celou. Plovoucí a pozicované bloky spolu nijak
nekomunikují a nemůžete tedy říci: "Blok_X bude umístěn tam, kde skončí blok_Y, podle toho, kolik v něm bude textu..."
Bohužel. Něco takového dokážete pouze se skripty, kdy za chodu spočítáte velikosti objektů a pak podle nich přizpůsobíte
pozice objektů dalších. Záměrně se zde nebudu zmiňovat o relativním pozicování, které by podobné problémy mohlo řešit.
Je však poměrně složité - nejvíc asi pro programátory prohlížečů, které je zpracovávají velmi obtížně a často zcela nepredikovatelně.
Musíme si zřejmě počkat, s čím přijdou v nových verzích. Do té doby je vhodné používat relativní pozicování pouze pro
posouvání plovoucích (inline) prvků.
Absolutní pozicování je naopak velmi jednoduché. Každý blok kromě vlastností width a height
může mít ve spojení s atributem position: abslolute i vlastnosti left, right, top a bottom.
Ty určují vzdálenost levého, pravého, horního, resp. spodního okraje bloku od nadřazeného kontejneru. Pokud prvek není
vložen do jiného bloku, vztahují se tyto vzdálenosti k okrajům okna prohlížeče (BODY je také kontejner). Okrajem prvku
se přitom rozumí vnější hrana oblasti margin - má-li tedy nějaký blok nastaveno left: 10px, margin: 10px
a padding: 10px, bude začínat 10px od levého okraje, pak bude následovat 10px margin a 10px padding - samotný obsah
tedy bude vzdálen od levého okraje 30px.
Pokud ještě podle tipu v minulé kapitole zajistíte přesné rozměry bloků, máte k dispozici stránku jako dětskou skládanku
- každý prvek umístíte na libovolnou pozici v okně, bez ohledu na to, na kterém místě HTML kódu leží. To je velký přínos,
především v souvislosti s tím, o čem jsme již několikrát mluvili: nejprve vytvoříte strukturovaný dokument, který je čitelný
a přehledný bez jakéhokoli formátování a pak, jen pomocí CSS rozmístíte jednotlivé části na stránce tak, jak vám vyhovuje.
Např. menu, které je až na konci stránky, umístíte úplně nahoru; obsah, který je naopak na začátku kódu skryjete úplně
a necháte jej rozbalit po kliknutí na tlačítko "Obsah stránky". Je to velmi, velmi příjemné.
Ukázku možností formátování
i absolutního pozicování jsem zde již několikrát nabízel.
Tabulky vs. CSS pošesté: Impérium vrací úder
A je to tady. Nejčastější protipříklad, co CSS neumí příliš dobře: vícesloupcová "sazba".
Nemyslím tím obdobu klasické novinové sazby, kdy text plynule přetéká z jednoho sloupce do druhého - to v HTML nejde udělat
žádnými prostředy. Mám na mysli známý třísloupcový design stránky, jímž je u nás vyvedený každý druhý zpravodajský server
a každý první portál. V levém sloupci menu, v prostředním články, v pravém další informace. To prostě bez tabulek nejde...
Že ne? Je to hlavní omyl odpůrců CSS. Jde to relativně dobře - se všemi výhodami, které má CSS (strukturovaná stránka,
rychlé načítání, zobrazení bez čekání, než se načtou všechny sloupce). Navíc s mnoha výhodami, které pomocí tabulek uděláte
celkem složitě (mezisloupcové linky, obrázek na pozadí pouze u jednoho okraje či opakovaný jen v jednom směru, různé odstupy
od rámu atd.). Na druhé straně jsou zde i nevýhody - přesněji řečeno jedna: jen velmi obtížně dosáhnete toho, aby všechny
sloupce byly nataženy na výšku toho nejdelšího - což je u tabulek naopak jediná možnost. Pokud to pro vás není zrovna
kritický bod, nic vám nebrání udělat si krásnou vícesloupcovou sazbu jen pomocí CSS.
Pochopitelně, pokud použijeme absolutní pozicování, nemáme s libovolným počtem sloupců žádný problém. Má to ale nevýhodu,
že buďto musíme stanovit přesnou výšku sloupců, nebo, ponecháme-li ji plovoucí, můžeme jen odhadovat, jak nízko pod sloupce
umístit další prvky. (Na druhé straně zase můžeme každému sloupci pro případ delšího textu dát scroll-bary, což může být
užitečné.) Příklad je zde.
Většinou ale chceme, aby sloupce měly výšku přizpůsobenu svému obsahu, jehož délku většinou předem neznáme. Toto je možné
řešit poměrně jednoduchým způsobem, a to tak, že všechny sloupce uděláme plovoucí (float: left, float: right)
- stejně jako se v HTML dělají obtékané obrázky - a tyto sloupce budou "obaleny" omezujícím boxem. Tím zajistíme,
že na stránce bude vedle sebe v jednom rámečku několik boxů, přičemž obálka bude mít výšku nejvyššího z nich.
Příklad 2 a Příklad 3.
Není třeba se ale držet zažitých (přežitých?) zvyklostí - kolikrát jsem již na našich portálech viděl, že obsah sloupce
v půlce stránky skončí a až do konce zabírá pouze místo prázdnou, jednobarevnou plochou. Pokud bychom se tomu chtěli vyhnout
a prostor na stránce tak využít lépe, poskytují nám k tomu i ty "nedokonalé" CSS plovoucí sloupce dokonce výhodu.
Stačí totiž, když uděláme plovoucí pouze krajní sloupce a za ně v kódu umístíme obsah "sloupce" prostředního,
již bez obtékání. Ten bude krajní sloupce obtékat a až jejich obsah skončí, bude pokračovat v celé šíři sazby.
Příklad 4 a Příklad 5.
Pokud však nutně potřebujete, aby všechny sloupce byly ve své barvě protaženy na stejnou výšku, budete muset použít tabulku
- postačí však velmi jednoduchá tabulka, bez rámečku a pozadí. Uvnitř políček tabulky již můžete zase pracovat s jednoduchým
strukturováním a vše formátovat jen pomocí CSS - stejně jako tabulku samotnou: políčka tabulky jsou sama o sobě bloky
a z hlediska CSS je možné je formátovat stejně jako běžný <DIV>. Pouze již musíte myslet na to, jak se stránka zobrazí
bez CSS. Příklad 6
Jestli to ale není nutné, poslední variantě se snažte vyhnout. Pokud už si nevzpomínáte proč a o co všechno tím přijdete,
přečtěte si znovu první díl tohoto článku.
Staníček Petr
|