Aktivní tlačítka pomocí CSS — ano či ne?
Marek Prokop, vydáno/aktualizováno: 29.10.2001/13.07.2003
Čtenář Jan Bönisch nám poslal zajímavý tip, jak udělat tlačítka, která se mění při najetí myší (tzv. rollover), bez použití JavaScriptu. Zároveň se ptá:
"Chtěl bych znát Váš názor na toto použití, jestli se mohou vyskytnout nějaké problémy a pod."
Zkusme se tedy na jeho řešení podívat podrobněji. Úvodní příklad stránky naleznete na adrese
www.sovavsiti.cz/samples/bonisch/index.htm
Ve stejném adresáři pak je i soubor definice stylů style.css.
Nejprve popíšu princip řešení. Ve vlastní stránce je menu tvořeno šesti průhlednými obrázky o stejné velikosti, naskládanými těsně pod sebe a jednotlivě uzavřenými do prvku <a>
. Každý prvek <a>
má definovánu unikátní třídu (class) CSS.
<a class="m1" href="#1">
<img src="s.gif" width="190" height="36" border="0">
</a><br>
<a class="m2" href="#1">
<img src="s.gif" width="190" height="36" border="0">
</a><br>
...
<a class="m6" href="#1">
<img src="s.gif" width="190" height="36" border="0">
</a><br>
V definici CSS je pak pro každou třídu m1 až m6 definováno toto:
a.m1 {background: url("m1.jpg");}
a.m1:hover {background: url("m1a.jpg");}
a.m2 {background: url("m2.jpg");}
a.m2:hover {background: url("m2a.jpg");}
...
a.m6 {background: url("m6.jpg");}
a.m6:hover {background: url("m6a.jpg");}
Prostudováním samotného kódu možná odhalíte drobnou, dalo by se říci stylovou chybu. Místo třídy (class) by určitě bylo lepší zvolit id. Třída totiž může být použita opakovaně, pro více prvků, kdežto id pouze pro jeden jediný prvek v celém dokumentu, což je právě tento případ. Proto je zde id lepší.
Pokud si příklad otevřete Internet Explorerem (zkoušel jsem 5.0, ale stejné asi bude i 4 a vyšší), je zdánlivě vše v pořádku. Oproti tradičnímu řešení rollover efektu se objeví jediná vada — při prvním najetí myší na jednotlivé položky menu vlevo chvíli trvá, než se objeví druhá verze obrázku s vysvíceným nápisem. Obraz na chvíli problikne. To je proto, že druhá sada obrázků ještě není ze serveru načtena, zatímco při řešení JavaScriptem se obvykle načte předem hned v úvodu stránky (tzv. preload).
Horší situace ovšem nastane, když si stránku otevřete prohlížečem Opera. V tom případě zjistíte, že celé menu zmizelo a místo se něj se zobrazuje jen prázdná žlutá plocha. Proč tomu tak je? Problém je v tom, že Opera neumí pomocí CSS definovat pozadí řádkových (inline) značek (tagů) a tedy ani značky <a>
.
Ještě horší situace však nastane, pokud se na stránku podíváte textovým prohlížečem, nebo prohlížečem s vypnutými obrázky. Uvidíte pak přibližně toto:
IMAGE
IMAGE
...
IMAGE
Částečně jsem se pokusil tento problém napravit v příkladu index2.htm a jemu odpovídajícímu souboru stylů style2.css. Změna spočívá v tom, že je každý jednotlivý obrázek uzavřen do prvku <div>
takto:
<div id="m1">
<a href="#1">
<img src="s.gif" alt="Sestava">
</a>
</div>
Zároveň jsem obrázkům přidal nezbytný (a v původním příkladu chybějící) atribut alt
a ostatní atributy přesunul do definice stylů. Ta nyní vypadá pro každou položku menu takto:
#m1 {
background: #ffffc0 url("m1.jpg") no-repeat;
}
#m1 a:hover {
background-image: url("m1a.jpg");
}
a pro všechny položky menu ještě jednotný rozměr obrázků:
#m1 img, #m2 img, #m3 img, #m4 img, #m5 img, #m6 img {
width: 190px;
height: 36px;
border: none;
}
Co se mi těmito úpravami podařilo změnit?
V IE je vše při starém. Menu se zobrazuje podle záměru autora jen s drobnou kosmetickou vadou — výše zmíněným probliknutím při načítání překryvného obrázku.
V Opeře se menu již zobrazí také, i když bez rollover efektu. Je však plně použitelné.
Menu dobře funguje i v textovém (případně hlasovém) režimu. Díky altům se zobrazí tak jak má a je opět dobře použitelné.
Znamená to tedy, že se nám náš pokus podařil? Bohužel, zatím nikoli. Zkuste se podívat na třetí příklad, index3.htm a zjistíte, že celé menu opět zmizelo. Jedná se o stejný příklad jako index2.htm s jediným rozdílem — v hlavičce chybí odkaz na definici stylů. Takto tedy bude vypadat stránka v prohlížeči s žádnou nebo nedostatečnou podporou CSS. To si nemůžeme dovolit. Existuje ale řešení?
Existuje. Nejprve jsem průhledné obrázky s.gif v html dokumentu zaměnil za základní obrázky položek menu m1.jpg až m6.jpg. Tím se menu opět objevilo i bez připojené definice stylů. Nicméně ani s připojenou definicí stylů a ani v IE nefunguje rollover efekt, neboť je tvořen obrázky na pozadí, které jsou ovšem nyní překryty neprůhlednými obrázky na popředí.
Zbývá tedy v definici stylů obrázky na popředí označit za neviditelné. Do pravidel pro obrázky menu doplníme ještě visibility:hidden
a je to:
#m1 img, #m2 img, #m3 img, #m4 img, #m5 img, #m6 img {
width: 190px;
height: 36px;
border: none;
visibility: hidden;
}
Tím jsme dosáhli stavu, kdy je stránka plně použitelná jak v prohlížečích podporujících CSS, tak ve starších bez této podpory a dokonce i v prohlížečích textových. V majoritním IE navíc funguje požadovaný rollover efekt. Výsledek si můžete prohlédnout na
www.sovavsiti.cz/samples/bonisch/index4.htm
Odpovídající definice stylů je zde:
www.sovavsiti.cz/samples/bonisch/style4.css
Doufám, že vám tento příklad názorně ukázal, jaké nástrahy vás mohou při ladění návrhu pomocí CSS čekat a jak je můžete postupnými pokusy a omyly překonávat. Mějte na paměti, že návrh využívající CSS má stránky učinit přístupnější, nikoli naopak. Důležitá je v prvé řadě přístupnost obsahu, teprve na druhém místě je design.
Na závěr dlužno dodat, že celý příklad bude správně fungovat jen tehdy, pokud definice stylů nebude přístupná starším prohlížečům. Jak to udělat se dozvíte ze starších čísel Sovy v síti (číslo 11, Redesign Sovy v síti II), nebo přímo z jejího současného zdrojového kódu.