Rolečky pomocí CSS se vším všudy

3. dubna 2004

V tomto článku si ukážeme, jak vytvořit pouze s pomocí CSS „dokonalé“ rolečky – tedy obrázky, které se při přejetí kurzorem myši změní na jiné obrázky. Samozřejmostí bude přednahrání (preload) obrázku a plná přístupnost rolečku v jakémkoliv prohlížeči.

Rolečky se používají již od dob nejstarších prohlížečů a jsou obvykle řešeny pomocí JavaScriptu. Vychází se přitom z podobného (X)HTML kódu:

<div id=“button“><a href=“#“><img src=“button1.gif“ alt=“Button“ /></a></div>

Do stránky je tedy vložen obrázkový odkaz. Obrázek, který je zde nahrán, je zároveň stavem rolečku před přejetím myší. Odkaz může být vnořen i v jiném elementu než <div>, já jsem ho zde vybral kvůli jeho neutrálnosti. Při tradičním řešení se k tomuto kódu přidají javascriptové ovladače událostí, které zajistí prohození obrázku. Ne tak ale tentokrát – my totiž použijeme k vytvoření rolečku pouze CSS.

Princip řešení

Jaký je logický postup řešení v CSS? Druhý obrázek, který se má zobrazit při přejetí kurzorem myši, nastavíme jako pozadí prvku <a>. Za normálních okolností tedy bude zakryt obrázkem, který se vloží díky prvku <img>. Při najetí kurzoru myši nad odkaz (stav „hover“ v CSS) ale obrázek přesuneme za odkaz a uživatel uvidí druhý obrázek (jako pozadí odkazu). Při umístění kurzoru mimo odkaz se obrázek opět přesune nad odkaz a skryje tak jeho pozadí.

Přikročme k praktickému provedení. Začneme tím jednodušším, tedy nastylováním odkazu:

#button a {
  background: url(„button2.gif“) no-repeat;
  display: block;
  width: 164px; height: 82px;
}

První deklarací jsme přiřadili druhý obrázek na pozadí odkazu. Ve zbytku pravidla jsme potom dali odkazu přesné rozměry – bez nich dělá celý efekt prohlížečům problémy. Obrázek má šířku 164 pixelů a výšku 82 pixelů. Vlastnost display je zde proto, že rozměry se nemohou nastavovat řádkovým prvkům (proto jsme z odkazu udělali blokový). Také zrušíme rámeček kolem obrázku:

#button a img {
  border: 0; /* zrušení řámečku kolem obrázku */
}

A nyní se již budeme věnovat přesunování obrázku za odkaz, tedy vlastně jeho pozicování ve třetím rozměru. To se v CSS dělá vlastnosti z-index, kterou při stavu „hover“ odkazu nastavíme na -1:

#button a:hover img, #button a:focus img {
  z-index: -1;
  position: relative;
}

Vlastnost z-index je možné využívat jen u pozicovaných prvků, proto obrázek také relativně pozicujeme. Aby se nám obrázek neposunul „za dokument“, musíme nastavit vlastnost z-index i pro náš <div>, díky čemuž se obrázek bude posouvat za něj:

#button {
  position: relative;
  z-index: 0;
}

V prohlížeči se zapnutými obrázky není rozdíl poznat. Pokud si je ale vypnete, zjistíte, že by bez tohoto pravidla prvek obrázku při stavu „hover“ z dokumentu úplně zmizel (posunul by se pod dokument), což nevypadá příliš hezky.

Poznámka: Vedle pseudotřídy „hover“ jsme efekt nastavili i pro pseudotřídu „focus“. Ta je vlastně obdobou „hover“ při pohybu po stránce pomocí klávesnice (aktivuje se při zaměření prvku kurzorem ovládaným obvykle pomocí klávesy TAB).

Chyba v Internet Exploreru 6

Všechno by tedy už mělo fungovat. Prohlížeč Microsoft Internet Explorer 6 však obsahuje „zajímavou“ chybu, která způsobí, že tento kód nebude fungovat tak, jak očekáváme. Problém spočívá v tom, že MSIE 6 bere v úvahu změny při stavu „hover“ u prvků vnořených v odkazu jen tehdy, když se změní i nějaká vlastnost samotného odkazu. (A neptejte se mě, jak dlouhou dobu jsem strávil objevováním této chyby…) Musíme tedy přidat pravidlo, kde uděláme nějakou neškodnou změnu odkazu při stavu „hover“>:

#button a:hover {
  background-position: 0 0;
}

Jak vidíte, změnili jsme hodnotu vlastnosti background-position. Její výchozí hodnotou je 0% 0% – ta má ale naprosto stejný význam jako 0 0.

Suma sumarum

Vytvořili jsme tedy roleček pouze pomocí CSS, který správně funguje v prohlížečích MSIE 6+, Mozilla, Opera 7+ a v dalších, které mají podporu CSS na dostatečné úrovni (budu rád, když zmíníte funkčnost rolečku v dalších prohlížečích v diskusi pod článkem). Ve všech těchto prohlížečích zároveň funguje i přednahrání druhého obrázku (samozřejmě, pokud zde není nějak nestandardně nastavena cache, v takovém případě zde ale obvykle nefunguje přednahrání ani u rolečků realizovaných JavaScriptem).

Náš odkaz bude zároveň přístupný jakýmkoli prohlížečem. Nevizuální prohlížeč použije alternativní text z obrázku, stejně jako vizuální prohlížeč s vypnutým zobrazováním obrázků – zde se žádný roleček samozřejmě nepoužije, ale uživatel i tak bude moci odkaz bez problémů použít. Prohlížeč bez odpovídající podpory CSS zobrazí pouze první obrázek a roleček také nepoužije.

A v čem je roleček vytvořený pomocí CSS lepší než klasický javascriptový? Hlavně díky němu nemusíme zapojovat žádný JavaScript a roleček zůstane tam, kde je jeho místo, tedy v prezentační vrstvě stránky (styly). Řešení využívající CSS je také kratší (co do použitých znaků) než to javascriptové.

Postup vytvoření rolečku, který jsem vám právě ukázal, jsem shrnul do ukázkového příkladu.

Rozchození rolečků v Microsoft Internet Exploreru 5.x

Ze záhadných důvodů vytvoří MSIE 5.x rolečky jen v tom případě, že odkaz je řádkový a nejsou mu nastaveny rozměry – při stavu „hover“ ale musí být přeměněn na blokový a musí mu být nastaveny rozměry. Ostatní prohlížeče ale potřebují mít zadané rozměry v obou případech, takže musíme změnit pravidla pro prvek <a>:

#button a {
  background: url(„button2.gif“) no-repeat;
  di\splay: block;
  wid\th: 164px; heigh\t: 82px;
}
#button a:hover {
  background-position: 0 0;
  display: block;
  width: 164px; height: 82px;
}

V prvním pravidle přečtou deklarace vlastností display, width a height jen ty prohlížeče, které ovládají escape-sekvence v CSS a mezi ně MSIE 5.x nepatří. MSIE 6+, Mozilla, Opera 7+ a další, po stránce CSS vyspělé prohlížeče, přiřadí rozměry odkazu již zde. V druhém pravidle potom nastavujeme tyto vlastnosti i pro MSIE 5.x.

Celý kód na vytvoření rolečku fungujícího ve všech moderních prohlížečích tedy vypadá takto:

#button {
  position: relative;
  z-index: 0;
}
#button a {
  background: url(„button2.gif“) no-repeat;
  di\splay: block;
  wid\th: 164px; heigh\t: 82px;
}
#button a img {
  border: 0;
}
#button a:hover {
  background-position: 0 0;
  display: block;
  width: 164px; height: 82px;
}
#button a:hover img, #button a:focus img {
  position: relative;
  z-index: -1;
}

Můžete se podívat i na kompletní příklad druhého rolečku nebo si stáhnout oba příklady zazipované.

A to je vše. Až tedy příště budete dělat na nějakém webu rolečkovou navigaci, můžete s klidem využít možností CSS a na JavaScript v tomto případě zapomenout.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek hrachovka
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

1 komentář

  1. Luboš

    Čvc 29, 2010 v 8:47

    Funguje to ale pouze jen když div, v kterém je odkaz vložen, není pozicován. Jakmile divu hodím position:absolute / relative, obrázky při přejiždění myší nepříjemně přeblikávají (aspoň tedy v MSIE8). Takže buď musí být odakz přímo v body anebo žádný vnější div nesmí být pozicován. Jinak ještě to jde, jako prázdný odkaz s display:block, konkrétní výškou a šířkou, s pozicí absolute či relative, s pozadím jednoho obrázku, a potom a:hover s pozadím druhého obrázku

    Odpovědět

Napsat komentář: Luboš Zrušit odpověď na komentář

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