z-index
Что такое z-index
Это css-свойство элемента, которое определяет его положение относительно других элементов по оси Z. Оно применяется только для элементов с позиционированием absolute, fixed, sticky или relative (соответствиенно при отсутствии указанного свойства position, добавление z-index'а никак не будет влиять на положение элемента).Есть обычный порядок наложения элементов - это когда последующий перекрывает предыдущий с учетом родительской вложености. Но с помощью z-index'ов мы можем его изменять. Это настолько просто, что многие разработчики пользуются этим, не задумываясь о том, как важно структурировать z-index'ы, чтобы они не испортили проект в будущем.
Пример
Рассмотрим какой-нибудь стандартный проект на jQuery. Шучу-шучу, пусть будет проект на React'е. Но в целом это не принципиально. Допустим, у нас есть модальное окно, галерея и флэш-сообщения.Начнем с модального окна. Выберем пару библиотек для модалок, наугад, первые из поиска, предполагая, что они самые популярные. И посмотрим какие z-index'ы они выставляют по умолчанию.
1. Бибилотека react-responsive-modal выставляет один z-index: 1000 для перекрывающего слоя, остальное "само" позиционируется внутри:
2. Плагин jQuery Modal задает z-index: 1 для подложки и z-index: 2 для модального окна:
Как видим из примера, нет единого подхода для определения z-index'ов в модальных окнах. Нет одного универсального способа сказать, что 1000 - это единственно верное число для z-оси. Так как 1 и 2 однозначно плохие варианты, потому что у нас могут быть на странице слайдер, анимация, placeholder, у которых тоже может быть значение 1, 2 и даже 3. И они будут перекрывать модальные окна.
Можем ли мы вывести, что 1000 - достаточное значение для модалок? Достаточно большое, чтобы удовлетворить все наши прихоти? Конечно, используя сторонние библиотеки, нам ничего не стоит переопределить свойства согласно нашему дизайну. Но как часто мы меняем z-index'ы? И если менять, то на какие?
Давайте для начала добавим в наш проект галерею. Возьмем стандартную, добротную и всеми любимую lightGallery и посмотрим на z-index'ы, которые она проставляет по умолчанию.
z-index:
1050 - общая перекрытие
1060 - для отдельного слайда
1080 - кнопки навигации влево-вправо, столько же подписи и пагинация
1081 - оверлей
1082 - верхняя навигация
1083 - статус прогресса загрузки
Выглядит немного странно. Где-то значения увеличиваются на десятки, а где-то - на единицы. Но самое главное - это то, что начинается с 1050. Это значит, что он перекроет наше модальное окно с z-index: 1000. Отлично!
Звучит классно. Но что если нам надо в галерею добавить слайд с кнопкой, которая вызывает модалку? Это не просто мое предположение, так было в одном из проектов, над которыми я работала. Какое значение должно быть тогда у модалки? z-index: 1090 или 1100? Может сразу поставить 2000 чтобы предупредить возможные коллизии?
Хорошо. А теперь добавим в проект флэш-сообщения. Надеюсь, вы уже начинаете догадываться, что вы больше не контролируете z-index'ы? Это они навязывают вам свою структуру. А вы ходите по разным файлам с галереей, модалками, флэш-сообщениями, анимацией и пытаетесь привести весь этот зоопарк в порядок, каждый раз сжимая кулачки, надеясь, что нигде в другом месте ничего не выползет. И начинают появляться значения 1100, 10000, 10100...
Гомеопатическая панацея
Вы все еще думаете, что можете что-то контролировать, когда у вас есть sass. Вы определяете в файле с модалками переменную для общего перекрывающего слоя и внутреннего блока:
$modal-overlay: 1000;
$modal-under-overlay: $modal-overlay - 1;
$modal-content: $modal-overlay + 1;
Но это лечение симптомов, а не болезни. Потому что помогает только для одного связного блока - блока модального окна. И никак не отражает отношение к другим модулям.
Оно же является источником заражения десятками. Что это значит? Чтобы определить другую переменую в другом модуле, нужно отступить от переменной
$modal-overlay
в обе стороны по 10 или 20 единиц. Это хорошо видно на примере lightSlider'а. Мифическя цифра 1050 у них появилась из предположения, что 1000 будет использована для модалок и вообще как самое большое число, а относительная флуктуация в ее пределах 10-20, но для верности они взяли отступ в 50. Итого вышло 1050.Лично меня пугает не мифичность числа, потому что я знаю его происхождение, а его разрядность. 100 - это уже много. Я не могу представить, что будет 100 потребностей в перекрытии элементов!
Моя серебряная пулька
Для себя я нашла способ контроля - это вынести все z-index'ы в отдельный файл как переменные. Вы же выносите базовые цвета, типографику, размеры. Почему бы не сделать то же самое и для z-index'ов?Итого мой файл "_z-index.scss" в одном из проектов выглядит так:
$zIndexSubzero: -1;
$zIndexZero: 0;
$zIndexMin: 1;
$zIndexInputValue: 2;
$zIndexInputAbove: 3;
$zIndexFormCover: 4;
$zIndexStickyTop: 5;
$zIndexNavigation: 6;
$zIndexInfoBar: 7;
$zIndexPopupOverlay: 8;
$zIndexPopup: 9;
$zIndexConsentedCookie: 10;
Чем это удобно:
- Контроль. Все переменные z-index'ов находятся в одной файле, поэтому сразу видна иерархия.
- Легкоизменяемость. Нужно сделать флэш-сообщения поверх модалок? Просто меняете местами нужные строки с сохранением нумерации сверху вниз по возрастанию.
- Прозрачность. Все z-index'ы хранятся здесь. Нет никаких локальных переменных в других файлах.
- Мелкая разрядность z-index'ов. Не нужно создавать значения в 100 и 1000 единиц. Все помещается в пределах 10-20 в зависимости от проекта.
- Наименование. По названию сразу понятно где используется каждая переменная. Исключение составляют первые три; они носят общий характер и, как правило, используются для позиционирования элемента относительного базового элемента или 0.
Выводы
На самом деле z-index'ы - это такая мелочь, на которую не сразу обращаешь внимание. Только после того, как проект разрастается и появляются новые слои перекрытия элементов, начинаешь задумываться, что что-то с ними не так. Но часто даже это не может послужить поводом для рефакторинга.Я придумала эту систему в очень крупном проекте, том самом с галереей, попапами, тултипами и флэш-сообщениями. Но там я сохранила в переменных десятичную градацию. Сейчас же понимаю, что это не нужно, достаточно единичных. Не нужно оставлять себе лазеек для обхода этой системы, нужно просто уметь ею пользоваться.
В текущем же проекте у меня все идеально ^_^ Пример выше - тому подтверждение. И я каждый раз радуюсь, глядя на этот файл, потому что сразу вижу какую большую головную боль он мне решает с z-index'ами.
Гениальное - просто!
Пользуйтесь в удовольствие =)
Комментарии