CSS-cвойство z-index: подробный обзор

Большинство CSS-свойств довольно просты в использовании. Зачастую, применение CSS-свойства к элементу в разметке дает мгновенный результат – как только вы обновите страницу, набор значений свойства применится, и вы сразу же увидите результат. Другие CSS-свойства, однако, более комплексные и будут работать только после задания определенного набора условий.

Свойство z-index принадлежит к последней группе свойств. Это свойство так часто вызывало всеобщую путаницу и разочарование, как ни одно, из существующих CSS-свойств. По иронии судьбы, однако, когда вы поближе познакомитесь с z-index, вы поймете, что это свойство очень простое, и предлагает эффективный метод решения многих проблем верстки.

В этой статье вы узнаете, что представляет собой z-index, как он может быть неправильно истолкован, а также некоторые примеры его использования. Кроме того, вы узнаете некоторые различия в поведении браузеров при обработке свойства z-index, это касается в основном предыдущих версий Internet Explorer и Firefox. Этот подробный обзор z-index предоставит разработчикам отличную основу для использования этого свойства уверенно и эффективно.

Что это такое?

Свойство z-index определяет уровень стека HTML-элемента. «Уровень стека» обозначает позицию элемента на оси Z (направленно перпендикулярно оси X, или оси Y). Элемент, которому назначено самое большое значение z-index, будет расположен в самом верху стека слоев. Этот стек слоев, располагается перпендикулярно к экрану, или области просмотра.

3-д представление оси Z:

graphical-z-index

Для того, чтобы продемонстрировать как работает z-index, картинка, представленная выше, немного увеличивает отображение элементов стека по отношению к области просмотра.

Обычный порядок стека

На HTML-странице, обычный порядок стека (то есть порядок элементов на оси Z), определяет ряд факторов. Далее представлен список, отображающий порядок, в котором элементы укладываются в стек, начиная снизу. В этом списке нет элементов, с назначенным свойством z-index:

  • Фон и рамка элемента, создающие контекст стека
  • Элементы с отрицательным контекстом стека, в порядке появления
  • Не позиционированные, не плавающие, блочные элементы, в порядке появления
  • Не позиционированные, плавающие элементы, в порядке появления
  • Строчные элементы, в порядке появления
  • Позиционированные элементы, в порядке появления

Когда свойство z-index используется правильно, оно может изменить обычный порядок стека.

Конечно, порядок элементов в стеке не является таким наглядным, пока элементы позиционируются, перекрывая друг друга. Поэтому, чтобы увидеть обычный порядок стека, можно использовать отрицательные поля, как показано ниже:

Серый блок

Синий блок

Коричневый блок

Блокам, показанным выше, назначен разный фоновый цвет и цвет рамки, а последним двум блокам, специально назначены отрицательные верхние отступы, чтобы проиллюстрировать обычный порядок стека. Серый блок появляется первым в разметке, синий блок вторым и коричневый блок третьим. Назначенные отрицательные поля отлично демонстрируют этот факт. Этим элементам не назначены значения z-index, они располагаются на странице в обычном порядке, или по умолчанию. Они накладываются друг на друга, благодаря отрицательным полям.

Почему появляется путаница?

Несмотря на то, что z-index не сложное для понимания свойство, при ошибочном толковании, оно может привести в заблуждение начинающих разработчиков. Это заблуждение появляется потому, что свойство z-index будет работать только с тем элементом, у которого свойство position установлено в одно из трех значений: absolute, fixed или relative.

Чтобы продемонстрировать, что z-index, работает только с позиционированными элементами, вот те же самые три блока, вместе с примененными значениями z-index, для изменения обычного порядка слоев:

Серый блок

Синий блок

Коричневый блок

Серому блоку, установлено значение z-index, равное “9999”; синему блоку, установлено значение z-index, равное “500”; и коричневому блоку, установлено значение z-index, равное “1”. Логично было бы предположить, что порядок, в котором уложены блоки, должен изменится. Но этого не случилось в данном примере, потому что, не одному из этих элементов, не назначено свойство position.

Вот те же самые блоки, но только с добавленным свойством position: relative, к каждому из них, и ранее назначенные свойства z-index:

Серый блок

Синий блок

Коричневый блок

Вот теперь, мы получили желаемый результат: Порядок элементов изменился; серый блок перекрывает синий, а синий, в свою очередь, перекрывает коричневый.

