z-index в IE6-7
Проблема
В IE6-7 элементы, находящиеся в блоках с position: absolute/relative, не воспринимают z-index.
Теория
Согласно спецификации CSS 2.1 каждый позиционируемый блок имеет значение z-index (по умолчанию z-index: auto, что эквивалентно z-index: 0). Чем больше это значение, тем выше элемент по z-оси. При равных значениях z-index, будет показан тот элемент, который по HTML коду ниже. Но IE6-7 и их Mac версии это правило игнорируют:
- z-index элемента зависит от z-index родителя (и не может быть больше значения родителя в общем потоке);
- z-index с заданным числом может перекрываться z-index: auto.
Например, возьмем 2 блока, идущих друг за другом с position:relative — header и content. В header у нас есть выпадающее меню(menu), которое позиционируется с помошью position:absolute; , и частично перекрывает блок content. Присваиваем menu z-index:1000 (чтобы явно было больше, чем у других блоков) — menu должно быть поверх блока content.
HTML код
<div class="header"><div class="menu"></div></div> <div class="content"><div>
CSS код
.headaer { [...] position: relative; } .menu { [...] position: absolute; z-index: 1000; } .content { [...] position: relative; }
Результат.
Для IE6 не сработает выпадение меню(лень было делать javascript для отмирающего браузера).
В данном примере в браузерах IE6 и IE7 блок menu не перекрывает блока контента, так как IE принимает во внимание z-index родителей, при чём z-index родителя важнее, чем у данного элемента.
В IE меню не перекрыло контент - z-index проигнорирован |
В FF с z-index все нормально |
Решение
Явно задаем z-index родителям. При чем z-index родителя, в котором будет всплывающий элемент, должен быть больше, блока, который будет перекрываться:
По идее для menu можно не задавать z-index, но для уверенности все же можно указать. CSS код:
.headaer{ [...] position: relative; z-index: 2; } .menu{ [...] position: absolute; z-index: 3; } .content { [...] position: relative; z-index: 1; }
Результат. А теперь представь ситуацию, когда идет ряд блок друг за другом и в каждом есть появляющийся блок, например в строки таблицы. Придется учитывать чтобы у каждого последующего блока z-слой был ниже, чем у предыдущего:
В ручную не всегда удастся задать z-index, особенно в тех случаях, когда на перед неизвестно сколько будет блоков. В тах случаях выручает javascript.
Решение с помощью jQuery
Ниже пример подобного решения с применением jQuery:
$(function() { var zIndexNumber = 1000; $('div').each(function() { $(this).css('zIndex', zIndexNumber); zIndexNumber -= 10; }); });
Вариант без jQuery
update by Dmitry Balan: нормальные браузеры слои расставят и так нормально, для IE же можно воспользоваться подобным expression:
div{ behavior:expression(onmouseover=function(){this.className +=" zindex"},onmouseout=function() this.className=this.className.replace("zindex","")},style.behavior=null);} .zindex { z-index:1000; }
Смысл в том, что родителю, на который навели мышью, присваиваем z-index больше, чем у остальных блоков. У этого способа есть плюс — не нужно подключать библиотеки или внешние js-файлы.
Материалы
- IE7 lessons learned: the z-index bug
- Fixing IE7 Z-Index Issues with jQuery
- Effect of z-index value to positioned elements