Sexy obrázkové menu pomocí CSS!
Na webu se dost často setkávám s hlavní navigací, která je řešena obrázky. Ty ale většinou nemají textovou alternativu, maximálně ALT (alternativní popisek obrázku), při vypnutých obrázcích pak nastává situace, že jdou vidět „jakési“ alternativní popisky bez jakékoli formy. Při vypnutých stylech, se pravděpodobně zobrazí opět ono obrázkové menu, mnoho kodérů totiž jednotlivé odkazy na sekce umísťuje do HTML do tagu <img>, což ale není nejlepší řešení, obrázkově ztvárněná navigace totiž patří celá do kaskádových stylů, v kódu má být pouze obsahová část… tedy nečíslovaný seznam. Vychází to z oné základní koderské filozofie.
Připravil jsem si pro vás obrázkovou navigaci, která splňuje tyto
požadavky, v HTML dokumentu je pouze obsah, vizuální podoba menu je
v kaskádových stylech. K tomu všemu si pohrajeme s posouváním
pozadí u prvků, ušetříme tím práci s dalšími soubory
(obrázky) a zmenšíme tak i datový objem celé navigace. Pokud tedy máte
čas, pohodlně se usaďte a pustíme se do toho. ![]()
Podíváme se nejdříve na hotové řešení, aby jste měli představu, co vás čeká. Jak vidíte zvolil jsem variantu horizontálního menu. Hover efekt není nic jiného, než změna barvy písma. Klidně si tam udělejte hezčí efekt, já se s tím moc nebabral. :o)
Rozebereme si, co pro takové přístupné menu musíme udělat:
- Grafické ztvárnění navigace
- Vytvoříme si holé HTML
- A teď to všechno pořádně osolíme, teda ostylujeme :o)
- Přidáme třídu .aktivni
- Závěrečné oslavy a ohňostroj xD
Grafické ztvárnění navigace
Tohle nechám na vás, jistě máte svůj oblíbený grafický editor, v kterém jste jako ryba ve vodě, nebo alespoň jako v akvárku :o). Udělejte si také hover variantu (při najetí myší na položku v menu). Umístěte jí pod vámi vytvořenou navigaci, nějak tak jako to dělám já ve svém příkladu.
Teď určitě čekáte, že to celé naporcujeme, pořádně to rozsekáme na jednotlivé sekce + jejich hover variantu. Uděláme z toho pořádný masakr, celé menu tak rozsekáme do 12 souborů (obrázků). Nikoliv! Celou navigaci uděláme pouze pomocí jednoho obrázku! No není to sexy? :o) Doporučuji vám oddělit jednotlivé položky v menu vodítky, zjednodušíte si pak počítání při posouvání pozadí v CSS.
Vytvoříme si holé HTML
Připravíme si HTML kód, budeme se zabývat pouze části s naším menu, nadpisy a odstavce v našem příkladu jsou jen pro názornost, to snad zvládnete sami, pokud ne můžete nahlídnout do zdrojového kódu samotného příkladu. Nejprve si připravíme holý nečíslovaný seznam, nebo sémanticky trochu lépe – použijeme tag <menu>. Přiřadíme všem prvkům <li> a odkazům <a> stejnou třídu, pokud v tom máte teď trochu guláš tak se nebojte, všechno si vyjasníme při stylování :o).
<div id="wrapper">
<menu>
<li class="home">
<a class="home" href="index.html"> </a>
</li>
<li class="product">
<a class="product" href="product.html"> </a>
</li>
<li class="sexypixely">
<a class="sexypixely" href="sexy.html"> </a>
</li>
<li class="templates">
<a class="templates" href="templates.html"> </a>
</li>
<li class="links">
<a class="links" href="links.html"> </a>
</li>
</menu>
</div>
Takhle by nám to stačilo v případě, že bychom se vykašlali na bez-obrázkové zobrazení a na situaci s vypnutými styly. Jenže my přece nejsme žádní flákači a uděláme to pořádně. Přidáme tedy <span>, do kterého nacpeme textovou variantu názvů našich položek menu, do spanu dáme další odkaz <a>, který povede na stejnou adresu, jako první odkaz. Tento odkaz tam dáváme kvůli zobrazení bez CSS stylů, kdybychom ho tam nedali, viděli bychom pouze nečíslovaný seznam, bez odkazů. Span umístíme za každý tag <a> s předem definovanou třídou. Takhle:
<div id="wrapper">
<menu>
<li class="home">
<a class="home" href="index.html"> </a>
<span> <a href="index.html"> Homepage </a> </span>
</li>
<li class="product">
<a class="product" href="product.html"> </a>
<span> <a href="product.html"> Product </a> </span>
</li>
<li class="sexypixely">
<a class="sexypixely" href="sexy.html"> </a>
<span> <a href="sexy.html"> Sexypixely </a> </span>
</li>
<li class="templates">
<a class="templates" href="templates.html"> </a>
<span> <a href="templates.html"> Templates </a> </span>
</li>
<li class="links">
<a class="links" href="links.html"> </a>
<span> <a href="links.html"> Links </a> </span>
</li>
</menu>
</div>
A teď to všechno pořádně osolíme, teda ostylujeme :o)
Zlehka pošimráme obecné styly a definujeme šířku a horizontální vycentrování divu #wrapper, který navigaci, nadpisy, odstavce… zkrátka celý obsah – obalí a vycentruje doprostřed stránky, ať jsme v jakémkoli rozlišení. Hvězdičkovou definicí si vynulujeme u všech prvků margin a padding, tím docílíme stejného zobrazení ve všech prohlížečích.
* {
margin: 0;
padding: 0;
}
body {
text-align: center;
font-family: sans-serif;
}
#wrapper {
width: 770px;
margin: 50px auto;
}
Teď nadefinujeme obecné styly pro <li> a taky ostylujeme všechny odkazy, kterým jsme dali třídu. Všimněte si dvou podstatných věcí… #wrapper menu li jsem nastavil position:relative; to z důvodu, aby v každém <li> mohli být absolutně umístěny odkazy s námi přidanou třídou a později i spany, které jsou v kódu hned za nimi, budou tedy přelepeny přes sebe jako dvě nálepky, my jenom určíme z-indexem jejich pořadí na ose Z :o). Druhá důležitá věc je právě to, že jsme všem těmto „otřídovaným“ odkazům definovali absolutní pozici a všem jsme také přiřadili stejné pozadí – navigace.png.
#wrapper menu li {
height: 58px;
float: left;
list-style: none;
position: relative;
background: #1A1919;
}
#wrapper menu li a.home, a.product, a.sexypixely, a.templates, a.links {
height: 58px;
display: block;
position: absolute;
top: 0;
left: 0;
z-index: 1;
background: url(navigace.png) no-repeat;
}
Každá položka v navigaci, kterou jsem navrhl má jinou šířku. Musíme tedy každému <li> a odkazu <a>, který je v něm, nastavit specifickou šířku.
#wrapper li.home, a.home {
width: 155px;
}
#wrapper li.product, a.product{
width: 158px;
}
#wrapper li.sexypixely, a.sexypixely {
width: 166px;
}
#wrapper li.templates, a.templates {
width: 163px;
}
#wrapper li.links, a.links {
width: 128px;
}
Tak a teď začneme posunovat pozadí u odkazů, kterým jsme dali třídu podle názvu položky. Uděláme najednou posunutí i při hover efektu, ať to máme pěkně při sobě. Posouvání pozadí funguje na principu záporných hodnot na ose X a Y. Tady se vám budou parádně hodit ty vodítka, které jste si udělali ve vašem grafickém editoru. Snadno teď zjistíte, kolik pixelů mají na šířku jednotlivé položky. První položka – odkaz se třídou .home v našich stylech nemusí vůbec být, dal jsem ji tam jen názorně, aby jste nebyli zmateni, proč nám chybí. Pozice pozadí 0 0 je totiž auto! :o)
Při počítání posunutí pozadí vždycky přičtete k předchozí
hodnotě tu, kterou jste si změřili v grafickém editoru. Vyjde vám tak
místo na obrázku, od kterého se začne zobrazovat pozadí další položky.
Chápete ne? :o) Prostě 155px + 158px je přece –313px. ![]()
#wrapper a.home {
background-position: 0 0;
}
#wrapper a.home:hover{
background-position: 0 -59px;
}
#wrapper a.product {
background-position: -155px 0;
}
#wrapper a.product:hover {
background-position: -155px -59px;
}
#wrapper a.sexypixely {
background-position: -313px 0;
}
#wrapper a.sexypixely:hover {
background-position: -313px -59px;
}
#wrapper a.templates {
background-position: -479px 0;
}
#wrapper a.templates:hover {
background-position: -479px -59px;
}
#wrapper a.links {
background-position: -643px 0;
}
#wrapper a.links:hover {
background-position: -643px -59px;
}
Teď ještě ostylujeme <span> a chování odkazu v něm. Všimněte si, že spanu jsem taky definoval absolutní pozici a důležitou věc > z-index:0; který nám zajistí, že <span> se schová pod námi ostylovaný odkaz výše. Levý padding nám textovou variantu položek posune o 40px doprava, určitě by šlo tohle vyřešit i jinak.
Nastavíme taky chování textových odkazů uvnitř spanu. Vlastnost line-height nám pomůžeme vertikálně vycentrovat onen textový odkaz, dáme mu barvu… to samé pro hover… modrou… a nastavíme vlastnost cursor: na hodnotu pointer, tím pomůžeme Internet Exploreru pochopit to, že po něm chceme, při najetí myši zobrazit cursor ručičky :o)
#wrapper menu li span {
position: absolute;
z-index: 0;
top: 0;
left: 0;
padding-left: 40px;
}
#wrapper menu li span a {
color: #FFFFFF;
line-height: 58px;
text-decoration: none;
}
#wrapper menu li:hover span a {
color: #1C9FC4;
cursor:pointer;
}
A to je ze stylování všechno milí přátelé xD. Ještě ale budeme muset něco málo přidat pro zobrazení třídy .aktivni.
Přidáme třídu .aktivni a třídy s příponou _aktivni
Třída .aktivni nám zvýrazní vybranou textovou položku v navigaci (při zobrazení bez obrázků), na které se zrovna nacházíme. Prostě zvýraznění aktuální stránky, znáte to ne? … třeba ze záložek… :o)
Budeme k tomu potřebovat přidat speciální třídy odkazům, které mají na pozadí právě to obrázkové menu, vytvoříme tak všem třídám příponu _aktivni… třídy pak budou vypadat takto >>> .home_aktivni, .sexypixely_aktivni a tak dále. Na každé stránce pak bude logicky jen jedna položka, která bude aktivní tudíž přidáme třídu .aktivni a příponu k odkazu _aktivni pouze té položce, která je na stránce. Pokud by šlo o dynamické menu, tak chytrým kolegům programátorům by nedělalo moc problém přidat proměnou, která by nám tam třídu .aktivní, či třídu home_aktivni atd. vložila. :o) Zapíšeme si to tedy do HTML.
<menu>
<li class="home aktivni">
<a class="home_aktivni" href="index.html"> </a>
<span> <a href="index.html"> Homepage </a> </span>
</li>
<li class="product">
<a class="product" href="product.html"> </a>
<span> <a href="product.html"> Product </a> </span>
</li>
<li class="sexypixely">
<a class="sexypixely" href="sexy.html"> </a>
<span> <a href="sexy.html"> Sexypixely </a> </span>
</li>
<li class="templates">
<a class="templates" href="templates.html"> </a>
<span> <a href="templates.html"> Templates </a> </span>
</li>
<li class="links">
<a class="links" href="links.html"> </a>
<span> <a href="links.html"> Links </a> </span>
</li>
</menu>
Přiřadíme třídě .aktivni styl, který odkazu ve spanu přiřadí modrou barvu, nic jiného na tom není.
#wrapper menu li.aktivni span a {color:#1C9FC4;}
Tyto třídy, s příponou _aktivni, budou mít úplně stejně definované vlastnosti jako ty stejné třídy bez přípony, kromě posunutí pozadí, to musí být nastaveno právě tak stejně, jako při hover efektu. Doufám, že to chápete :o) Přidáme tedy tuto definici za hover zmiňovaných tříd .home, .sexypixely atd.
#wrapper a.home:hover, a.home_aktivni {
background-position: 0 -59px;
}
#wrapper a.product:hover, a.product_aktivni {
background-position: -155px -59px;
}
#wrapper a.sexypixely:hover, a.sexypixely_aktivni {
background-position: -313px -59px;
}
#wrapper a.templates:hover, a.templates_aktivni {
background-position: -479px -59px;
}
#wrapper a.links:hover, a.links_aktivni {
background-position: -643px -59px;
}
Závěrečné oslavy a ohňostroj xD
Tak to by mělo být vše, neprovedl jsem tam připsání těch aktivních tříd k těm odkazům se třídou, to uvidíte až v posledním finálním přehledu celého CSS. Doufám, že jste pochopili podstatu věci. Pokud ne, podívejte se do závěrečného přehledu níže. Pokud vám to nebude ani tak jasné, zeptejte se v komentářích! Tohle je můj první vysvětlovací článek, omluvte tak jakousi nepřehlednost a neučesanost. :o)
Závěrečný přehled:
<menu>
<li class="home aktivni">
<a class="home_aktivni" href="index.html"> </a>
<span> <a href="index.html"> Homepage </a> </span>
</li>
<li class="product">
<a class="product" href="product.html"> </a>
<span> <a href="product.html"> Product </a> </span>
</li>
<li class="sexypixely">
<a class="sexypixely" href="sexy.html"> </a>
<span> <a href="sexy.html"> Sexypixely </a> </span>
</li>
<li class="templates">
<a class="templates" href="templates.html"> </a>
<span> <a href="templates.html"> Templates </a> </span>
</li>
<li class="links">
<a class="links" href="links.html"> </a>
<span> <a href="links.html"> Links </a> </span>
</li>
</menu>
* {
margin: 0;
padding: 0;
}
body {
text-align: center;
font-family: sans-serif;
}
#wrapper {
width: 770px;
margin: 50px auto;
}
#wrapper menu li {
height: 58px;
float: left;
list-style: none;
position: relative;
background: #1A1919;
}
#wrapper menu li a.home, a.product, a.sexypixely, a.templates,
a.links, a.home_aktivni, a.product_aktivni, a.sexypixely_aktivni,
a.templates_aktivni, a.links_aktivni {
height: 58px;
display: block;
position: absolute;
top: 0;
left: 0;
z-index: 1;
background: url(navigace.png) no-repeat;
}
#wrapper menu li span {
position: absolute;
z-index: 0;
top: 0;
left: 0;
padding-left: 40px;
}
#wrapper menu li span a {
color: #FFFFFF;
line-height: 58px;
text-decoration: none;
}
#wrapper menu li:hover span a {
color: #1C9FC4;
cursor:pointer;
}
#wrapper menu li.aktivni span a {color:#1C9FC4;}
#wrapper li.home, a.home, a.home_aktivni {
width: 155px;
}
#wrapper li.product, a.product, a.product_aktivni {
width: 158px;
}
#wrapper li.sexypixely, a.sexypixely, a.sexypixely_aktivni {
width: 166px;
}
#wrapper li.templates, a.templates, a.templates_aktivni {
width: 163px;
}
#wrapper li.links, a.links, a.links_aktivni {
width: 128px;
}
#wrapper a.home {
background-position: 0 0;
}
#wrapper a.home:hover, a.home_aktivni {
background-position: 0 -59px;
}
#wrapper a.product {
background-position: -155px 0;
}
#wrapper a.product:hover, a.product_aktivni {
background-position: -155px -59px;
}
#wrapper a.sexypixely {
background-position: -313px 0;
}
#wrapper a.sexypixely:hover, a.sexypixely_aktivni {
background-position: -313px -59px;
}
#wrapper a.templates {
background-position: -479px 0;
}
#wrapper a.templates:hover, a.templates_aktivni {
background-position: -479px -59px;
}
#wrapper a.links {
background-position: -643px 0;
}
#wrapper a.links:hover, a.links_aktivni {
background-position: -643px -59px;
}
Toto řešení jsem vymyslel sám, nepátral jsem, jestli něco
podobného existuje… podle mě určitě ano, určitě i lepší řešení.
Pokud něco takového najdete, budu rád, když hodíte do komentářů odkaz
.