Синтаксис

Свойство z-index может влиять на порядок слоев, как у блочных, так и у строчных элементов, и устанавливается назначением положительного или отрицательного, целого значения, или значения auto. Значение auto, определяет элементу такой же порядок слоев, как у родительского элемента.

Вот так выглядит CSS-код третьего примера, где свойство z-index применяется правильно:

#grey_box {
width: 200px;
height: 200px;
border: solid 1px #ccc;
background: #ddd;
position: relative;
z-index: 9999;
}

#blue_box {
width: 200px;
height: 200px;
border: solid 1px #4a7497;
background: #8daac3;
position: relative;
z-index: 500;
}

#gold_box {
width: 200px;
height: 200px;
border: solid 1px #8b6125;
background: #ba945d;
position: relative;
z-index: 1;
}

Опять же, не будет лишним еще раз напомнить, особенно начинающим разработчикам, что свойство z-index не будет работать до тех пор, пока вы не примените позиционирование к элементу.

Использование JavaScript

Если вы хотите динамически изменить значение z-index у элемента, с помощью JavaScript, то это довольно просто. Синтаксис используется такой же, как и для доступа к большинству CSS-свойств, просто замените, записанные через дефис CSS-свойства, на код, как показано ниже:

var myElement = document.getElementById("gold_box");
myElement.style.position = "relative";
myElement.style.zIndex = "9999";

Как показано в примере, CSS-свойство «z-index», записывается как «zIndex». Точно так же, «background-color» становится «backgroundColor», «font-weight» становится «fontWeight», и так далее.

Также, с помощью вышеуказанного кода, изменяется свойство position, потому что, z-index будет работать только с позиционированным элементом.

Неправильная обработка в IE и Firefox

При определенных обстоятельствах, в некоторых браузерах, свойство z-index может обрабатываться по-разному, это касается браузера Internet Explorer, версии 6 и 7, а также Firefox версии 2.

Элементы <select> в IE6

В Internet Explorer 6, элемент <select> всегда появляется в самом верху в порядке слоев, нарушая обычный порядок, значения позиционирования или z-index. Эта проблема проиллюстрирована на картинке ниже:

ie6

Элемент <select> появляется первым в обычном порядке слоев, и получает значение z-index, равное «1», наряду со значением свойства position, равному relative. Коричневый блок, появляется вторым, в порядке слоев, и ему назначено свойство z-index, равное «9999». В соответствии с правилом обычного порядка слоев, и назначенных свойств z-index, коричневый блок должен перекрыть элемент <select>, что и происходит во всех текущих браузерах, за исключением IE6:

Коричневый блок

Если вы посмотрите на этот пример, с помощью браузера IE6, вы увидите, что элемент <select>, перекрывает коричневый блок, игнорируя обычный порядок слоев и свойства z-index.

Этот баг в IE6 создает проблемы с выпадающим меню, которое не может перекрыть элементы <select>. Есть два решения этой проблемы. Первое, это с помощью JavaScript временно скрывать элемент <select>, а затем, снова его отображать, после того, как выпадающее меню скроется. Другое решение предполагает использование <iframe>.

Позиционирование Родительских элементов в IE6/7

Internet Explorer версии 6 и 7, неправильно сбрасывает контекст стека, по отношению к ближайшим, позиционированным, дочерним элементам. Для того чтобы продемонстрировать эту, чуть более сложную проблему, давайте снова отобразим два блока, но в этот раз, мы заключим первый блок, в позиционированный элемент.

Серый блок

Синий блок

Серому блоку, назначено свойство z-index, равное «9999», синему блоку назначен z-index, равный «1», и оба элемента позиционированы. Следовательно, при правильной обработке, серый блок, должен быть расположен поверх синего блока.

Опять же, если вы посмотрите на этот пример в браузере IE6, или IE7, вы увидите, как синий блок перекрывает серый блок. Эти браузеры неправильно «сбрасывают» контекст стека, по отношению к позиционированному родителю, но так быть не должно. Серому блоку назначено самое высокое значение z-index, и он должен быть расположен поверх синего блока. Все другие браузеры обрабатывают этот пример правильно.

Отрицательные значения в Firefox 2

В Firefox версии 2, отрицательное значение z-index, позиционирует элемент позади порядка слоев, вместо того, чтобы расположить его поверх фона и рамок элемента, которые устанавливают контекст стека. Ниже представлена картинка, иллюстрирующая этот баг в Firefox 2:

ff2

Ниже представлена HTML-версия этой картинки, так что, если вы посмотрите на страницу в Firefox 3 или в другом, современном браузере, вы увидите правильную обработку: Фон серого блока (который является элементом, устанавливающим контекст стека) появляется в самом низу, и текст, расположенный в сером блоке, появляется поверх синего блока, который соблюдает правила «обычного порядка слоев», как говорилось выше.

Серый блок

Синий блок

Gold Box

Примеры использования

Применение свойства z-index к различным элементам на странице, может предоставить быстрое решение для различных задач макета, и позволяет дизайнерам создавать более творческие проекты. Некоторые, интересные примеры использования z-index, на практике, приведены ниже.

CSS-Тултипы

Свойство z-index может быть использовано в качестве части тултипа, основанного на CSS, как показано в примере ниже, от trentrichardson.com:

trent-tooltip

Фото-галерея

Polaroid Photo Gallery, использует некоторые возможности CSS3 вместе с z-index, для создания фото-галереи, с забавным эффектом наведения.

line25

Fancy Thumbnail Hover Effect – здесь, значение z-index изменяется с помощью JQuery-скрипта.

fancy-hover

LightBox

Существует огромное количество качественных скриптов light box, для бесплатного использования, например плагин к JQuery FancyBox. Большинство, если не все они, используют свойство z-index:

fancybox-light

Скрипты Light box используют полупрозрачное PNG-изображение, для затемнения фона, в то время как новый элемент, похожий на окно <div>, отображается на переднем плане. PNG-слой и <div> используют свойство z-index, для того чтобы расположить эти элементы поверх всех остальных элементов на странице.

Перевод статьи «The Z-Index CSS Property: A Comprehensive Look«, автор Louis Lazaris

Комментарии: (35)

  1. а как же быть со flash? Ведь z-index у флэш-объектов всегда выше

  2. как не пытался фреймами перекрывать в IE6 чего то не вышло, тупо прячу селекты когда надо

  3. 2r_ip для флеша есть wmode=transparent
    не хватает некоторых ньюансов

  4. George

    Статья не плохая, но допущены грамматические ошибки, не помешало бы поправить.

    > на оси Z (направленно противоположно оси X, или оси Y).

    Оси можно расположить перпендикулярно друг другу, но никак не противоположно.

    > большинству CSS-свойств, просто замените, записанные через дефис CSS-свойства

    Там нет свойств, записанных через дефис, есть только через подчёркивание.

    > Серому блоку назначен самый высокое значение

    назначенО самОЕ

    > Фон серого блока (который является элементом, устанавливающих контекст стека)

    является элементом, устанавливающиМ …

    • dreamhelg

      George, спасибо за указанные ошибки. А по поводу CSS-свойств, здесь имеется в виду, что свойство z-index, записывается как zIndex

  5. Vladislav.Mysla

    Все правильно: глубина работает, но…

    — флеш будет свеху (к сожалению, я не знаю исключений)

    — в старом експлорере и опере элементы ввода не перекрываются (почти все специльные)

    — согласно политике безопасности (а уязвимостей хватало) большинство браузеров запрещают перекрывать ифреймы

    — не всегда нужен релятивный(или спец.) позишн. просто (как сказал автор) появляется путаница (у разных браузеров)

    Прятать — работает, и пожалуй, спасает. Но это не всегда приемлемо ввиду интерфейсов.

    Лично мое мнение, ИМХО, глубина, также как и относительная позиция элементов реализована из_вон_рук_плохо. А про % размеры вообще говорить не стоит… :(

    • Вот примеры сайта с флешем и слоями, пожалуйста смотрите, полная динамика js+html+flash+php+sql Сайт на флеше

      • Антон

        полная динамика ??? Вы что умом тронулись? Это язык не поворачивается назвать дизайном. Динамикой и флешем тем более. ПРимер тут ахахах. Кусог говна там..

  6. Забыли еще упомянуть поведение z-index в IE6 при hover — оно просто не работает.

    • dreamhelg

      Katakikuto, никогда не сталкивалась. А можно взглянуть на пример такого поведения?

  7. Спасибо за статью. Помню одно время намучился я с селектом в ИЕ 6(хорошо, что скоро он уйдет в небытие). С фреймами не совсем выходило, приходилось прятать, или селект заменять (через бекграунд, а при нажатии див показывать).

  8. Blustmaster

    Для того что б положить что либо поверх флеша лучше устанавливать wmode=opaque с wmode=transparent у флешки могут начатся необъяснимые глюки :)

  9. dreamhelg, пример реализации можно посмотреть на teplolux.kh.ua (главная страница).
    Отключите JAVA-скрипт и посмотрите что получится.

  10. DjeiDi

    Спасибо большое!
    Очень полезная статья!

  11. Если не разобрались, то вот пример:
    есть два блока — 1 и 2. Блок #1 наполовину находится ПОД #2. Нужно сделать, чтобы при наведении на блок #1 он стал поверх #2.

  12. dreamhelg

    Katakikuto, да действительно, не приходилось раньше сталкиваться. Все потому что в IE6, hover работает только для ссылок, остается только яваскрипт.

  13. step

    Статья хорошая, но для наглядности можно в блоках написать значения z-index. Типа —
    «Синий блок. z-index:1»

  14. Спасибі за статтю. Тепер я знаю чому іноді z-index не працював, адже я не завжди прописував обов’язкову умову position

  15. Евгений

    Большое спасибо за статью. Наконец-то решилась следующая проблема:
    позиционировал position:absolute изображение (предполагалось использовать для фона) и оно плюя на z-index мне перекрывало все элементы.

  16. demimurych

    >> — согласно политике безопасности (а уязвимостей хватало) большинство браузеров запрещают перекрывать ифреймы

    это не правда.

  17. Дааааааа, IE6 такая штука весёлая))))

    Статья на 5+!

  18. Sergei Plaxienko

    Опять Вы мне помогли.
    Спасибо! :)

  19. Спасибо!, очень помогла статья справится с багом в IE6-7 с позиционированием.

  20. makregistr

    Так все же как бороться с ие6-7 и перекрыванием блоков, в статье только суть проблемы, нет никаких советов по решению.

  21. Спасибо! Замечательный туториал!

  22. Валерий

    Отличная статья, автору респект

  23. Спасибо, мне статья очень помогла! Я как раз искала решение проблемы — меню сайта все время оставалось поверх lightbox. Решение оказалось простым — в настройках лайтбокса выставила z-index 9999999, теперь все выглядит идеально.

  24. Artemeey

    Неясное определение «отрицательного значения» z-index.

    Параграф «Отрицательные значения в Firefox 2» вообще не понятен, я не понял даже в чем там баг и к какому блоку применялся стиль. Как я понял синему блоку дали z-index :-1 и он стал ниже всех остальных. Что имел автор тут не понятно.

    Ну а так, спасибо конечно зща статью!

  25. Огромное спасибо! Столько раз в коде видел этот z-index, но никогда не задумывался что он делает! Пока не столкнулся с проблемкой, а тут Ваш блог на подмогу! Вобщем за статью спасибо!

  26. 2 часа бился с z-index. Только ваша статья помогла!:) СПАСИБО ВАМ ОГРОМНОЕ!!!

  27. Спасибо большое за стать, я долго ломал голову, как отобразить меню по верх всего, так как реклама от google в java script и меню отображалось за ним. Так как сайт на ucoz, то там еще есть реклама, которая так же перекрывала меню. Я даже скрипт нашел как с ней бороться, но этот скрипт то же делал каку. Но благодаря пониманию z-index и position вопрос решен. А ответ я так долго искал. Спасибо.

  28. Андрей

    Не пойму, но почему-то не работает свойство на одном из объектов.
    Стоит position:absolute; и z-index:9999;
    Однако, другие надписи лезут поверх блока. Всё пробовал переделать с этой надписью (это тег ) — и индекс задавал маленький, и разное позиционирование пробовал и дисплей разный, не помогает…

  29. Таник

    Здравствуйте! Хорошая статья. Можно задам вопрос по теме: У меня кнопка чата расположена внизу страницы, код в стилях такой: float: right;
    margin-top: -200px;
    position: relative;
    z-index: 2147483647;

    Мне нужно зафиксировать кнопку, чтобы она оставалась на месте при прокрутке сайта: пишу position: fixed; и кнопка вообще исчезает? не могу понять, что не так?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *