Interval.cz
NavigaΦnφ menu pomocφ CSS

Dnes si ukß₧eme, jak pouze pomocφ CSS vytvo°it navigaΦnφ menu s roll-over efekty. Jednß se o oblast CSS, kterß je vyu₧itelnß ji₧ v dneÜnφch prohlφ₧eΦφch, proto byste si Φlßnek rozhodn∞ nem∞li nechat ujφt!

Nejprve zkonstruujeme zßkladnφ menu, potΘ mu p°idßme jeÜt∞ jednu zajφmavou vlastnost. Prvnφ menu se nachßzφ v prvnφm p°φklad∞.

(X)HTML k≤d

Na strßnku vlo₧φme zßkladnφ (X)HTML k≤d, kter² vytvo°φ jednotlivΘ odkazy. Tento k≤d potΘ odpovφdajφcφm zp∙sobem nastylujeme. NavigaΦnφ menu je vlastn∞ seznam odkaz∙, proto bychom m∞li vyu₧φt elementy pro seznamy v (X)HTML:

<div id="navigation">
<ul>
  <li><a href="#">Webdesign</a></li>
  <li><a href="#">V²voj aplikacφ</a></li>
  <li><a href="#">E-komerce</a></li>
  <li><a href="#">Nßstroje</a></li>
  <li><a href="#">Magazφn</a></li>
  <li><a href="#">Diskusnφ f≤rum</a></li>
</ul>
</div>

CelΘ menu uzavφrßme do div(u) s nßzvem navigation û toho vyu₧ijeme pozd∞ji v selektorech CSS. Na normßlnφch strßnkßch by navφc m∞ly odkazy n∞kam vΘst.

Tento k≤d je velmi dob°e srozumiteln² pro jak²koli prohlφ₧eΦ podporujφcφ HTML, proto bude navigaci moci vyu₧φt ka₧d² u₧ivatel. Ti, kte°φ navφc pou₧φvajφ modernφ vizußlnφ prohlφ₧eΦ, uvidφ efektnφ menu. K podpo°e v prohlφ₧eΦφch se dostaneme pozd∞ji.

CSS definice

Nynφ zaΦneme p°i°azovat CSS vlastnosti. V₧dy si ukß₧eme kus definice a pak si k nφ n∞co °ekneme:

body {
  color: #000; background-color: #fff;
  font-family: "Verdana CE", Verdana, sans-serif; line-height: 1.35;
  margin: 0; padding: 2.5em;
}

Nejprve nastavujeme vlastnosti celΘ strßnky: barvy, okraje a druh pφsma. VÜimn∞te si, ₧e nenastavujeme velikost pφsma û celΘ menu bude mφt relativnφ rozm∞ry a nebude proto zßvislΘ na velikosti pφsma. To si m∙₧ete vyzkouÜet v p°ilo₧enΘm p°φklad∞ tak, ₧e zm∞nφte velikost pφsma v prohlφ₧eΦi.

Tyto zßkladnφ vlastnosti zßvisφ pouze na vßs. VÜe m∙₧ete ud∞lat podle sv²ch konkrΘtnφch pot°eb, m∙₧ete pou₧φt i pevnou velikost pφsma, proto₧e menu se jφ v takovΘm p°φpad∞ p°izp∙sobφ. PokraΦujeme dßl:

div#navigation {
  color: #fff; background-color: #8eccfb;
  width: 13em;
  padding: 0.5em;
  voice-family: "\"}\""; voice-family: inherit;
  width: 12em;
}

div#navigation ul {
  background-color: #6caad9;
  margin: 0; padding: 0;
}

Zde ji₧ zaΦφnßme nastavovat vizußlnφ vlastnosti menu. Nenφ na nich nic k nepochopenφ, snad pouze to, ₧e vyu₧φvßme hacku ÜpatnΘho box-modelu v IE 5.x. TakΘ zde musφme vynulovat okraje a vycpßvky u elementu pro neuspo°ßdan² seznam, proto₧e ty jsou v prohlφ₧eΦφch pom∞rn∞ ₧iveln∞ implicitn∞ nastaveny.

VÜechny rozm∞ry nastavujeme pomocφ relativnφ jednotky em. Ta se vß₧e k velikosti pφsma elementu, proto m∙₧e menu obsahovat jakkoli velkΘ pφsmo (proto₧e se v₧dy roztßhne na pot°ebnou velikost).

VÜimn∞te si takΘ, ₧e vÜe nastavujeme pouze pro naÜe menu, a to pomocφ selektor∙ vßzan²ch na nßÜ div pojmenovan² navigation. M∙₧eme tedy pokraΦovat dßl:

