Myslete elasticky s CSS

9. srpna 2004

Myslet elasticky ve webdesignu znamená určovat rozměry stránek ne napevno, ale v závislosti na preferencích uživatele – v závislosti na jeho velikosti písma a na velikosti okna prohlížeče. Elastické stránky nemají problém se zobrazením téměř v žádném zařízení, nekladou uživateli překážky. Ukážeme si tedy, jak pomocí CSS nastavit relativně velikost písma a jak se zbavit pevné šířky stránky.

Proč myslet elasticky

V současnosti si uživatelé prohlížejí webové stránky na různých zařízeních s různými preferencemi. Jmenujme například PDA a podobné vymoženosti s malou obrazovkou a tím pádem i malým oknem prohlížeče, nebo klasické počítače, jejichž rozlišení se dnes pohybuje od 640 do 1 600 pixelů na šířku. V takových podmínkách je stále obtížnější vystačit s pevnou šířkou stránky, protože těžko vyhovíte jednou hodnotou současně malé obrazovce PDA a počítači s rozlišením více než 1 000 pixelů na šířku.

Vedle tohoto vznikajícího problému se již dlouho potýkáme i s problémem druhým – prohlížeč Microsoft Internet Explorer pro Windows (MSIE) neumožňuje uživateli změnit velikost písma, pokud je v CSS nastavena pomocí absolutních jednotek, včetně pixelů. To by snad ještě ani nebyla taková tragédie, kdyby ale MSIE nemělo nainstalováno přes 90 % uživatelů internetu. (Těžko říct, jestli je chování MSIE v tomto případě správné nebo chybné. Možná by se nám stejně tak nelíbilo, kdyby umožňoval písmo s absolutní velikostí zvětšovat.)

Nechat uživatele ovlivnit velikost písma stránky je určitě dobrá věc, když uvážíme, kolik lidí nosí brýle nebo má jiné problémy. Proto je třeba nastavovat písmo stránky relativně, s čímž jsou spojeny další problémy. Nyní se na ně podíváme.

Jak nastavit relativně velikost písma

K nastavení velikosti písma, která byla nastavena uživatelem v prohlížeči, stačí jediné – nenastavovat žádnou velikost pro prvek <body>, nastavit pouze větší či menší písmo pomocí procent tam, kde to potřebujeme, například u nadpisů.

Výchozí velikost písma v prohlížeči (pokud ji uživatel po instalaci nezmění) je ale obvykle příliš velká a nehodí se nám do grafického pojetí stránky. Proto budeme chtít nastavit velikost, která je přibližně osmdesátiprocentní oproti výchozí velikosti v prohlížeči. To se dělá většinou takto…

body {
  font-size: 0.8em;
}

…nebo takto:

body {
  font-size: 80%;
}

Zde je ale kámen úrazu! Pokud nastavíme písmo jedním z těchto způsobů a zkusíme ho zmenšit nebo zvětšit v prohlížeči, zjistíme, že rozdíly mezi jednotlivými stupni velikosti jsou příliš velké (u jednotek em větší než u procent). Například v MSIE už při „malé“ velikosti písma dostaneme téměř nečitelnou velikost. Tento problém se ale týká i ostatních prohlížečů, například Mozilly.

Řešením je použít klíčová slova pro nastavení velikosti písma, v našem případě slovo small. Klíčová slova jsou ale špatně interpretována v MSIE 5.x, proto musíme použít hack. Pro MSIE 5.x použijeme klíčové slovo x-small, které nastavuje ještě o stupeň menší písmo, protože MSIE 5.x má posunuté významy těchto klíčových slov. Pro ostatní prohlížeče nastavíme small pomocí zkráceného Tantekova hacku.

body {
  font-size: x-small;
  fo\nt-size: small;
}

Nyní již jsou rozestupy mezi různými stupni velikosti písma v pořádku. Proč ale způsobují procenta a em takové problémy a klíčová slova fungují, to se můžeme jen dohadovat. Podle mého názoru je to zapříčiněno různými aproximacemi při počítání skutečné velikosti písma, kdy u procent a em jich je určitě více než u klíčových slov, jejichž číselné hodnoty si může prohlížeč podle svých potřeb upravit.

Problémy s některými elementy v MSIE

