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.

Obrázek Navigace

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>
     <a href="index.html"> </a>
  </li>

  <li>
     <a href="product.html"> </a>
  </li>

  <li>
     <a href="sexy.html"> </a>
  </li>

  <li>
     <a href="templates.html"> </a>
  </li>

  <li>
     <a 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>
      <a href="index.html"> </a>
      <span> <a href="index.html"> Homepage </a> </span>
  </li>

  <li>
       <a href="product.html"> </a>
       <span> <a href="product.html"> Product </a> </span>
  </li>

  <li>
       <a href="sexy.html"> </a>
       <span> <a href="sexy.html"> Sexypixely </a> </span>
  </li>

  <li>
       <a href="templates.html"> </a>
       <span> <a href="templates.html"> Templates </a> </span>
  </li>

  <li>
       <a 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:rela­tive; 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 .homev 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_ak­tivni 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>
      <a href="index.html"> </a>
      <span> <a href="index.html"> Homepage </a> </span>
  </li>

  <li>
       <a href="product.html"> </a>
       <span> <a href="product.html"> Product </a> </span>
  </li>

  <li>
       <a href="sexy.html"> </a>
       <span> <a href="sexy.html"> Sexypixely </a> </span>
  </li>

  <li>
       <a href="templates.html"> </a>
       <span> <a href="templates.html"> Templates </a> </span>
  </li>

  <li>
       <a 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)

Výsledek tady!

Závěrečný přehled:

<menu>

  <li>
      <a href="index.html"> </a>
      <span> <a href="index.html"> Homepage </a> </span>
  </li>

  <li>
       <a href="product.html"> </a>
       <span> <a href="product.html"> Product </a> </span>
  </li>

  <li>
       <a href="sexy.html"> </a>
       <span> <a href="sexy.html"> Sexypixely </a> </span>
  </li>

  <li>
       <a href="templates.html"> </a>
       <span> <a href="templates.html"> Templates </a> </span>
  </li>

  <li>
       <a 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 ;-).