Náhledy různých verzí produktu čistě pomocí CSS

Před časem jsem potřeboval do stránky klienta dostat asi 15 různých verzí polepů, které si mohou zákazníci nechat dát na letadlo. Zvolil jsem střídání náhledů, které se aktivuje najetím myši na vzorek polepu. Výsledné řešení je založeno čistě na CSS. Ukážu vám, jak jsem postupoval, určitě se vám to bude někdy hodit.

Kam se chceme dostat

Začnu tím, že prozradím konec celé detektivky ;) Podívejte se na výsledek, ke kterému směřuje tento článek.

Líbí? Když navíc zdůrazním, že náhledy jsou dostupné okamžitě po najetí myší nad vzorek polepu – žádná prodleva, ve které by se tahal potřebný obrázek – mohli byste být už správně naladěni na pár řádků HTML a CSS.

HTML pódium

Vystačíme si s jedním div, který nám podrží obrázek letadla bez polepu a s jedním ol seznamem.

<div id="aircraftBlueprint">
  <img src="img/exterior/model.gif" alt="" width="406" height="172"/>
</div>

<ol id="exteriorSwitch" class="floatHolder">
  <li class="ext01"><a href="#"><span><strong>Design exteriéru č. 1</strong></span></a></li>
  <li class="ext02"><a href="#"><span><strong>Design exteriéru č. 2</strong></span></a></li>
  <li class="ext03"><a href="#"><span><strong>Design exteriéru č. 3</strong></span></a></li>
  <li class="ext04"><a href="#"><span><strong>Design exteriéru č. 4</strong></span></a></li>
  <li class="ext05"><a href="#"><span><strong>Design exteriéru č. 5</strong></span></a></li>
  <li class="ext06"><a href="#"><span><strong>Design exteriéru č. 6</strong></span></a></li>
  <li class="ext07"><a href="#"><span><strong>Design exteriéru č. 7</strong></span></a></li>
  <li class="ext08"><a href="#"><span><strong>Design exteriéru č. 8</strong></span></a></li>
  <li class="ext09 clrRgt" class="noMargin"><a href="#"><span><strong>Design exteriéru č. 9</strong></span></a></li>
  <!--  druhy radek vzorku  -->
  <li class="ext10 secondRow clrLft"><a href="#"><span><strong>Design exteriéru č. 10</strong></span></a></li>
  <li class="ext11 secondRow"><a href="#"><span><strong>Design exteriéru č. 11</strong></span></a></li>
  <li class="ext12 secondRow"><a href="#"><span><strong>Design exteriéru č. 12</strong></span></a></li>
  <li class="ext13 secondRow"><a href="#"><span><strong>Design exteriéru č. 13</strong></span></a></li>
  <li class="ext14 secondRow"><a href="#"><span><strong>Design exteriéru č. 14</strong></span></a></li>
  <li class="ext15 secondRow"><a href="#"><span><strong>Design exteriéru č. 15</strong></span></a></li>
  <li class="ext16 secondRow"><a href="#"><span><strong>Design exteriéru č. 16</strong></span></a></li>
</ol>

Jak to funguje

Ve zkratce: Přes obrázek čistého letadla v <div id="aircraftBlueprint"> budeme zobrazovat jednotlivé polepy, které máme uložené všechny v jednom obrázku průhledném na barvu pozadí. Docílíme toho tím, že po najetí myší na vzorek transformujeme span na blok o stejných rozměrech jaké má obrázek letadla a posuneme obrázek na pozadí tak, aby zobrazoval odpovídající náhled polepu.

Dva obrázky je vše, co potřebujeme a to včetně tlačítek se vzorky polepů

Obrázky

Budeme potřebovat dva obrázky – jeden s čistým letadlem a druhý s polepy. Začneme s letadlem, protože to nám určí, jaký rozestup musíme nechat mezi polepy, aby se při posunování obrázku na pozadí zobrazoval vždy jen jeden.

Obrázek č. 1 – čistý obrázek letadla, rozměr 406px × 172px



Obrázek č. 2 – ukázka části obrázku s polepy, celý obrázek obsahuje všech 16 polepů pod sebou

Výhoda posouvání obrázku na pozadí je v tom, že prohlížeč potřebuje stáhnout pouze jeden obrázek a pak už okamžitě reagují všechny vzorky na najetí myši a ihned se zobrazují náhledy. Navíc díky umístění na pozadí, nemusíme být naprosto pixelově přesní v přípravě obrázku se všemi polepy, protože můžeme odchylky pozicování dorovnat v CSS, jak si ukážeme vzápětí.

CSS zaklínadla

Konečně se mrkneme na nějaké CSS. Definice div pro obrázek čistého letadla a definice ol nepotřebují moc vysvětlování:

div#aircraftBlueprint {
  font-size: 0;
  line-height: 0;
}