V MSIE se po použití hodnoty small na <body> vykreslují prvky <samp>, <code> a <kbd> menším písmem, než by měly. Proto se vyplatí přidat do CSS ještě pár řádek:

samp, code, kbd {
  font-size: 90%;
}

Při devadesátiprocentní velikosti vypadá neproporciální písmo (jímž jsou tyto prvky vykresleny) uvnitř normálně psaného textu asi nejlépe, jak může a nenarušuje tolik jeho tok jako při stoprocentní velikosti.

Také můžete uživatele nechat ovládat písmo ve formulářových prvcích:

input, select, button, textarea {
  font-size: 100%;
}

Po tomto nastavení se i v nich bude písmo zvětšovat a zmenšovat podle přání uživatele.

Jak se osvobodit od pevné šířky

Jak jsme si již řekli, v současnosti bychom při návrhu vzhledu stránky měli počítat jak s malými, tak velkými obrazovkami (a tím pádem s různými velikostmi okna prohlížeče). Měli bychom tedy dělat stránky elastické, které se automaticky přizpůsobují velikosti okna (protože příliš široké stránky v malém okně se špatně používají a příliš úzké stránky ve velkém okně špatně vypadají). Samozřejmě není možné dělat elastické stránky ve všech případech, pokud například potřebujeme na stránku naskládat hodně grafiky nebo chce zadavatel stejný vzhled za všech okolností, pravděpodobně použijeme pevnou šířku. Troufám si ale tvrdit, že většina webů se bez ní může obejít.

A jak provést osvobození od pevné šířky prakticky? Nenastavovat šířku stránky vlastností width a místo ní začít používat vlastnosti min-width pro minimální šířku (důležitá kvůli malým obrazovkám) a max-width pro maximální šířku (důležitá kvůli vyšším rozlišením). Společně nám tyto vlastnosti umožňují nastavit jakési rozmezí. Podle konkrétního webu je třeba se rozhodnout, jestli použít tyto vlastnosti pro celou stránku a šířku jejích částí nastavit procentuálně, nebo takto omezovat její části zvlášť – například hlavní obsah, sloupečky a podobně.

Textové bloky

U textových bloků bychom měli vlastnosti min-width a max-width nastavovat podle velikosti písma. Tu jsme ale nastavili relativně, záleží tedy na uživatelově prohlížeči. Skvěle nám v tomto případě poslouží jednotka em, která nám umožní nastavit rozmezí šířky v závislosti na velikosti písma v prvku:

#obsah {
  min-width: 18em;
  max-width: 30em;
}

Otázka zní, jaké hodnoty se pro textové bloky hodí. Obecně se míní, že ke čtení je vhodná šířka od 40 do 65 znaků na řádek. Je tedy třeba zjistit, která hodnota zajistí potřebný počet znaků na řádek při všech možných velikostech písma. Provedl jsem pokusy s různými písmy a došel jsem k následujícím hodnotám:

Písmo Šířka pro 40 znaků Šířka pro 65 znaků
Arial 18 em 30 em
Times 16 em 26 em
Verdana 21 em 34 em
Georgia 19 em 31 em

Vhodné hodnoty se liší podle typu písma, což je způsobeno různým poměrem šířky a výšky znaků u jednotlivých písem. Pokud se s tím ale nechcete zase tolik „babrat“, můžete se smířit s určitými nepřesnostmi a používat jedny hodnoty pro všechna písma.

Grafická záhlaví

V souvislosti s grafikou a elastickými stránkami můžete použít jeden trik. Řekněme, že máte v hlavičce obrázek na pozadí přes celou šířku stránky – s pevnou šířkou jste v CSS mohli použít následující:

#hlavicka {
  background: url(„zahlavi.gif“) no-repeat;
  width: 750px;
}

S použitím elastické šířky by to ale dopadlo takto:

#hlavicka {
  background: url(„zahlavi.gif“) no-repeat;
  max-width: 750px;
  min-width: 250px;
}

V druhém případě může mít hlavička různou šířku. To ale obrázku nevadí, protože se ho zobrazí pouze taková část, aby se do hlavičky vešel. Dokonce můžete nastavit maximální šířku i větší než 750 pixelů a celý obrázek udělat větší – vždy se ho zobrazí pouze taková část, jaká je potřeba.

Co zvážit, na co si dát pozor

Používání minimálních a maximálních šířek je daleko složitější na možné kombinace než pevná šířka, hlavně v kombinaci s jednotkou em. Při návrhu vzhledu stránky je tedy třeba vždy přemýšlet a zkoušet, jak bude stránka vypadat ve velkém a jak v malém okně, jak ji ovlivní nastavení většího či menšího písma a podobně.

Zprovoznění max-width v MSIE

Prohlížeč MSIE bohužel nepodporuje vlastnosti min-width ani max-width. V případě vlastnosti min-width to tolik nevadí (je důležitá hlavně kvůli malým obrazovkám), ale max-width je již bolestivá ztráta, protože bez ní se může stránka na vysokých rozlišeních roztáhnout tak, že už z ní uživatel nebude moci nic přečíst.

Programátoři Microsoftu sice neimplementovali výše uvedené vlastnosti, ale zavedli speciální CSS hodnoty expression(výraz) (viz About Dynamic Properties), kde „výraz“ je vyhodnocen pomocí JavaScriptu a jeho výsledek je použit jako hodnota pro danou vlastnost. Právě s pomocí této hodnoty max-width nahradíme:

#hlavicka {
  max-width: 750px;
  min-width: 250px;
  width: 751px;
  width: expression((document.getElementById(„hlavicka“).currentStyle.width == „751px“) ? „auto“ : (document.getElementById(„hlavicka“).offsetWidth > 750 ? „750px“ : „auto“));
}

Jak vidíte, testujeme skutečnou šířku prvku a pokud je větší než 750 pixelů, nastavíme šířku na těchto 750 pixelů.

Kromě toho se musíme nějak vypořádat se situací, kdy jsou vypnuté skripty, v takovém případě totiž expression() nefunguje. Proto jsme předřadili naší deklaraci ještě jednu deklaraci, která nastavuje pevnou šířku 751 pixelů. V hodnotě expression() pak tuto šířku zrušíme. Tato pevná šířka nesmí být stejná jako šířka, kterou jsme určili jako maximální, jinak by se výpočet expression() zacyklil (po prvním překročení maximální šířky by se stále dokola nastavovaly hodnoty „auto“ a „750px“).

Skrytí deklarací před ostatními prohlížeči

Obě nastavení vlastnosti width ve výše uvedené ukázce jsou ale určena jen pro MSIE, v ostatních prohlížečích by měla dopad, o který nestojíme. Proto musíme tyto dvě deklarace před ostatními prohlížeči nějak skrýt. Pro tento účel můžeme použít podtržítkový hack – na začátek jména vlastnosti se umístí podtržítko, což zajistí, že tuto vlastnost interpretuje jen MSIE:

#hlavicka {
  max-width: 750px;
  min-width: 250px;
  _width: 751px;
  _width: expression((document.getElementById(„hlavicka“).currentStyle.width == „751px“) ? „auto“ : (document.getElementById(„hlavicka“).offsetWidth > 750 ? „750px“ : „auto“));
}

Podtržítkový hack způsobí, že naše CSS bude nevalidní, protože specifikace CSS o žádné vlastnosti _width nemluví. Zároveň ale tato specifikace říká, že v názvu vlastnosti se smí vyskytovat podtržítko a že prohlížeče mají ignorovat neznámé vlastnosti. Proto by ostatní prohlížeče měly deklaraci _width ignorovat a pokračovat další částí předpisu (jeho správnému parsování tato deklarace nezabraňuje).

Pokud chcete mít svůj stylový předpis validní, můžete použít ke skrytí obou deklarací druhou možnost, takzvané podmíněné komentáře. Stačí umístit do hlavičky stránek tento kód:

<!–[if IE]>
<link rel=“stylesheet“ type=“text/css“ href=“styl-ie.css“ />
<![endif]–>

Prohlížeč MSIE načte v takovém případě do stránky další stylový předpis, ve kterém můžete uvést všechny deklarace určené jen pro něj (tedy i naše dvě deklarace šířky). Ostatní prohlížeče budou tento zápis chápat správně jako (X)HTML komentář a nic nenačtou. Udržíte si tak svůj stylový předpis validní, na druhou stranu bude muset MSIE nahrávat o jeden soubor CSS navíc, což může vykreslování stránky zpomalit. Vyberte si sami řešení, které je vám bližší.

Proč nenahrazovat min-width