div#navigation li {
  list-style: none;
  margin: 0; padding: 0;
}

Nynφ p°i°azujeme vlastnosti elementu li, kter² vytvß°φ jednotlivΘ polo₧ky seznamu. Op∞t zde nulujeme okraje a vycpßvky, navφc vÜak zruÜφme zobrazovßnφ seznamovΘ odrß₧ky pomocφ vlastnosti list-style. V dalÜφ definici se ji₧ v∞nujeme odkaz∙m:

div#navigation a {
  color: #fff;
  font-size: 1em;
  text-decoration: none;
  display: block;
  border-left: 1em solid #6caad9; border-right: 1em solid #6caad9;
  width: 12em;
  padding: 0.35em 1em;
  voice-family: "\"}\""; voice-family: inherit;
  width: 8em;
}

VÜechny odkazy p°edefinovßvßme na blokovΘ prvky. Je to d∙le₧itΘ kv∙li tomu, abychom u nich mohli nastavit Üφ°ku (u °ßdkov²ch element∙ nem∙₧eme) a odkaz byl aktivnφ (tj. dalo se na n∞j kliknout) po celΘ Üφ°ce menu. PotΘ mu tedy nastavujeme Üφ°ku, p°iΦem₧ musφme poΦφtat s vadn²m box-modelem v IE 5.x.

DalÜφ vlastnosti jsou op∞t vizußlnφ, cht∞l bych zde zd∙raznit pouze jednu, vlastnost font-size: 1em;. Asi se vßm zdß, ₧e je zde zbyteΦnß, proto₧e p°i pou₧itφ pro nastavovßnφ velikosti pφsma se velikost jednotky em odvozuje od velikosti pφsma rodiΦovskΘho elementu. Touto definicφ toti₧ °φkßme, ₧e chceme stejnou velikost pφsma jako u rodiΦovskΘho elementu. To je ale automatickΘ, proto₧e vlastnost font-size se d∞dφ. P°esto je nutnΘ ji pou₧φt, proto₧e IE/Win do verze 6 Üpatn∞ poΦφtß skuteΦnou velikost jednotky em p°i nastavenφ velk²ch pφsem v prohlφ₧eΦi a vykresluje jednotlivΘ polo₧ky kratÜφ ne₧ by m∞ly b²t. Pokud ale tuto vlastnost explicitn∞ nastavφme, IE si vÜe sprßvn∞ äuv∞domφô a ₧ßdn² problΘm nevznikne.

Nynφ se postßrßme o dynamickΘ efekty menu:

div#navigation a:hover, div#navigation a:focus {
  background-color: #7dbbea;
  border-left: 1em solid #8eccfb; border-right: 1em solid #8eccfb;
}

div#navigation a:active {
  background-color: #ffb380;
  border-left: 1em solid #ffb380; border-right: 1em solid #ffb380;
}

Nejprve nastavujeme zm∞nu stavu pro odkaz, nad kter²m se nachßzφ kurzor ukazovacφho za°φzenφ (v∞tÜinou myÜi) pomocφ pseudo-t°φdy hover. Takov² efekt je ale vßzan² prßv∞ na ukazovacφ za°φzenφ, proto by o n∞j p°iÜli u₧ivatelΘ pohybujφcφ se po strßnce pomocφ klßvesnice nebo jin²m zp∙sobem. Ty samΘ zm∞ny tedy nastavφme i pro pseudo-t°φdu focus, kterß se aktivuje v moment∞, kdy mß element tzv. fokus, nap°. p°i surfovßnφ pomocφ klßvesy TAB nebo p°i skßkßnφ z odkazu na odkaz ve hlasovΘm prohlφ₧eΦi (ten samoz°ejm∞ nezobrazφ naÜe vizußlnφ efekty). V souΦasnΘ dob∞ podporuje pseudo-t°φdu focus pouze Mozilla/Netscape 6+ a IE 5/Mac, IE/Win do verze 6 aktivuje p°i fokusu pseudo-t°φdu active.

Pseudo-t°φdu active nastavuje druhΘ pravidlo, p°iΦem₧ stejn∞ jako u hover a focus dochßzφ k barevn²m zm∞nßm pozadφ a rßmeΦk∙ û u t∞ch nem∙₧eme pou₧φt vlastnosti border-left-color a border-right-color, aΦkoli dochßzφ pouze k barevn²m zm∞nßm, proto₧e Opera do verze 6 v takovΘm p°φpad∞ barvu rßmeΦku nezm∞nφ.

