Schováváme CSS před prohlížeči

30. ledna 2003

V podpoře CSS v dnešních prohlížečích se stále ještě vyskytují chyby. Proto často potřebujeme určitý kus CSS skrýt před nějakým konkrétním prohlížečem s konkrétní chybou. To můžeme udělat efektivně i v samotných tabulkách stylů, pomocí různých neobvyklých ale standardních zápisů. Dnes si ukážeme nejčastější postupy.

Prohlížeče, kterými se budeme zabývat

Budeme se zabývat pouze nejrozšířenějším prohlížeči, protože jenom u nich má smysl ošetřovat chyby v CSS (kvůli velkému počtu uživatelů, kteří je používají). U ostatních prohlížečů bychom tím pouze ztráceli čas, neboť jejich uživatelů není mnoho.

  • Microsoft Internet Explorer pro Windows (zkratka IE) ve verzích:
    • 4 (IE 4)
    • 5 (IE 5)
    • 5.5 (IE 5.5)
    • 6 (IE 6)
  • Microsoft Internet Explorer pro Macintosh verze 5 (zkratka IE 5/Mac).
  • Mozilla ve verzích 1.0 a vyšší pro všechny platformy (zkratka Mozilla). Do této skupiny řadíme i Netscape verze 6 a vyšší, který je z Mozilly odvozen.
  • Netscape Navigator verze 4.x – tedy 4.0, 4.5 a 4.7 – pro Windows (zkratka NN 4).
  • Opera verze 5 a 6 pro Windows (zkratka Opera).

Ještě pár slov k tomu, jak následující metody schovávání používat. Obvykle se to dělá tak, že pomocí jednoduchého zápisu nastavíme nějakou vlastnost tak, aby to vyhovovalo prohlížeči s horší podporou CSS. Vzápětí potom vlastnost přepíšeme na hodnotu, která by měla fungovat podle standardu a ovládají ji tak i prohlížeče s lepší podporou CSS. Učiníme to pomocí zápisu, který nejsou schopné přečíst „horší“ prohlížeče. Právě takovým metodám zápisu (tzv. CSS hackům) se budeme v dnešním článku převážně věnovat.

Box Model Hack

Tento velmi známý trik vychází z parsovací chyby IE 4, IE 5, IE 5.5 a NN 4. Používá se především k obcházení chybného box modelu ve starších verzích IE. Vypadá následovně:

#prvek { /* selektor může být libovolný, v tomto případě na něm nezáleží */
  width: 100px;
  border: 1px solid #000;
  padding: 10px;
  voice-family: „\“}\““; voice-family: inherit;
  width: 78px;
}
html>body #prvek {
  width: 78px;
}

Co jsme tady vlastně udělali? Nejprve jsme definovali vlastnosti width, border a padding, které budou normálně interpretovány všemi prohlížeči.

Poté ale následuje „magická řádka“, pomocí které zajistíme, že IE 4, 5, 5.5 a NN 4 budou zbývající obsah pravidla ignorovat. Využíváme zde chybné interpretace escape sekvencí CSS v těchto prohlížečích. Zároveň jsme potřebovali, aby byl celý kód validní, proto jsme hack definovali v hodnotě téměř nevyužívané vlastnosti voice-family, která očekává jako svůj obsah řetězec. (Pokud vás to zajímá, tak tato vlasnost slouží k definici typu hlasu pro hlasový výstup. V současnosti ale asi neexistuje zařízení, které by ji umělo interpretovat.) Tuto vlastnost pak nastavíme na původní hodnotu pomocí klíčového slova inherit, abychom naším hackem neovlivnili prohlížeče, které by ji případně mohli využívat.

Následující řádek je již výše zmíněnými prohlížeči ignorován, proto zde můžeme nastavit hodnoty vlastností, které přísluší prohlížečům se správnou podporou CSS (v příkladu upravujeme vlastnost width, čímž obcházíme chybný box model).

Za první pravidlo jsem navíc vložil pravidlo další. To je zde kvůli tomu, že některé prohlížeče ignorují bezprostředně následující pravidlo za box model hackem (mám tuto zkušenost s IE 5) a my jim takto předložíme pravidlo, které by stejně neinterpretovaly. Navíc některé prohlížeče mají stejnou parsovací chybu jako starší verze IE, ale box model interpretují správně (sem se prý řadí i Opera 5). Proto tímto pravidlem nastavíme vlastnosti znovu na správné hodnoty. IE 4, 5, 5.5 i 6 budou toto pravidlo ignorovat, protože se zde vyskytuje tzv. child-selektor (viz dále). V prohlížečích, které child-selektor ovládají, se toto pravidlo bude aplikovat na libovolné selektory, které můžeme vložit místo #prvek (protože v každém (X)HTML dokumentu je body dítětem html).

@import

Pravidlo @import slouží k připojení souborů se styly. Může za ním následovat buď funkce url() nebo řetězec. A právě řetězcovou podobu tohoto pravidla neumí IE 4, takže toto pravidlo bude ignorovat:

@import „styly.css“;

Tato podoba @import se používá k tomu, aby styl nenačetly starší prohlížeče, protože ho ovládají až IE 5+, Mozilla a Opera. NN 4 ho neumí v podobě s url() ani jako řetězec.

Pravidlo @import se musí podle standardu CSS vyskytovat před všemi bloky (ty jsou ohraničené složenými závorkami „{}“), tedy de-facto na začátku celé tabulky stylů. Všude jinde má být ignorováno. Tak tomu ale není u IE, proto můžeme použít následující zápis k připojení stylů pouze pro IE (tento zápis je ale nestandardní, proto se mu snažte všemi možnými způsoby vyhýbat):

