Kaskádové styly (CSS) jsou moderním způsobem, jak formátovat HTML (ale i XHTML či XML) dokumenty. Idea, kterou vnesly standardy
W3C do práce s WWW stránkami, je v podstatě jednoduchá - oddělit strukturu a vlastní
obsah dokumentu od popisu jeho formátování. Velkým obloukem se tak možnosti HTML vrací zpět k dřevním principům, s
nimiž se na počátcích začínalo. Pokud na stránce ponecháme jen čistý obsah, jemuž je HTML značkami udělena přehledná struktura
(nadpis, odstavec, zvýrazněný text, adresa, odkaz, seznam atd.), takový dokument se velmi dobře automaticky zpracovává
(předávání informací, vyhledávače, indexování), je funkční ve všech prohlížečích (i v těch nejstarších a nejobyčejnějších)
a snadno se provádějí úpravy jeho vzhledu. Ten je popsán samostatně v CSS definicích, což umožňuje předat formátování
podle typu koncového zařízení (prohlížeč, tiskárna, hlasový výstup), škálovat styly podle možností prohlížeče (minimální
popis pro staré prohlížeče, sofistikované CSS pro prohlížeče moderní) a také snadno provádět úpravy (externí CSS soubor
společný pro celý web - jediná změna se promítne do všech stránek najednou).
Není cílem tohoto seriálu, ba ani tohoto dílu zabývat se problematikou kaskádových stylů. Zájemcům doporučuji jiné články,
v nichž se jí věnuji podrobněji:
DHTML a styly
CSS jsou kaskádové styly - tou kaskádou se zde myslí jakási hierarchie, kdy jsou obecnější definice přepisovány
a doplňovány definicemi konkrétnějšími, přesněji určenými. Tato hierachie je zde dvojí - první je z pohledu tzv. selektorů
- konkrétnější selektory mají přednost před obecnějšími. Selektor s ID (#prvek{ }) je konkrétnější než
selektor třídy (.trida{ }), ten má zase přednost před selektorem typu prvku (DIV{ });
kontextové selektory (#zahlavi .nadpis{ }) jsou zase konkrétnější než selektory bez kontextu (.nadpis{ })
atd. Přesný algoritmus najdete v popisu kaskádování.
Druhou částí hierarchie stylů, z pohledu DHTML tou důležitější, je odlišení podle toho, kde jsou CSS definice umístěny
(tzv. váha zdroje). Přednost mají pravidla, definovaná nejpozději - nejkonkrétnější jsou tak styly umístěné přímo
ve značce v atributu style, nejmenší priorotu mají styly importované z jiného souboru:
- Styly v externím CSS souboru, načtené do jiného CSS souboru (pomocí direktivy
@import)
- Styly načtené do stránky z externího souboru
- Styly definované ve stránce (pomocí značky
<style>)
- Style definované v atributu
style přímo ve značce (tagu) - např. <div style="...">.
Protože skripty mají omezené prostředky na zkoumání celé kaskády stylů, pro zjednodušení a zamezení konfliktům jsou při
tvorbě stromu dokumentu do objektů reprezentujících prvky stránky umístěny pouze ty poslední, nejkonkrétnější styly. DHTML
tak pracuje pouze se styly definovanými v atributu style v každém prvku na stránce. Změna nějaké CSS
vlastnosti v objektu odpovídá zapsání této vlastnosti do atributu style u prvku odpovídajícího tomuto objektu.
Styly definované dříve nejsou v objektech přímo dostupné - a i když existují možnosti, jak zjistit výsledný styl aplikovaný
na prvek, pracuje se vždy výhradně s atributem style. Příklad:
<style type="text/css">
#nadpis { color:red }
.odst { color:blue }
</style>
...
<h1 id="nadpis">Toto je nadpis</h1>
<p id="odst1" class="odst">text odstavce</p>
<p id="odst2" class="odst" style="font-size:10px">
druhý odstavec
</p>
Titulek #nadpis nemá z pohledu javascriptu (JS) definovány žádné CSS vlastnosti (atribut style
je prázdný), i když výše je pro něj definována vlastnost color:red. Pokud tedy najdeme objekt odpovídající
tomuto prvku, vlastnost odpovídající hodnotě color (objGet('nadpis').style.color) nebude mít
definovánu hodnotu. Stejně tomu bude u prvního odstavce odst1 - nemá atribut style, všechny
hodnoty CSS v objektu budou prázdné. U druhého odstavce je však už definována vlastnost font-size, proto
na odpodvídajícím místě v objektu bude přednastavena příslušná hodnota:
objGet('odst2').style.fontSize == '10px';
Teprve pokud u nadpisu změníme pomocí skriptu příslušnou vlastnost, bude mít definovánu hodnotu:
objGet('nadpis').style.color = 'yellow';
bude to stejné, jako by bylo v HTML napsáno:
<h1 id="nadpis" style="color:yellow">...
a nadpis bude zobrazen žlutě (tento styl je konkrétnější a má přednost před definicí color:red uvedenou výše).
Jistě jste již zaregistrovali, že zde v ukázkách používáme vlastnosti typu objekt.style.fontSize, které se
sice podobají vlastnostem CSS, nejsou však stejné. Důvod je prostý - vlastnosti CSS často používají "víceslovné"
názvy typu font-size, margin-left, border-top-style atd. Znaménko -
je ale v JS operátorem, nelze jej tedy použít v názvech proměnných. Proto byly pro účely DHTML zvoleny názvy podobné,
které ale respektují syntaxi jazyka - většinou přesně odpovídají názvům z CSS, jen pomlčky jsou odstraněny a následující
část názvu je uvozena velkým písmenem (např. fontSize, marginLeft, borderTopStyle
atd.). Jejich podrobný výčet je uveden níže.
Minule jsme si ukázali, jak se liší objekty ve stromu dokumentů v DOM prohlížečích
a v NN. Zatímco v DOM je základním typem objektu Element, obsahující objekt style, v NN je to
objekt JSSTag, který již style neobsahuje a vlastnosti spojené s CSS má uloženy přímo v sobě.
V následujícm seznamu jsou proto uvedeny vlastnosti CSS dvakrát - všimněte si také, že netscapovský JSSTag
neobsahuje zdaleka všechny vlastnosti CSS a je jich podstatně méně než v DOM - navíc je jejich použitelnost velmi diskutabilní
(viz poznámku pod seznamem).
Názvy vlastností v následujícím seznamu jsou sebevysvětlující, není tak nutné připojovat odpovídající vlastnost CSS.
| Objekt JSSTag (Netscape) |
| vlastnosti (související s CSS): |
| background, backgroundColor, backgroundImage, borderBottomWidth, borderColor, borderLeftWidth, borderRightWidth,
borderStyle, borderTopWidth, clear, clip, color, display, fontFamily, fontSize, fontStyle, fontWeight, height,
left, lineHeight, listStyleType, marginBottom, marginLeft, marginRight, marginTop, paddingBottom, paddingLeft,
paddingRight, paddingTop, textAlign, textDecoration, textIndent, textTransform, top, verticalAlign, visibility,
whiteSpace, width, zIndex |
| metody: |
| borderWidths(), margins(), paddings(), rgb() |
Důležitá poznámka: v NN jsou tyto vlastnosti určeny pouze k zápisu, a to pouze v sekci <head>
a před načtením celého dokumentu - nelze je číst, ani měnit po ukončení načítání těla dokumentu. Což, jak je zřejmé, zcela
degraduje použití NN pro účely DHTML.
| Objekt Element.style (DOM) |
| vlastnosti: |
|
Přehled vlastností je v samostatné tabulce,
včetně jejich podpory v různých prohlížečích
Pozn. 1: Seznam obsahuje všechny známé vlastnosti objektu Element.style,
včetně nestandardních. Některé z nich jsou proprietární a podporované tak např. pouze v prohlížečích MSIE.
U každé vlastnosti je to uvedeno - pokud pro vás není zřetelná standardnost z uvedené podpory v DOM či CSS,
pro jednoduchost lze za strandardní považovat ty vlastnosti, které jsou podporovány jak v MSIE, tak i v NN
6.
Pozn. 2: Povšimněte si, že prohlížeč Opera, jehož podpora CSS a dalších standardů je jinak vynikající,
má pouze velmi sporé možnosti DHTML - počet podporovaných vlastností objektu style je vskutku
minimální. Podle vyjádření výrobce tohoto prohlížeče lze očekávat širší podporu DOM a DHTML až v pozdějších
verzích.
|
| příklad: |
|
obj = objGet('jmeno') // obj je typu Element
obj.style.backgroundColor = '#FF9933';
obj.style.width = '90%';
obj.style.margin = '1em 2em 1em 0');
|
S touto znalostí již můžeme přistoupit k přípravě další funkce - nastavení obecné vlastnosti stylu. Bude to celkem jednoduché
- jen bude vhodné otestovat, zda náš objekt má vlastnost style. Pokud ne, může se jednat o objekt typu JSSTag
(Netscape), nebo o prohlížeč s malou podporou DHTML, který styly vůbec nepodporuje. Pro každý případ naši funkci vybavíme
návratovou logickou hodnotou (false|true), která nám řekne, zda se vlastnost podařilo definovat, či nikoli.
Nezapomeňte, že minule jsme si připravili půdu pro to, že všem našim funkcím
můžeme předat jak objekt, tak jen jeho jméno - budeme toho tedy do důsledků využívat, později zjistíme, jak je tento přístup
pohodlný. Novou funkci nazveme objSetStyle, česky objNastavStyl s parametry obj,
prop a val. Tato funkce nastaví vlastnost prop v objektu obj na hodnotu
val a vrátí hodnotu true, pokud se to zdařilo - a false, pokud nikoli.
V DOM verzi bude naše funkce vypadat takto:
// DOM verze:
function objSetStyle (obj,prop,val) {
var o = objGet(obj);
if (o && o.style) {
eval ('o.style.'+prop+'="'+val+'"');
return true;
}
else return false;
}
var objNastavStyl = objSetStyle;
Počáteční objGet nám předaný parametr převede vždy na objekt - pokud je obj řetězcem, najde objekt
odpovídajícího jména (ID), jinak (pokud je obj objektem) jej pouze vrátí zpět (o=obj). Pokud
objGet objekt našlo (o existuje) a navíc obsahuje o.style (což standardně obsahuje),
uložíme do vlastnosti o.style.prop hodnotu val - nejprve vytvoříme příkaz jako řetězec- např.
při prop='color' a val='red' vytvoříme řetězec o.style.color="red" -
a ten poté pomocí eval vyhodnotíme (obsah řetězce se provede, jako by tento text byl napsán přímo v kódu).
Hodnoty vlastností style jsou vesměs typu řetězec (string), proto přidáváme kolem hodnoty val
úvozovky.
V "univerzální" verzi bychom mohli ještě přidat nastavení stylu pro JSSTag. Již jsme si ale výše
řekli, že CSS vlastnosti v NN nejsou pro DHTML použitelné (nelze je měnit po načtení dokumentu), takže umožnit
změnu vlastností nějakého objektu by bylo zbytečné. Funkci tedy ponecháme i v této verzi stejnou, budeme si pouze pamatovat,
že v NN nic neprovede, vlastnosti CSS zde měnit nemůžeme. Jedinou výjimkou je chování prvků <layer>
- ty jsou však již zrušeny jak v nových verzích Netscapu, tak i v HTML, nemá proto smysl se jimi dále zabývat. Nejlepší
je prostě počítat s tím, že NN 4.x je prohlížeč nepodporující DHTML.
Pozn.: Měli bychom si vždy dát pozor, abychom nastavovali jen vlastnosti, které prohlížeč podporuje. Každý objekt
má všechny známé vlastnosti již vytvořeny, pouze nemají definovánu hodnotu, dokud není nějaká přiřazena. Pokud bychom
nastavili nějakou prohlížeči neznámou vlastnost, přiřazení se provede (vytvoří se nová vlastnost objektu style),
ale na stránce to nebude mít žádný efekt - např. o.style.bflmpsvz='10' vytvoří novou vlastnost bflmpsvz
s hodnotou "10", která však nebude mít žádný vliv na formátování stránky.
Teď již je jen na nás, abychom tuto funkci používali korektně. V parametru obj je nutné předat existující
objekt, odpovídající nějakému prvku na stránce, nebo ID takového prvku. V prop potom předat existující vlastnost
(viz seznam vlastností pro DOM i NN výše). A v neposlední
řadě vložit korektní hodnotu val - tak, aby odpovídala specifikacím CSS - především nezapomenout uvést jednotky
tam, kde jsou předepsány:
Špatně: objSetStyle('zahlavi','width',100);
Špatně: objSetStyle('zahlavi','width','100');
Správně: objSetStyle('zahlavi','width','100px');
Ukázky k tomuto dílu:
ukázka 1 - příklad nastavení vlastností objektu
ukázka 2 - test funkce objSetStyle()
Použitelnost prvků zmíněných v tomto díle:
JSSTag.vlastnost
- pouze Netscape 4.x, od verze 6.0 již nepodporováno. Nelze je číst, pouze zapisovat, navíc jen v sekci
<head>
a ještě před ukončením načítání dokumentu.
Element.style.vlastnost
- viz tabulka vlastností
DHTML knihovna ke stažení:
| Číslo verze: |
0.4 (pro přehlednost číslujeme verze shodně s díly seriálu) |
| Stažení DOM verze: |
dhtml_0_4_dom.js |
| Obsah (anglické názvy) |
objGet(), objSetStyle() |
| Obsah (české názvy) |
objNajdi(), objNastavStyl() |
| Stažení "univerzální" verze: |
dhtml_0_4_uni.js |
| Obsah (anglické názvy) |
objGet(), objSetStyle() |
| Obsah (české názvy) |
objNajdi(), objNastavStyl() |
Staníček Petr
|