Nynφ by se mohlo zdßt, ₧e je ji₧ menu hotovΘ. K ·plnΘ ädokonalostiô mu ale n∞co chybφ, a to je odliÜenφ ji₧ navÜtφven²ch odkaz∙. To je vcelku dost d∙le₧itΘ, proto₧e toto odliÜenφ u₧ivateli znaΦn²m zp∙sobem ulehΦuje pohyb naÜφm webem. Zvolil jsem matn∞jÜφ barvu textu:

div#navigation a:visited {
  color: #ddd;
}

CelΘ menu m∙₧ete samoz°ejm∞ nastylovat pomocφ jin²ch vizußlnφch vlastnostφ, kostra menu z∙stßvß v₧dy stejnß. Vizußlnφ podob∞ jsem se tolik nev∞noval, Ülo mi pouze o nastφn∞nφ principu.

NaÜe menu by m∞l zobrazit sprßvn∞ ka₧d² prohlφ₧eΦ s dobrou podporou CSS, bez problΘm∙ jsem ho testoval na IE 6/Win, Mozille/Netscape 6+ a Ope°e 5+. IE 4/Win nemß problΘmy s efekty, ale menu nevypadß, tak jak mß (je to hlavn∞ kv∙li zoufalΘmu box-modelu v tomto prohlφ₧eΦi), i p°esto je vÜak pln∞ pou₧itelnΘ.

äMagick² efektô

Nynφ se podφvejte na druh² p°φklad. P°ipomφnßm, ₧e se stßle jednß pouze o XHTML + CSS, ₧ßdn² JavaScript. Jednß o prvnφ menu, u n∞ho₧ se p°i p°ejetφ nad polo₧kou zobrazφ pod menu nßpov∞da k nφ.

Nßpov∞da, kterß se pod menu objevuje, musφ b²t souΦßstφ strßnky. My ji umφstφme do odkaz∙ v menu, a to p°φmo za nßzev polo₧ky (samoz°ejm∞ na tomto mφst∞ musφ b²t n∞jak² odd∞lovaΦ polo₧ky a jejφho popisu pro prohlφ₧eΦe bez podpory CSS). Podφvejte se tedy na upraven² (X)HTML k≤d:

<div id="navigation-container">
<div id="navigation">
<ul>
  <li><a href="#" title="Webdesign&nbsp;û V tΘto rubrice se v∞nujeme webdesignu.">Webdesign<span>&nbsp;û </span><span class="description">V tΘto rubrice se v∞nujeme webdesignu.</span></a></li>
  <li><a href="#" title="V²voj aplikacφ&nbsp;û V tΘto rubrice se v∞nujeme v²voji aplikacφ.">V²voj aplikacφ<span>&nbsp;û </span><span class="description">V tΘto rubrice se v∞nujeme v²voji aplikacφ.</span></a></li>
  <li><a href="#" title="E-komerce&nbsp;û V tΘto rubrice se v∞nujeme e-komerci.">E-komerce<span>&nbsp;û </span><span class="description">V tΘto rubrice se v∞nujeme e-komerci.</span></a></li>
  <li><a href="#" title="Nßstroje&nbsp;û V tΘto rubrice se v∞nujeme nßstroj∙m vhodn²m pro vytvß°enφ web∙.">Nßstroje<span>&nbsp;û </span><span class="description">V tΘto rubrice se v∞nujeme nßstroj∙m vhodn²m pro vytvß°enφ web∙.</span></a></li>
  <li><a href="#" title="Magazφn&nbsp;û V tΘto rubrice se v∞nujeme ostatnφm tΘmat∙m.">Magazφn<span>&nbsp;û </span><span class="description">V tΘto rubrice se v∞nujeme ostatnφm tΘmat∙m.</span></a></li>
  <li><a href="#" title="Diskusnφ f≤rum&nbsp;û V tΘto rubrice si m∙₧ete zadiskutovat.">Diskusnφ f≤rum<span>&nbsp;û </span><span class="description">V tΘto rubrice si m∙₧ete zadiskutovat.</span></a></li>
</ul>
</div>
</div>

Cel² text jsme navφc umφstili do atributu title u odkaz∙. To je d∙le₧itΘ pro p°φpad, kdy prohlφ₧eΦ podporuje dob°e CSS, ale neumφ zobrazovat dynamicky nßpov∞du k polo₧kßm. U₧ivatel by v takovΘm p°φpad∞ o nßpov∞du p°iÜel. P°esn∞ takto se mj. chovß Opera verze 6 a ni₧Üφ, ale mohou to b²t i jinΘ, mΘn∞ znßmΘ prohlφ₧eΦe.