body {color: black;} /* na selektoru nezáleží, jde pouze o to, aby zde byl nějaký blok */
@import url(„styly-ie.css“);

Pravidlo @import nám navíc umožňuje za souborem se styly definovat také skupinu médií, pro které se má soubor načíst:

@import „styly.css“ screen, print;
nebo:
@import „styly.css“ all;

Tento zápis neovládá IE, a proto ho můžete použít například k přepsání všech vlastností box modelu, pokud se nám nechce používat box model hack.

Atributové selektory

CSS definuje také několik atributových selektorů. Ty ovládají, z našich prohlížečů, pouze Opera a Mozilla. Všechny ostatní taková pravidla ignorují:

div[id=“prvek“] {
/* vlastnosti */
}

Pokud použijete atributový selektor u selektorů sdružených pomocí čárky, bude celé pravidlo ignorováno v IE:

.trida, [class~=“trida“] {
/* vlastnosti */
}

Pokud uděláme před ~= mezeru, nebude toto pravidlo interpretováno v novém prohlížeči pro Mac s názvem Safari. Tento hack uvádím pouze pro zajímavost, protože Safari není jedním z prohlížečů, kterými se zde zabýváme:

.trida {color: #000;}
/* nastaví barvu v prohlížečích, které atributové selektory neznají */
[class~=trida] {color: inherit;}
/* prohlížeče, které atr. selektory znají, nastaví barvu na původní hodnotu */
[class ~=trida] {color: #000;}
/* nyní všechny prohlížeče, které ovládají atr. selektory, kromě Safari nastaví barvu na tuto hodnotu */

Child-selektor

Child-selektor se uplatní pouze pokud je druhý prvek selektoru dítětem prvního prvku selektoru (tedy je v něm přímo vnořen). Z námi zohledňovaných prohlížečů ho ovládá pouze Mozilla, Opera a IE 5/Mac. Proto můžeme následující selektor použít ke skrytí před ostatními prohlížeči:

html>body #prvek {
   /* opět můžeme použít libovolný selektor místo #prvek,
   * protože každý prvek v (X)HTML formátovatelný v CSS
   * je následníkem elementu body
   */
/* vlastnosti */
}

High Pass Filter

Tento hack vychází ze stejné parsovací chyby jako box model hack, ale využívá ji jinak. Podívejte se na příklad:

@import „null?\“\{„;
@import „styl.css“;

První @import bude prohlížeči IE 4, 5, 5.5 a NN4 nesprávně považováno za začátek bloku, a proto nenačtou soubor styl.css. Tento soubor načtou pouze „chytré“ prohlížeče (IE 6, Mozilla, Opera a IE 5/Mac). Ty totiž přečtou první pravidlo @import tak, že mají nahrát soubor null?“{ a tak bez problémů interpretují i druhé pravidlo.

V případě, že tento hack použijete, měli byste na server umístit také soubor null (nemusí ani nic obsahovat). Soubor pak bude „chytrými“ prohlížeči stahován s nesmyslným dotazem „{, který ale nemá na věc žádný vliv. Pokud tento soubor nezahrnete do svého webu, bude server muset prohlížeči vracet HTTP stavový kód 404, čímž se vám jednak zkreslí statistiky, jednak může způsobit prodlevu nebo zatuhnutí prohlížeče.

Hrátky s komentáři

Komentáře se často stávají prostředky k různým hackům, protože v jejich implementaci prohlížeče obsahují mnoho chyb. Například pokud umístíte komentář ihned za selektor, pak nebude toto pravidlo interpretováno v IE 4 a IE 5:

#prvek/* */ { /* vlastnosti */ }

Dalším trikem dosáhnete ignorování pravidel v NN 4. Stačí tam, kde má NN 4 začít CSS ignorovat, umístit komentář ve speciálním tvaru:

/* všechny následující CSS budou ignorovány v NN 4: */
/*/*/
… pravidla …
/* dalším použitím komentáře se NN 4 „chytí“ a již další pravidla interpretuje */

Podobným trikem můžeme donutit i IE 5/Mac, aby následující CSS ignoroval:

/* následující CSS neuvidí IE 5/Mac –
   mylně totiž interpetuje escape sekvenci
   na konci tohoto komentáře
\*/
… pravidla …
/* dalším použitím komentáře se IE 5/Mac opět chytí */

Metody specifické pro NN 4

Kromě výše zmíněného hacku pomocí komentářů můžeme pro NN 4 použít ještě dva další triky. První spočívá v tom, že NN 4 stahuje pouze soubory se styly, které jsou určeny pro obrazovku (media="screen"). My mu tedy zadáme jiná média:

<link rel=“stylesheet“ type=“text/css“ href=“styly.css“ media=“all“ />
nebo:
<link rel=“stylesheet“ type=“text/css“ href=“styly.css“ media=“screen, print“ />
<!– ani jeden z těchto souborů NN 4 nestáhne –>

Další možností jsou selektory ve tvaru element#id, které NN 4 ignoruje:

div#prvek { /* vlastnosti */ }
nebo:
body#telo #prvek {
   /* zde můžeme použít místo #prvek libovolný selektor,
   * pouze musíme element body pojmenovat odpovídajícím způsobem
   * pomocí atributu id
   */
/* vlastnosti */
}

Zdroje informací

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 bozpinfo.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

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