BoB 25. 1. 2008 | 16.58
Pěkné, pěkné, měl bych však pár připomínek.
V takovémto řešení:
A v rámci předvedeného dema by celého výsledku šlo dosáhnout jednodušeji,
avšak chápu, že to už je jen otázkou grafického odlišení obrázků.
Fred 25. 1. 2008 | 19.12
Přesně jak píše Bob, tady je moje řešení http://concer.to/test.html
Adam Marčan 26. 1. 2008 | 1.13
BoB>
ad 1) při obrázkové verzi je to logické :o), při textové alternativě zvětšování bez problému funguje…
ad 2) ano, ale o tom je celá obrázková metoda… vypadá dobře, huře se edituje…
ad 3) mě se taky moc nelíbí, ale je to kvůli IE6, která nezvládá hover efekt na žádném jiném elementu než na <a>
Fred>
Nelíbí se mi moc v tvé verzi použití prázdného tagu EM… co tam chceš zvýrazňovat?… není to moc sémanticky dobře… kód je sice v tvé verzi štíhlejší, ale bez obrázků jsi to nedostyloval, podivej se na mojí a tvojí variantu bez obrázků, nevím jak docílíš aktivního zvýraznění textové verze…
BoB 26. 1. 2008 | 21.33
Adam >
Adam Marčan 27. 1. 2008 | 11.46
BoB>
jo určitě bych mohl, někdy ale v grafickém návrhu použiješ font, který není systémovým písmem, pak není jiná cesta :o)
Lery 27. 1. 2008 | 23.04
no pěkný návod. sice mi to příjde složitější jak java ale to nevadí, kdybych nad tím hodně dlouho zauvažoval tak bych to možná zvládnul.. Sice mi jsou trochu záhadou mínusové hodnoty u toho pozicování ale tak snad se o tom pobavíme někdy při kofole v hospodě ;)
Dx 28. 1. 2008 | 0.50
Každý to má jinak Lery a třeba mi příjde Java 10× náročnější než tohle. Pokud se nepletu, tak mínusové hodnoty pozic slouží k posouvání zobrazené části těch obrázků.
Lery 28. 1. 2008 | 16.42
takže když tam je mínus a nějaké číslo tak se obrázek posune. ale kam?:D
Adam Marčan 28. 1. 2008 | 18.31
Lery>
myslel jsem, že to teda proberem až při té kofole
Tak jak psal Dx slouží to k posunutí obrázku na pozadí, záporné hodnoty se použivají proto, aby se posunul obrazek, který pak bude v daném prvku na souřadnicích left:0; top:0; … pokud bychom použili kladné hodnoty, obrázek na pozadí by se začal zobrazovat např. 20px od vrchu a 50px z leva… nad ním by pozadí nebylo… chápeš? pokud ne, tak to necháme asi až na tu kofolu xD
Lery 30. 1. 2008 | 0.10
jo už to chápu.. ale kofolu dáme stejně:D
vertigo4 4. 2. 2008 | 17.27
při použití tohoto písma mi ale přijde zbytečné používat obrázkové menu… dá se to nahradit jedním obrázkem a nemusí se nic posouvat a navíc je to lepší pro SEO
Adam Marčan 4. 2. 2008 | 18.02
Použitý font není systémovým písmem, proto to není zbytečné. Obrázková navigace s textovou variantou je to nejmenší zlo pro vyhledávací stroje… spíš bych se zaměřil na kritiku obsahu a jeho strukturu než na obrázkovou navigaci…
danaketh 13. 2. 2008 | 14.43
vertigo4> Mohu se zeptat, proč řešíte použitý font? Od začátku jde přece o ukázku způsobu řešení obrázkového menu pomocí CSS, tudíž je naprosto jedno, jaký font byl v obrázcích použit :)
J.P. 17. 4. 2008 | 20.56
zkuste omrknout sexy řešení menu na http://www.apple.com Už to tam mají více jak rok ;)
Gul 29. 4. 2008 | 9.16
J.P. Je to hezké, ale moc se mi nelíbí zvýraznění aktivní sekce pomocí javascriptu. Raději bych nějaký class v li prvku. Ale asi to bude tím, že moc javascript neovládám
Noby 29. 1. 2009 | 14.31
Nejlepší řešení co snad existuje:
http://maciweb.net/blog/web/priklady/iehover.html
-arne- 22. 6. 2009 | 21.14
jen k tomu vynulování paddinku a marginu tou hvězdičkou, to je sice hezké, ale pak nefungují korektně „li“ seznamy někde v textu stránky, protože ty puntíky lezou mimo doleva…
Adam Marčan 4. 8. 2009 | 11.08
arne > Nic přece nebrání tomu, globálně elementům <li> ten chybějící margin nastavit, ne? ;o)
Hvězdičkové nulování je jedna ze základních praktik, jak donutit prohlížeče, aby vykreslovali elementy stejně.
Fergie 5. 9. 2010 | 0.49
Dik moc, dost jsi mi pomohl a usetril nekolik hodin :D
Rozky 16. 1. 2011 | 21.47
Díky, moc pomohlo!