Sådan fixes IE7’s z-index bug med jQuery

Det er sæd­van­ligvis Inter­net Explorer, der kræver ekstra opmærk­somhed, workarounds og udviklingstid, når man skal gøre et web­site kom­pat­i­belt på tværs af web­browsere. Jeg har lige spenderet en del tid på at komme omkring en grov ren­der­ings­fejl i IE før ver­sion 8, der ram­mer den orden hvori CSS posi­tionerede HTML ele­menter  sta­bles. Jeg er rendt ind i IE’s z-index bug.

Opgaven: En lang række list items skal udstyres med fork­laringer i form af drop downs. HTML koden ser således ud.

<ul class="linklist">
  <li>
    <h4>Overskrift 1</h4>
    <a href="#" class="dropdown-trigger">Vis beskrivelse</a>
    <div id="beskrivelse-1">
      Beskrivende note der falder ned, når man klikker på linket "Vis beskrivelse".
    </div>
  </li>
  <li>
    <h4>Overskrift 2</h4>
    <a href="#" class="dropdown-trigger">Vis beskrivelse</a>
    <div id="beskrivelse-2">
      Beskrivende note der falder ned, når man klikker på linket "Vis beskrivelse".
    </div>
  </li>
</ul>

CSS koden ser således ud.

.linklist li {position:relative;width:270px;}
.linklist li div.hidden {display:none;} /* skjuler div'en, før den aktiveres med jQuery .slideDown() */
.linklist li div {
  background:#ddd;
  border:1px solid #ccc;
  left:0;
  padding:6px 12px 12px;
  position:absolute;
  top:20px;
  width:244px;
}

<div> ele­mentet bør således placere sig ovenpå <li> ele­menterne. Det virker bare ikke i IE før ver­sion 8, fordi stakke­or­de­nen er fejl­be­hæftet. Jeg prøvede at løse prob­lemet ved at definere en lavere z-index på <li> ele­menterne, end på <div> ele­menterne, men det løste ikke prob­lemet. De efter­føl­gende <li> ele­menter blev stadig vist ovenpå det aktive <div>ele­ment.

Efter en del søgn­ing på net­tet fandt jeg Vance Lucas’ jQuery-baserede løs­ning af prob­lemet:

$(function() {
  var zIndexNumber = 1000;
  $('div').each(function() {
    $(this).css('zIndex', zIndexNumber);
    zIndexNumber -= 10;
  });
});

Ideen er, dynamisk at vende stan­dard z-index stakke­or­de­nen af HTML ele­menterne om. Således sikrer man, at ele­menter, der lig­ger højere i kildeko­den også har en højere z-index orden på siden, hvilket burde løse ren­der­ing­sprob­lemet i IE.

Det løste ikke umid­del­bart mit prob­lem. Jeg havde imi­dler­tid andet­st­eds læst, at man skulle kunne løse prob­lemet ved at give det rel­a­tivt posi­tionerede omgivende ele­ment en højere z-index orden, end det abso­lut posi­tionerede element.

Det gav mig ideen til også at lave en Vance Lucas jQuery løs­ning på det rel­a­tivt posi­tionerede <li> ele­ment, men med en højere z-index orden. Altså:

$(function() {
  var LizIndexNumber = 1100;
  $('li').each(function() {
    $(this).css('zIndex', LizIndexNumber);
    LizIndexNumber -= 10;
  });
  var DivzIndexNumber = 1000;
  $('div').each(function() {
    $(this).css('zIndex', DivzIndexNumber);
    DivzIndexNumber -= 10;
  });
});

Og voila! Så virker det.