Když při :hover mění text svoji šířku…

Když při :hover mění text svoji šířku, poukazuje to na nedostatečné splynutí webdesignerovy mysli s duchem internetu. Konkrétně se jedná o případ, kdy tvůrce webu chce, aby při najetí myši na odkaz změnil text odkazu svůj řez. Nebo aby se ztučnil. Vykreslil se kurzívou. Zvětšil prostrk mezi jednotlivými písmeny. Cokoliv, co většina z vás pravděpodobě považuje za nepřirozené.

Po delší době jsem zavítal na diskusi jakpsatweb.cz. Narazil jsem na poměrně zajímavý dotaz, který se týkal přesně problému, který jsem nastínil výše.

Zlobivá kurzíva

Uživatel Celebi žádal o pomoc při řešení problému, kdy při najetí myši na odkaz mění text odkazu sklon textu z normálního na kurzívu. Kurzívou psaný text je však o něco málo širší než text normální, proto se při najetí vždy následující text posunul, což samozřejmě není zamýšlené chování. Problém můžeme zapsat například takto:
<style type="text/css">
  * { font-family: "Times New Roman", serif; }
  a { color: red; }
  a:hover { color: blue; font-style: italic; }
</style>
...
<p>
  Lorem ipsum dolor sit amet, <a href="#">consectetuer adipiscing</a> elit. In nulla mauris...
</p>

Podívejte se na ukázkovou stránku a najeďte na odkaz. Uvidíte, že zbytek řádku se posune vpravo, možná se i nějaké to slůvko přemístí na nový řádek, čímž způsobí hotové kaskádovité kataklyzma, kdy se přemístí i slovo z dalšího řádku, a to způsobí přesun slova z řádku následujícího… myslím, že nemusím pokračovat. Toto chování je tedy jednoznačně nežádoucí.

Rozbor problému

Hned na úvod musím říci, že všechny odpovědi v odkazované diskusi obsahovaly radu, aby se při hoveru styl písma vůbec neměnil. Toto je i mé stanovisko a předesílám, že v tomto případě více než v jakémkoliv jiném platí, že vyřešit problém znamená se mu vyhnout.

Jak však zjistit šířku tohoto prostoru? Nějaká konstanta nepřipadá v úvahu, což dokazuje toto řešení-neřešení:

<style type="text/css">
  * { font-family: "Times New Roman", serif; }
  a { color: red; padding-right: 0.7em; }
  a:hover { color: blue; font-style: italic; padding: 0; }
  .vetsi { font-size: 120%; }
</style>
<p>
  Lorem ipsum dolor sit amet, <a href="#">consectetuer adipiscing</a> elit. In nulla mauris...
</p>
<strong><p class="vetsi">
  Lorem ipsum dolor sit amet, <a href="#">consectetuer adipiscing</a> elit. In nulla mauris&hellip;
</p></strong>

Definoval jsem dva odstavce o odlišné velikosti textu (ukázka). Odkazům jsem „natvrdo“ přidal pravé vnitřní odsazení o šířce 0.7 čtverčíku, které při najetí myši zruším. Při standardní velikosti textu by mělo tohle nastavení ošetřit situaci v prvním odstavci. Druhému odstavci, ve kterém je definováno větší písmo, však tohle odsazení vyhovovat nebude. Šlo by jistě dosáhnout zajímavých výsledků při použití jiných kombinací jednotek, avšak univerzální řešení takto nestvoříte. Je to tedy slepá ulička.

Obecné řešení

Je třeba definovat kontejner o šířce, která bude stejná jako text odkazu po najetí myši. Do tohoto kontejneru pak odkaz umístit. Tím se zajistí optimální prostor pro rozšířený text. Vložíme tedy odkaz do neutrálního řádkového elementu, spanu. Tento span musí být stejně široký jako odkaz v hoveru. Vpíšeme do něj tedy stejný text jako do odkazu a nastavíme mu, aby jej vykresloval kurzívou. V této chvíli se nastavená kurzíva zdědí i odkazem, proto mu nastavíme normální sklon.
<style type="text/css">
  * { font-family: "Times New Roman", serif; }
  a { color: red; font-style: normal; }
  a:hover { color: blue; font-style: italic; }
  span { color: #bbb; font-style: italic; }
</style>
...
<p>
  Lorem ipsum dolor sit amet, <span>consectetuer adipiscing<a href="#">consectetuer adipiscing</a></span> elit. In nulla mauris...
</p>

Teď máme span široký jako text při hoveru + text bez hoveru (ukázka). Naším cílem je teď span o šířku odkazu bez hoveru zkrátit. Když se podíváte na příklad, jistě vás napadne řešení. Ano, stačí pomocný text ve spanu zneviditelnit, absolutní pozicování využít k vyjmutí odkazu z dokumentu a jeho přesunutí na začátek spanu. Tím se span zkrátí o šířku odkazu a ustálí se na šířce svého obsahu, která odpovídá šířce odkazu po najetí myši. Zní to složitě, vím, ale kód mluví zcela jasně:

<style type="text/css">
  * { font-family: "Times New Roman", serif; }
  a { color: red; font-style: normal; position: absolute; top: 0; left: 0; visibility: visible; }
  a:hover { color: blue; font-style: italic; }
  span { color: #bbb; font-style: italic; position: relative; visibility: hidden; white-space: pre; }
</style>
...
<p>
  Lorem ipsum dolor sit amet, <span>consectetuer adipiscing<a href="#">consectetuer adipiscing</a></span> elit. In nulla mauris...
</p>

Shrnutí

Zkušenější tvůrci mezi vámi se již ušklíbají. Ano, tohle řešení je samozřejmě v praxi nepoužitelné. Tolik zbytečného kódu kvůli jedné estetické libůstce, navíc nepřístupného, by mohl použít jen blázen. Přesně tak, po dnešku totiž může. :o)

Umíte lépe?

Uvedený kód jsem stvořil na koleni, je tedy velmi pravděpodobné, že existuje lepší řešení. Možná snad i řešení přístupné, nevyžadující obalové prvky a duplikaci textu. V tom případě bych byl rád, kdybyste se o takové řešení mohli podělit v komentářích. Díky!
14. 5. 2006, 16.00 | (X)HTML, CSS.


Zanechte komentář





Můžete použít Texy! formátování.
Pokud se obsah boxů níže mění, zatímco píšete, potom žádné číslice nevyplňujte. V takovém případě antispam funguje, pouze se prohlížeči nepovedlo skrýt tento box.