Принцип работы свойства z-index и автоматического margin в Flexbox

Принцип работы свойства z-index и автоматического margin в Flexbox

От автора: Flexbox хорошо известен тем, что отлично решает такие задачи с макетами, как прилипающие футеры и колонки одинаковой высоты. Помимо этого, в Flexbox есть и другие полезные, но менее известные функции. Сегодня мы их и рассмотрим!

Flexbox и свойство z-index

Вы уже, наверное, знаете, что свойство z-index работает только на элементах с заданным позиционированием. По умолчанию у всех элементов задано position: static, т.е. они никак не спозиционированы. Позиционированным элемент будет считаться, если задать одно из следующих значений: relative, absolute, fixed или sticky.

Однако неспозиционированным элементам типа флекс ячеек можно задать свойство z-index . Из спецификации CSS Flexible Box Layout:

«Флекс ячейки отрисовываются точно так же, как инлайновые блоки [CSS21]. Отличие только в том, что тут используется модифицированный порядок в документе, а все значения свойства z-index кроме auto создают контекст стека даже при position: static.»

Взгляните на демо ниже, чтобы понять принцип работы:

Мы создали два элемента: .front и .back. В .front один дочерний элемент – блок с единицей. Элемент .front абсолютно спозиционирован, точнее ему задано position: fixed, и элемент занимает всю область просмотра.

Элемент .back является флекс контейнером, внутри которого расположены два дочерних элемента с цифрами 2 и 3. Вспоминая о чем мы говорили выше, мы можем задать флекс ячейкам свойство z-index, даже если они никак не спозиционированы (т.е. имеют position: static).

Обратите внимание, когда мы кликаем на кнопку в демо выше, мы добавляем флекс ячейкам свойство z-index: 2, тем самым поднимая их над элементом .front.

Flexbox и автоматический margin

Автоматический margin на флекс ячейках решает основные проблемы с UI. Для начала предположим, что мы хотим создать вот такой стандартный хедер:

Для этого мы будем использовать Flexbox. Никаких обтеканий, фиксированной ширины и т.д. Разметка:

<header>
  <nav>
    <h1 class="logo">LOGO</h1>

    <ul class="menu">
      <li>
        <a href="">About</a>
       </li>
      <li>
        <a href="">Projects</a>
      </li>
      <li>
        <a href="">Contact</a>
      </li>
    </ul>

    <ul class="social">
      <li>
        <a href="">Facebook</a>
      </li>
      <li>
        <a href="">Twitter</a>
      </li>
    </ul>
  </nav>
</header>

CSS

header {
  background: #333;
}

nav {
  display: flex;
  align-items: center;
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
}

.menu {
  margin-left: 60px;
  margin-right: auto;
}

В нашем примере роль флекс контейнера выполняет элемент nav, а логотип, основное меню и кнопки социальных сетей являются флекс ячейками. На картинке выше первые два элемента выравнены по левой стороне флекс контейнера вдоль главной оси. Кнопки социальных сетей же выравнены по правой стороне также вдоль основной оси.

Единственный способ выровнять элементы таким образом это использовать margin-right: auto на основном меню. Одной строкой кода мы переписываем стандартное выравнивание кнопок социальных сетей и прижимаем их к правому краю контейнера. Точно так же используем свойство align-self и переписываем стандартное выравнивание флекс ячеек вдоль оси.
Помимо автоматического внешнего отступа есть еще один метод. Первым делом необходимо удалить свойство margin-right у меню и прописать там flex-grow: 1.

Результат почти одинаковый, но есть одно существенное различие. В первом случае у меню заранее высчитанная ширина. То есть, при ширине окна в 1100 px ширина меню будет примерно такая:

Во втором методе ширина меню увеличивается, так как мы задали свойство flex-grow: 1. Ниже показана ширина меню при ширине окна в 1100 px:

CodePen демо:

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

Разметка остается без изменений. Нужно внести небольшие правки в CSS:

nav {
  background: #333;
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 180px;
  padding: 20px;
  box-sizing: border-box;
}

.menu {
  margin-top: 60px;
  margin-bottom: auto;
} 

В новом примере меню социальных сетей прижато к нижней границе родительского блока. Сделано это с помощью добавления свойства margin-bottom: auto к основному меню. Можно было бы использовать flex-grow: 1, но в таком случае увеличится высота меню.

Тут стоит сказать также про то, что если в любом из наших примеров применить свойство justify-content, результат будет точно тот же. Результат будет такой же, потому что мы используем автоматический margin для выравнивания флекс ячеек. Свойство justify-content сработает только, если удалить автоматические внешние отступы. Из спецификации:

«Свойства выравнивания не будут работать, если распределение пространства задано с помощью автоматических внешних отступов. Это происходит из-за того, что автоматический margin забирает все свободное пространство, оставшееся после применения Flexbox.»

Теперь давайте создадим еще одну вариацию нашего хедера:

Сделать это можно без особых проблем, задав свойство justify-content: space-between на флекс контейнере. Однако точно такой же макет можно сделать при помощи автоматических внешних отступов. Нужно всего лишь прописать свойство margin: 0 auto главному меню.

Заключение

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

Свойство z-index можно применять к флекс ячейкам, даже если у них задано свойство position: static.

Для пользовательского выравнивания флекс ячеек вдоль главной оси можно использовать автоматический margin.

Редакция: George Martsoukos

Источник: https://www.sitepoint.com/

Редакция: Команда webformyself.

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree