Internet Explorer и z-index

07 Dec, 2008

ИЕ воспринимает z-index не совсем так, как все остальные браузеры. Это поведение настолько часто встречается в моей жизни, что я решил о нём написать целый пост.
Меня часто просят поправить ошибки в верстке. Так вот эта — входит в топ-5.

z-index работает?

Да, совершенно точно работает. Берем два блока, с position:absolute (для работы z-index нужен либо relative либо absolute) Задаем им обоим что-то такое:
  1. #block1, #block2{
  2. position:absolute
  3. }
  4. #block1{z-index:10}
  5. #block2{z-index:20}

иллюстрация z-indexНа самом деле, мне просто больше нравятся зеленые блоки.
Не обращайте внимания на Гитлера.

Блок с большим z-index отобразится поверх блока с меньшим z-index. Все как бы работает. И в IE в том числе.

работает, но...

Классическая обстановка для «проблемы в вёрстке».

В коде идут подряд два блока с position:relative. Например, два блока новости, или блоки вроде header и content. В relative ничего необычного нет, может добавили для absolute блоков внутри, или для хаков.
Как-то так:

  1. <div class="entry"></div>
  2. <div class="entry"></div>
И теперь, например, в одном из них появляется всплывающее окошко, или попап, или выпадающее меню:
  1. <div class="entry">
  2. <div class="popup">Попап</div>
  3. </div>
  4. <div class="entry"></div>
И такой вот дизайн:

поведение всех броузеров кроме ИЕПопап должен находиться в блоке 1

Будь вы мной, вы написали бы такой CSS:
  1. .entry{
  2. position:relative
  3. }
  4. .popup{
  5. position:absolute;
  6. z-index:10;
  7. top:10px;left:100px;
  8. }
Если добавить цвета и размеры, все отобразится и правда так, как в дизайне. Но, разумеется, не в ИЕ.

Там это будет выглядеть так:

так выглядит в ИЕПопап или выпадающее меню скроется за следующие блоки

Я это понимаю так: ИЕ сравнивает не только z-index блоков, но и z-index их родителей. Причем родительский важнее. В моем примере роль «родительского z-index» исполняет просто последовательность блоков в коде. Какие блоки дальше в коде, те и отобразятся поверх.

Я сделал специальный пример, смайлик из acid-теста будет улыбаться всем браузерам кроме ИЕ. (его улыбка зависит от этого вот поведения с relative блоками)

решение?

  1. Убрать position:relative для .entry
  2. Задавать разные z-index для .entry. В случае новостей это невозможно, они ведь генерируются симметрично. Однако когда у нас header и content, вполне подходит.
Может быть есть еще?

В конце

Мне не хочется называть это багом, поскольку для него требуется куча обстоятельств, скорее всего не описанных w3c. (или описанных?) Поведение имеет место в IE5-7. И, наверное, 8. Как всегда буду рад вашему опыту и мыслям по этому поводу. Статьи на тему этого поведения:

48 комментариев к “Internet Explorer и z-index”

1.nbaksalyar | 22 Jul, 2009
Огромное спасибо! После получасовых мучений с IE наконец-то помогло :)
2.akella | 26 Apr, 2009
Ну убрать relative для .entry не значит отказаться от него совсем, просто нужно попробовать применить его к другому элементу, чему-то внутри .entry, чтобы обойти баг в ИЕ.
3.Wincert | 25 Apr, 2009
Столкнулся со второй проблемой... >решение? >Убрать position:relative для .entry С таким же успехом можно было бы написать: "Уволиться с должности верстальщика" - тоже неплохое решение этой проблемы. В реальных ситуациях position:relative не появляется просто так, если он стоит значит он там очень нужен. Пол сайта придется теперь переверстывать (((
4.цук | 08 Apr, 2009
Никто не думал менять z-index у главного родительского елемента на 1000 к примеру при событии вызывающим попап (js естественно)?это решит ваши проблемы. И даже в том случае если у идущих подряд блоков индексы отличаются задайте их в диапазоне от 0 до 999.Этого диапазона вам за глаза хватит и попап всегда будет поверх. ЗЫ на возгласи типо "js может быть отключен в браузере" я отвечу: "У кого в браузере отключен javascript тому и попапы не нужны.
5.Анатлий | 02 Apr, 2009
Спасибо ОГРОМЕННОЕ!
6.zmey | 09 Mar, 2009
спасибо за разъяснения
7.Dimox | 07 Dec, 2008
Очень мешает данное поведение IE, когда, бывает, хочется хитро извернуться в верстке. В результате приходится перемещать некоторые элементы кода в другое место. P.S. Юра, что стало со шрифтом на блоге? Шрифт стал мелким и пропало сглаживание.
8.Юрко | 07 Dec, 2008
Ваш дiзайн — отстой!
9.Genn | 07 Dec, 2008
Никто никогда не обращает внимания на Гитлера.
10.Евгений | 07 Dec, 2008
абсолютные блоки для осла нужно перемещать в конец body. то есть, когда popup включаем, то перед этим делаем так $('.popup').insertBefore($(body));
11.angizij | 07 Dec, 2008
Не обращайте внимания на Гитлера. это из 3-х Tt Crowd ? )
12.Spirit | 07 Dec, 2008
У меня самая распространенная проблема с z-index'ом - это выпадающие меню и какой-то absolute-ный или relative-ный контент. Лечилось выставлением z-index:1 для родителей выпадающего элемента по-очереди.
13.jahson | 07 Dec, 2008
Всё дело в волшебных контекстах стэков :) У ИА с ними особое отношение.
14.pepelsbey | 07 Dec, 2008
Вот матерем клянусь — видел решение этой проблемы. Попробую применить гипноз и вспомнить…
15.pepelsbey | 07 Dec, 2008
Нашёл! Да здравствует делишез — Effect of z-index value to positioned elements
16.akella | 07 Dec, 2008
Да, но его способ это задать для блоков-родителей z-index =(. Это обычно невозможно когда у нас список новостей, я ж как раз этот способ и написал (#2) @Dimox, боюсь что ты установил себе на винду шрифт Myriad. Ничего не могу поделать с ее пахабным сглаживанием к сожалению =( IT Crowd хорош ;)
17.pepelsbey | 07 Dec, 2008
@akella: ну, почему — если мы правим баги для IE, то вполне можно использовать одноразовый expression, который расставит z-index'ы по списку.
18.akella | 07 Dec, 2008
И правда, забыл о нашем колдовстве :) Я, правда, решил по-другому, ставил position:relative блоку только при :hover. Таким образом его "деть" как и он сам был "на высоте" по сравнению с остальными без relative.
19.Genn | 07 Dec, 2008
angizij, Вы будете удивлены, но чувство юмора есть не только у британских сценаристов.
20.jahson | 08 Dec, 2008
Как это ни банально, но http://css-discuss.incutio.com/?page=OverlappingAndZIndex И там всё есть )
21.akella | 08 Dec, 2008
Спасибо! Добавил в пост =)
22.SelenIT | 08 Dec, 2008
Спасибо! Буквально вчера пытался сам разобраться в спеке, кто из браузеров прав (причем мое имхо склонялось в пользу старых эксплореров). А тут по ссылкам в три клика нашлось доходчивое объяснение, почему правы современные браузеры, а IE6-7 заблуждаются :). Кстати, в самом стандартном режиме IE8 c z-index'ами уже тоже все в порядке. Хотя своих приколов с позиционированием пока тоже хватает, надеюсь, к релизу исправят...
23.xaOz | 09 Dec, 2008
Гитлер форева. Тьфу блин в смысле прикольно, но больше Гитлера не надо ). Шрифт в Висте ужасен полностью согласен - муть какая-то :(
24.Snowcore | 10 Dec, 2008
скажите, а z-index одинаково ведет себя в IE6 и IE7 ?
25.Givi | 18 Dec, 2008
Свой вариант предложу: обрамляем все новости (новостные блоки) в общий блок, в котором делаем дочерний блок-попап с зет-индексом 1. Его позиционируем относительно родителя (общего блока), и проблем нема :)
26.akella | 11 Dec, 2008
Да, в целом одинаково, и этот глюк тоже у них общий
27.cssing :: Архив :: CSSing 2008 | 30 Dec, 2008
[...] Internet Explorer и z-index — описание одного распространенного и вредного бага в ИЕ [...]
28.AMBA | 01 Jan, 2009
>Задавать разные z-index для .entry. В случае новостей это невозможно, Не совсем понимаю этот вывод, если новости генерятся, значит им автоматом можно и разные z-index сгенерить, по id или просто по итерациям цикла (с рассчётом чтобы максимально возможный не был больше чем используется где-то ещё на странице, если используется).
29.akella | 01 Jan, 2009
Совершенно верно, можно задать разные. Но только в темплейтах этого не получится сделать =( да и лишние телодвижения, не очень красивое решение будет
30.AMBA | 01 Jan, 2009
1. ёпть, не ввёл 4 и пост потерялся, плохо. Надо поле подтверждения вынести ближе к кнопке "Отправить", и как-то выделить. 2. страница с "Дважды два 4, нужно было ввести цифру 4 в поле." без указания кодировки, а не у всех по умолчанию включен утф. Отпало желание по второму разу писать то же, но попробую. Я давно смирился что практические и быстрые решения - не самые красивые и правильные с точки зрения каких-то стандартов "правильной" вёрстки. Держать оформление и вёрстку исключительно в шаблонах и цсс это скорее идеал, к нему можно стремится, но зачастую думаешь лишь о том чтобы всё работало, а не о том что завтра прийдётся менять дизайн и при этом возникнут лишние трудности. Помоему это зависит от ситуации, времени, верстает и порграмит один человек или разные, применяемых инструментов и решений, привычек и т.п. Хотя возможно я не дорос до того "уровня" когда всё верстается быстро, кроссбраузерно, идеально по всем стандартам, легко к изменению и красиво прои просмотре кода. P.S. >в темплейтах этого не получится сделать =( Это тоже не аксиома, смотря кто на чём темплейты строит, думаю не проблема передать в темплейт из модуля новости некое сгенерированное число, а в темплейте его использовать. Хотя лично я не совсем понимаю смысл такого |модуль выдающий данные в цикле|, тогда все данные получатся в одном блоке, или же сам шаблон надо будет прогонять через цикл n-раз, но зачем...
31.AMBA | 01 Jan, 2009
Эмм, вырезаются теги, я имел ввиду [див style="z-index:x;"] |модуль выдающий данные в цикле|[/див]
32.Сергей Прокопович | 14 Jan, 2009
>Какие блоки дальше в коде, те и отобразятся поверх. А существуют ли какие-нибудь способы указания порядка расположения одного блока над другим? У меня на блоге самописный движок, так вот там можно задавать параметры отображения для каждого блока в числовом значении. Оформляется это также через CSS. И еще: сейчас многие пробуют новую версию IE для вебмастеров. Там есть какие-то различия в отображении по сравнению с перечисленными релизами эксплорера?
33.akella | 02 Feb, 2009
Обычно эту проблему (с оверлеем) решают отображением ифрейма с фильтром поверх селектов, он их "покрывает", а его прячут в СС, или меняют его ширину как надо через ЖС. Когда дело касалось хинтов, я обычно корректировал их позиции чтобы они с селектом не пересекались. Ну и приятно помнить что в ИЕ7 это решили, хоть это и не освобождает от ИЕ6 ответственности. Возможно в вашем частном случае можно придумать что-то хитрое? Есть ли пример?
34.Nikita | 02 Feb, 2009
Спасибо за пост. А теперь расскажите как расположить абсолютно-позиционируемый элемент поверх элементов форм? В IE6 всякие селекты вылезают на самый верхний уровень. Единственное решение нашел, тупо visibility:hidden скриптом прописывать, ну это только в том случае если используется что-то вроде lightbox/thickbox.
35.akella | 04 Feb, 2009
Ну вот эти всякие лайтбоксы просто растягивают ифрейм в ИЕ6 и все. А что такого страшного в ифрейме? он ведь появится только для одного браузера? Ну сожрет он ему памяти, но и убирание всех селектов тоже откушает =) Но вариант со скрытием селектов на всей странице тоже отличный. Просто как видно из блога разработчиков, сделать больше мало что можно. Все остальные хаки будут еще более грязные =)
36.Nikita | 04 Feb, 2009
Ну как, если есть веб-сайт с контролами типа select (например last.fm, там сверху есть выбор раздела для поиска). При клике на сылку (например «Войти») появляется div развернутый на всё окно (сделаный примерно так же как lightbox), который затемняет всё содержимое веб-страницы. По центру затемненного фона появляетя форма входа, а сверху на этом же темном фоне вылезает упомянутый select. Насчёт iframe — не мой вариант. Терпеть его не могу. Лучше jQuery уберет контролы с глаз долой, а потом вернёт при закрытии попапа. Кстати, может лучше «поиск сбежавшего бота» поближе к кнопке «Отправить» поместить? А то замечаю это поле в последний момент :)
37.Newone | 18 Feb, 2009
Эта проблема не только IE, я сталкивался с подобным и в других браузерах. для себя зарекся давать z-index абсолютным элементам которые меряются им с относительными. оборачиваю абсолютный в относительный и на него уже z-index.
38.Shady | 20 May, 2010
Сначала всегда считала, что обходить подобные вещи можно только располагая выпадающее меню в самом низу страницы и position:absolute подгонять в нужное место. Когда надо, чтобы весь сайт центрировался это заставляло перепланировать полностью структуру сайта и делать чуть ли не весь сайт на абсолютах (left:50% ... left:-300px ...) и в этом полно своих минусов. И как-то случайно вспомнила про z-index ... и все бы ничего, но в IE6-7 не работает. И только наткнувшись на вашу статью (и это время сказать спасибо за нее) вспомнила что даже в htmlbook читала об relative или absolute для z-index но успешно об этом позабыла.
39.DDSSDD | 24 Jun, 2010
Долго искал решение проблемы с Z-idex и IE6. Но решилось все просто - http://tjkdesign.com/articles/z-index/teach_yourself_how_elements_stack.asp Подобрал, открыв эту ссылку в IE6 позиционирование и значение Z-idex для двух верхних блоков. Оказывается нужно было задать для нижнего блока значение Z-Index: - 1; позиционирование realativ , у верхнего static и положительный Z-Index и IE все прекрасно понял. Дочернее меню стало отображаться над нижним блоком.
40.Роман | 12 Aug, 2010
Вот тут объясняется проблема: http://www.webcocktail.ru/coding/z-index-position-bug-in-internet-explorer/ У родительских блоков, содержащих в себе блоки с абсолютным позиционированием, также должен быть указан z-index. Именно он и влияет в IE на то, какой блок будет находится "выше".
41.Константин | 11 Sep, 2011
Спасибо! Толково и доходчиво. Проблема решена
42.Дмитрий | 01 Sep, 2011
Блин, спасибо!
43.Владимир | 24 Oct, 2011
Очень интересный пост, и, главное, нравится Ваш подход с юмором. Но к сожалению мою проблему с z-index в IE8 она не решила...
44.Юля | 28 Aug, 2012
такой эффект я встречаю и в современных браузерах, фбсолют ложится под релатив..
45.ivanko | 21 May, 2012
111
46.ivanko | 21 May, 2012
1
47.Михаил | 07 Mar, 2012
Спасибо! про z-index для родителя сам бы никогда не догадался
48.Алексей | 21 Jul, 2013
спасибо! помогло с z-index "родителей" для 8 ИЕ (другие уже не волнуют)