English-only | Jenom česky | Bilingual/Dvojjazyčně

Řešení CSS: Rychlé rollovery bez načítání

Když vytváříme dynamická obrázková tlačítka (rollovery), musí se obvykle do prohlížeče načíst dva, tři i více obrázků (pro základní stav, pro :hover, obrázek pro :active atd.). Často se načítají i předem na pozadí, aby uživatel při změně stavu nemusel čekat na načtení dalšího obrázku (preload). Když ale všechny tyto obrázky spojíme do jediného obrázku, dynamické změny urychlíme a navíc není třeba žádného preloadu.

Vezměme si jednoduchý příklad. Položky menu jsou tvořeny prvky "a" s nastavením display:block. Vhodné nastavení výplně (padding) a obrázek na pozadí pro a, a:hover a a:active vytvářejí dynamické tlačítko (rollover). Pro jeho zjednodušení jsem použil jen jeden obrázek, obsahující tři stavy tlačítka — normální, :hover a :active.

Obrázek na pozadí pro rollover

Obr. 1: Tři stavy současně v jednom obrázku

V CSS rolloverech používáme obrázky na pozadí obvykle nějak takto:

#menu a {
   ...
   background: url("button.gif") top left no-repeat;
   }
#menu a:hover {
   ...
   background-image: url("button-over.gif");
   }
#menu a:active {
   ...
   background-image: url("button-active.gif");
   }

/* etc... */

Když ale použijeme jeden společný obrázek, měnit obrázek na pozadí nemusíme. Stačí změnit jeho umístění (hodnota background-position). Pro stav :hover se použije pozadí posunuté o vhodný počet pixelů (v našem příkladu to je o 157px doleva), stav :active použije posun ještě větší (v příkladu o 314px).

#menu a {
   background: url("button.gif") 0 0 no-repeat;
   ...
   }
#menu a:hover {
   background-position: -157px 0;
   ...
   }
#menu a:active {
   background-position: -314px 0;
   ...
   }

A to je celé. Je použit jen jediný obrázek, není třeba žádný preload, přepínání mezi stavy je tak rychlé, jak jen to jde (posunout obrázek na pozadí je mnohem rychlejší než jej vyměnit). Pokud vím, toto řešení funguje v každém prohlížeči podporujícím CSS2 (IE5+, Mozilla, Opera, Safari atd.)


Update

Jednoduchý, ale účinný doplněk poslal Marek Blaha. Tento postup řeší problém s pomalým načítáním pozadí ve Windows IE, což způsobuje blikání prvku, když nad ním přejíždí kurzor.

Řešení je v podstatě prosté: obrázek na pozadí (posunutý do pozice pro :hover) je přiřazen vnějšímu prvku a stejný obrázek má i vnitřní prvek A (ale v "základní" pozici). Ve stavu A:hover se jeho pozadí změní na průhledné, čímž se zviditelní pozadí "vnějšího" prvku pod ním. Tím pádem se s obrázkem na pozadí vůbec nemanipuluje a IE už nemá důvod blikat.

Prohlédněte si zdrojový kód příkladu 2, kde uvidíte toto řešení v praxi. Funguje prakticky v každém prohlížeči, který jsem potkal (kromě MacIE, kde toto řešení selhává)...