ol#exteriorSwitch {
  margin: 20px 0;
  padding: 0;
  width: 100%; float: left;
}
  ol#exteriorSwitch li {
    list-style: none;
    float: left;
    margin: 0 15px 15px 0; padding: 0;
    border: 1px solid #ddd; /*kolem tlacitek vzorku*/
  }

U div#aircraftBlueprint jsme si zajistili, že obrázek nebude mít kolem pod sebou nějakou divnou mezeru (Explorer na tebe se dívám), u ol#exteriorSwitch potřebujeme pevné pixelové okraje, protože jakákoli mezera relativní k velikosti písma by mohla rozhodit překrývání polepů a vynulujeme standardní padding. Šířka na 100% a float: left; nám zaručí, že ol bude vědět o floatovaných li.

Nadefinujeme si náhledová tlačítka pro vzorky polepů.

ol#exteriorSwitch li a {
  display: block; width: 32px; height: 32px;
  text-decoration: none;
  background-image: url("../img/polep.gif");
}

Náhledová tlačítka jsou zajímavá tím, že pro ně nepoužijeme zvláštní obrázky, ale opět ten jediný velký obrázek se všemi polepy. V níže uvedených definicích pro každé tlačítko napozicujeme polep přes CSS do takové pozice, která se bude hodit jako vzorek designu. Opět tím přispíváme k rychlosti načtení stránky a k plynulému dojmu, který z ní bude uživatel mít.

A teď složitější. Nadefinujeme hover podobu pro span, který nám překryje nákres letadla designem polepu.

#exteriorSwitch li a span { display: none; }

ol#exteriorSwitch li a:hover span {
  display: block; width: 406px; height: 172px;
  background: url("../img/polep.gif") 0 0 no-repeat;
  position: relative;
    top: -190px;
  margin-bottom: -172px;
  margin-right: -406px;

  padding: 5px 0 0 0;
  font-size: 1.4em;
  color: black;
}
  #exteriorSwitch li.secondRow a:hover span {
    top: -240px; /*jine odsazeni pro druhy radek tlacitek*/
  }

  #exteriorSwitch li a:hover span strong {
    position: relative;
    z-index: 15;
    margin: 0;
  }

Vidíte, že v základu span nezobrazujeme, chceme ho vidět až na hover, kdy mu nadefinujeme stejnou šířku a výšku, jako má obrázek letadla a pomocí position: relativetop ho přesuneme nad něj. Ještě po něm negativními okraji zameteme stopy.

To ani nebolelo, ne? Hm, jenže teď přijde teprve ta dělničina: Potřebujeme napozicovat zvlášť pozadí pro každé tlačítko a pro každý span při hover. Ukážeme si to na příkladu prvních dvou li, pak už je to samé v bledě modrém.

Jako první nadefinujeme pozici polepu pro tlačítko se vzorkem a pak pro hover překrytí.

/*tlacitko vzoru*/
#exteriorSwitch li.ext01 a {
  background-position: -330px -35px;
}
  /*hover stav spanu*/
  #exteriorSwitch li.ext01 a:hover span {
    left: -1px;
  }

Pro první polep je jeho hover stav definován už výše, takže tady nic neměníme. Definice left: -1px; nám dorovnává span do správné pozice – rozhodil nám to border kolem tlačítka a možná i nepřesnost v obrázku. Tady se právě projevuje výhoda, kterou jsem už zmiňoval – nemusíme být naprosto přesní, na správné místo si polep napozicujeme v CSS.

Takže radostně na li číslo dva.

#exteriorSwitch li.ext02 a {
  background-position: -335px -205px;
}
  #exteriorSwitch li.ext02 a:hover span {
    left: -50px; /*32 + 15 + 3*/
    background-position: 0 -172px;
  }

Prostě posouváme obrázek na pozadí po ose y. Pro tlačítko se vzorkem navíc potřebujeme najít vhodnou část polepu, takže budeme muset měnit i souřadnici x. U span je drobná nepříjemnost v tom, že s jinou pozicí mateřského tlačítka se posunuje i výchozí pozice pro span, takže ho pomocí left: -50px vrátíme na správné místo.

A obdobně pro všechny ostatní tlačítka a hover stavy.

Pár poznámek závěrem

Výsledek a zdrojové soubory si můžete prohlédnout na zvláštní stránce.

Funkčnost v prohlížečích: Firefox (Win, Mac), Safari 2.0.4, Opera 9.10 (Win), IE 7.0, IE 6.0. Pro nižší verze IE už netestuju, počítám, že se tam rozhodí něco kvůli jejich chybnému box modelu, ale kdyby někdo chtěl, tak to nejspíš půjde vyladit.

V některých případech se metoda překrytí průhledným obrázkem nebude dát použít, ale to není žádný problém, budeme podklad prostě celý překrývat jiným obrázkem.

No a to je asi vše. Nápady, poznámky, připomínky?

4 komentáře