V této chvíli si také můžeme vysvětlit druhý důvod, proč nenahrazovat min-width pomocí expression(). Pokud si uživatel otevře odkaz na naši stránku v MSIE do nového okna, je toto okno minimalizované. Velmi pravděpodobně by se v takovém případě nastavila šířka prvku (pomocí expression()) na svoji minimální hodnotu. Jak jste si ale již možná všimli, jakmile je takto šířka nastavena na určitou hodnotu, prvek si ji ponechá za všech okolností a již se pomocí expression() nezmění (protože hodnota document.getElementById("hlavicka").offsetWidth bude již napořád stejná). To znamená, že i po maximalizaci okna by si prvek ponechal minimální šířku, což jistě není ideální (vzhledem k tomu, že otevírání nových oken není nic neobvyklého).

Nahrazení max-width v em

Způsobem, který jsme si právě popsali, je tedy možné nahradit vlastnost max-width v případě, že ji uvádíte v pixelech. Nyní si ukážeme, jak tuto vlastnost nahradit v případě, že je nastavena pomocí jednotky em:

#obsah {
  min-width: 18em;
  max-width: 30em;
  width: 30.1em;
  width: expression((document.getElementById(„obsah“).currentStyle.width == „30.1em“) ? „auto“ : (document.getElementById(„obsah“).offsetWidth >= (parseInt(document.documentElement.currentStyle.fontSize) <= 10 ? ((parseInt(document.documentElement.currentStyle.fontSize) – 1) * 4/3 * 30) : ((parseInt(document.documentElement.currentStyle.fontSize) – 2) * 4/3 * 30)) ? „30em“ : „auto“));
}

Postup je podobný jako v předchozím případě, i když to tak podle délky kódu nevypadá. Jediný rozdíl je v tom, jak se zjišťuje maximální šířka v pixelech, která má pro prvek v dané chvíli platit (v předchozím případě bylo na tomto místě pouze číslo „750“). Musel jsem také použít neostrou nerovnost, protože s ostrou mi MSIE z mně nepochopitelných důvodů padal.

Abychom získali maximální šířku v pixelech, musíme nejprve zjistit velikost písma v bodech (pt) v dokumentu (předpokládám, že v našem prvku je tato velikost stejná, pokud ne, bylo by to třeba ve skriptu zohlednit). Vynásobením této velikosti čtyřmi třetinami získáme velikost písma v pixelech (číslo „4/3“, respektive jeho aproximaci, pro tento přepočet prohlížeče opravdu používají) a tuto velikost vynásobíme třiceti (protože šířka má být 30em a jedno em je rovno velikosti písma prvku v pixelech), čímž získáme maximální šířku v pixelech pro prvek.

Nyní k tomu, jak zjistit velikost písma dokumentu v bodech. Nemůžeme k tomu použít vlastnost currentStyle, protože ta obsahuje pouze přiřazené, ne přepočítané hodnoty (přiřazená hodnota je v našem dokumentu small). Udělal jsem tedy nějaké pokusy a zjistil jsem následující:

  • MSIE nabízí uživateli pět základních velikostí písma – 9 pt pro „nejmenší“, 10 pt pro „malé“, 12 pt pro „střední“, 14 pt pro „velké“ a 16 pt pro „největší“. Velikost vybraná uživatelem je nastavena pro dokument a relativní velikost, kterou nastavujeme pro <body>, se od ní odvozuje.
  • Pokud nastavíme pro <body> písmo small, celá stupnice se posune – 8 pt bude pro „nejmenší“, 9 pt pro „malé“, 10 pt pro „střední“, 12 pt pro „velké“ a 14 pt pro „největší“.

Abychom zjistili velikost písma dokumentu v bodech, stačí nám tedy získat uživatelem nastavenou velikost (pomocí document.documentElement.currentStyle.fontSize) a převést ji na hodnotu odpovídající small.

Jedná se o vcelku složitý výpočet, který však dává přesné výsledky. Vy mu ale rozumět příliš nemusíte, stačí vám upravit si můj zápis pro své potřeby (pravděpodobně pouze úpravou hodnoty maximální šířky). Samozřejmě byste opět měli obě deklarace skrýt před ostatními prohlížeči, buď podtržítkovým hackem nebo pomocí podmíněných komentářů.

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

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

Další článek poki.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 *