Posunutie anchoru aj v MSIE

Nový projekt so sebou prináša i nové riešenia použiteľnosti a opravy pre Internet Explorer. Projekt, na ktorom robím, má fixnú hlavičku a dlhé texty skryté pomocou JS. Pri rozbalení je potrebné, aby sa nadpis textu zobrazil pod hlavičkou. So štandardným HTML a CSS kódom to nie je žiaden problém.

Problém: fixná hlavička na vrchu stránky zaberá určitý priestor. Po kliknutí na cielený odkaz (#) sa stránka odskroluje tak, že cieľ odkazu (anchor: <a name=""></a>, alebo akýkoľvek element s atribútom id="" v moderných prehliadačoch) bude na vrchu stránky (bude mať nulovú výšku od horného okraja priezoru prehliadača). Pri fixnej hlavičke sa však zobrazí za hlavičkou.
Riešenie: posunutie cieľu odkazu (anchoru) pomocou CSS o výšku navigácie, aby sa nadpis zobrazil nižšie.

Hlavička je umiestnená pomocou position: fixed a fixnej pozície pre IE a má výšku 155px.

HTML kód:

<body>
...
<div class="item">
  <a name="p1-head" id="p1-head" class="target"></a>
  <h2>Nadpis 1</h2>
  <p>Text <a href="#p1-head">odkaz</a></p>
</div>
...
</body>

Cieľ odkazu treba od nadpisu posunúť o 155px vyššie. Môže sa nachádzať kdekoľvek v dokumente, použijeme teda relatívne pozíciovanie, ktoré posunie element o danú pozíciu z jeho aktuálneho miesta v dokumente.

a.target {
  position: relative;
  top: -155px;
}

/* je tiež možné použiť a[name] selektor */

Kód je samozrejme len pre moderné prehliadače (Firefox, Opera, Safari) a preto je možné alternatívne použiť a[name] alebo a[id] selektor.

Problém v IE: ako inokedy, toto v MSIE nebude fungovať. Po dlhom testovaní som zistil, že keď sa anchoru nastavia rozmery (width, height), pričom nezáleží na display: block/inline, element posunie relatívne, ale na jeho pôvodnom mieste sa vytvorí priestor (asi prázdeno textu), ktorý má rovnaké rozmery (okrem iného sa posunie celý obsah). Tento priestor je viediť pri označení textu myšou.

Keď relatívna pozícia nefungovala, skúsil som použiť inú možnosť na posunutie elementu. Tá musela spĺňať túto požiadavku: posunúť element vyššie podľa jeho pozície vypočítanej pri position: static.

Okrem vlastnosti topje možné posunúť aj pomocou margin-top. Pri použití margin-top: -155px sa však posunie aj celý statický obsah za elementom. Je teda nutné použiť ešte position: absolute. Absolútne poziciované prvky sú vyňaté z layoutu a svojou pozíciou neovplyvňujú iné prvky. Využívam tiež ďalšiu vlasnosť absolútnych prvkov: bez udania top/right/bottom/left atribútov je ich pozícia vypočítaná ako pri position: static.

Záporný margin-top „priťahuje“ element hore a teda MSIE nevytvára žiaden duplikovaný obsah (alebo ako tú podivnú vec nazvať).

Možno to bola náhoda, ale na odlaďovanie som používal border a nie background aby som videl rozmery elementu. Po úspešnom posunutí prvku hore v MSIE a odskúšaní fungovania cieľených odkazov som odstránil border, aby cieľ nebolo vidieť. Aké však bolo moje prekvapenie, keď zrazu anchory nefungovali. Po ďalšom textovaní som zistil, že fungujú jedine, ak majú nastavený viditeľný okraj – border. Nefunguje blokové zobrazenie s rozmermi, ani iné podobné techniky. Anchory musia mať nastavený viditeľný okraj!

Výsledné CSS:

.target {
  _position: absolute;
  _margin-top: -155px;
  _border: 1px solid white; /* !musí byť, ináč posunutie nefunguje v IE! */
  _visibility: hidden; /* skryjeme prvok */
}


.target[id] {
  position: relative;
  top: -135px;
}

Kód si môžete upraviť tak, aby bol validný a použiť ho napr. v spojení s podmienenými komentármi.