PopisnΘ texty jsem uzav°el do element∙ span. T∞m uzavφrajφcφm odd∞lovaΦe jsem nep°i°adil ₧ßdnou t°φdu, nßpov∞dn²m text∙m jsem p°i°adil t°φdu description. Toho budeme op∞t vyu₧φvat v CSS.

CelΘ menu jsme takΘ uzav°eli jeÜt∞ do jednoho div(u), s id="navigation-container". Jeho stylovßnφm nynφ zaΦneme:

div#navigation-container {
  position: relative;
  width: 13em;
}

Jak vidφte, p°edefinovßvßme jeho pozici na relativnφ, ale nenastavujeme vlastnosti top, right, bottom ani left, co₧ znamenß, ₧e se element neposune oproti svΘmu normßlnφmu umφst∞nφ, ale bude se od n∞j poΦφtat absolutnφ pozice vno°en²ch element∙. Toho vyu₧ijeme p°i umφs¥ovßnφ nßpov∞d.

DalÜφ pravidla jsou stejnß jako v prvnφm p°φpad∞, ale nakonec p°idßme t°i, pomocφ kter²ch nastylujeme nßpov∞dnΘ texty. Prvnφ z nich je velmi jednoduchΘ:

div#navigation a span {
  display: none;
}

Tφmto zßpisem zajistφme, ₧e se skryjφ odd∞lovaΦe ä&nbsp;û ô. Toto pravidlo by ale samo o sob∞ skr²valo i nßpov∞dnΘ texty, proto u nich nastavφme display na jinou hodnotu. P°idßme jeÜt∞ n∞kolik vlastnostφ:

div#navigation a span.description {
  color: #fff; background-color: #ccc;
  font-size: 0.9em; font-style: italic;
  position: absolute; left: 0; top: 15.5em;
  display: block; visibility: hidden;
  width: 13.3em;
  border-top: 1px solid #bbb; border-bottom: 1px solid #bbb;
  padding: 0.38em 1.1em;
  voice-family: "\"}\""; voice-family: inherit;
  width: 12.2em;
}

Krom∞ mnoha vizußlnφch vlastnostφ zde pozicujeme vÜechny nßpov∞dy p°esn∞ pod menu (pozice se poΦφtß od div(u) pojmenovanΘho navigation-container): ka₧dß polo₧ka mß v²Üku 2.05 em (v²Üka °ßdkovΘho boxu = velikost pφsma 1 em × v²Üka °ßdku 1.35 = 1.35 em, padding naho°e a dole 0.7 em) a je jich 6; padding u div#navigation naho°e a dole 1 em; zmenÜujeme pφsmo na 0.9 em, a proto musφme hodnotu adekvßtn∞ p°epoΦφtat; n∞co p°idßme na odd∞lenφ menu a nßpov∞d a vyjde nßm 15.5 em.

Po p°epoΦφtßnφ nßm takΘ vyjde Üφ°ka 13.3 em, kterß by m∞la b²t stejnß jako Üφ°ka menu a vycpßvky po stranßch 1.1 em, kterΘ by nßm m∞ly zajistit stejnΘ odsazenφ textu jako u menu.

Dßle ud∞lßme pomocφ vlastnosti display z implicitn∞ °ßdkovΘho elementu span blokov² element (a zßrove≥ tφm zruÜφme jeho skrytφ), cel² element navφc skryjeme pomocφ vlastnosti visibility. P°i p°ejetφ myÜφ nad polo₧kou nebo p°i p°edßnφ fokusu polo₧ce zm∞nφme hodnotu tΘto vlastnosti na visible, Φφm₧ menu odkryjeme. Tato myÜlenka je realizovßna pomocφ nßsledujφcφho zßpisu:

div#navigation a:hover span.description, div#navigation a:focus span.description {
  visibility: visible;
}

Tφmto zßpisem doslova °φkßme, ₧e jakΘmukoli elementu span s t°φdou description nachßzejφcφmu se uvnit° elementu a ve stavu hover/focus, kter² se nachßzφ uvnit° div(u) se jmΘnem navigation, se mß zm∞nit hodnota vlastnosti visibility na visible, tedy viditeln².

Tuto variantu menu podporujφ prohlφ₧eΦe stejn∞ jako v prvnφm p°φpad∞, pouze Opera verze 6 a ni₧Üφ skryje a ji₧ nezobrazφ nßpov∞dy, jak jsem ji₧ zmφnil.

Na konec jenom poznamenßm, ₧e by bylo lepÜφ pou₧φt pro skr²vßnφ nßpov∞d vlastnost display, proto₧e prvek skryt² pomocφ visibility m∙₧e reagovat na udßlosti (i kdy₧ tomu zde tak nenφ). IE/Win verze 6 a ni₧Üφ mß ale s display problΘmy, proto musφme pou₧φt visibility.

Dnes jsme si tedy ukßzali, ₧e i p°es stßle vcelku ₧ivelnou podporu nßroΦn∞jÜφch v∞cφ z CSS, se ji₧ dajφ vyu₧φt leckterΘ pokroΦilejÜφ konstrukce. Ty nßm mohou pomoci zefektivnit strßnku (kratÜφ a ΦistÜφ k≤d) a zv²Üit jejφ p°φstupnost i pou₧itelnost (nemusφme vyu₧φvat obrßzky ani JavaScript).


Po zve°ejn∞nφ Φlßnku jsem objevil na popisovan²ch menu t°i nedostatky, a to i dφky Φtenß°∙m û t∞m za tuto podporu velmi d∞kuji.

Prvnφm z problΘm∙ je ÜpatnΘ zobrazenφ v IE 5/Win. To je zp∙sobeno CSS box-model hackem (voice-family: "\"}\""; voice-family: inherit;), kter² v IE 5/Win zavinφ ignorovßnφ pravidla nßsledujφcφho za tφm, kde je hack pou₧it. Proto musφme dv∞ pravidla, kterß za hackem nßsledujφ, zduplikovat û tzn. vlo₧it dvakrßt za sebou:

...
div#navigation ul {
 background-color: #6caad9;
 margin: 0; padding: 0;
}
div#navigation ul {
 background-color: #6caad9;
 margin: 0; padding: 0;
}

...

div#navigation a:visited {
 color: #ddd;
}
div#navigation a:visited {
 color: #ddd;
}
...

P°i tomto zßpisu ji₧ nenφ problΘm v zobrazenφ prvnφho menu v IE 5/Win, IE 5.5/Win, IE 6/Win ani Mozille/NS6+ a Ope°e 5+ (ve vÜech testovßno).

Upraven² p°φklad si m∙₧ete stßhnout.

Druh² problΘm nalezneme v druhΘm p°φklad∞, a sice ve ÜpatnΘ pozici nßpov∞dy pod menu. Tu pozicujeme pomocφ jednotek em, kterΘ ale nemohou umφstit nßpov∞du v₧dy pod menu, proto₧e u nφ nastavujeme menÜφ pφsmo û p°i menÜφch velikostech pφsma se potom nßpov∞da zobrazφ p°es menu.

╪eÜenφm problΘmu je vlo₧it nßpov∞du do dvou span∙, p°iΦem₧ prvnφmu nechßme stejnou velikost pφsma jako u menu a pozicujeme ho; u druhΘho potom pφsmo zmenÜφme. Upraven² p°φklad.

Poslednφ t°etφ problΘm je op∞t s IE 5/Win. Ten v∙bec nezobrazuje nßpov∞dy k menu v druhΘm p°φkladu. ╪eÜenφm je p°i°adit vÜechny vlastnosti span.description a₧ kdy₧ je odkaz ve stavu hover, navφc nesmφme u odkaz∙ pou₧φt vlastnosti width ani height. TakΘ musφme nßpov∞du skr²vat pomocφ vlastnosti display. Vzhledem k nemo₧nosti pou₧φt width a height je menu aktivnφ pouze p°i kurzoru myÜi nastavenΘm nad textem, ne nad celou polo₧kou. Abychom tedy dosßhli sprßvnΘho zobrazenφ v IE 5/Win, musφme omezit zobrazenφ v ostatnφch prohlφ₧eΦφch, kterΘ podporujφ CSS lΘpe ne₧ IE 5/Win. Pokud tak chcete uΦinit, zde je upraven² p°φklad.

Jak tedy vidφte, chyby jdou na vrub p°edevÜφm ÜpatnΘmu zobrazovßnφ v IE 5/Win, na kterΘm jsem v dob∞ psanφ Φlßnku menu netestoval. Na vÜech ostatnφch prohlφ₧eΦφch uveden²ch v Φlßnku a na IE 5.5/Win je zobrazenφ sprßvnΘ i u p∙vodnφch dvou p°φklad∙ û tedy a₧ na nep°esnΘ pozicovßnφ nßpov∞dy, kterΘ zde zmi≥uji.



Martin Snφ₧ek (3.12. 2002)

Redakce Interval.cz |  Inzerce na Interval.cz |  Hledßme novΘ autory ISSN 1212-8651 
 ⌐ Zoner software, s.r.o., vÜechna prßva vyhrazena, tento server dodr₧uje prßvnφ p°edpisy o ochran∞ osobnφch ·daj∙.