it-swarm.com.ru

Псевдоэлементы, нарушающие justify-content: пробел в макете flexbox

У меня есть три div внутри родительского div, которые разнесены с помощью:

display: flex;
justify-content: space-between;

Тем не менее, родительский div имеет :after, что делает три div не выходящими на край родительского div. Есть ли способ заставить flexbox игнорировать :before и :after?

codepen.io

.container {
  width: 100%;
  display: flex;
  justify-content: space-between;
  padding-top: 50px;
  background: gray;
}

.container div {
    background: red;
    height: 245px;
    width: 300px;
  }
.container:before {
    content: '';
    display: table;
  }
.container:after {
    clear: both;
    content: '';
    display: table;
  }
<div class="container">
  <div></div>
  <div></div>
  <div></div>
</div>

13
Landon Call

Короткий ответ

В CSS в настоящее время нет 100% надежного способа предотвратить влияние псевдоэлементов на вычисление justify-content: space-between.

Объяснение

Псевдоэлементы ::before и ::after в flex-контейнере становятся flex-элементами.

Из спецификации:

4. Гибкие элементы

Каждый входящий дочерний элемент гибкого контейнера становится гибким элементом.

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

Большинство браузеров, если не все, интерпретируют это как псевдоэлементы. Псевдо ::before - это первый элемент flex. Элемент ::after является последним.

Вот еще одно подтверждение этого поведения рендеринга из документации Firefox:

псевдоэлементы ::after и ::before в потоке теперь являются гибкими Предметы ( ошибка 867454 ).

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

Смотрите мой ответ здесь для иллюстраций, когда псевдоэлементы портятся justify-content:

15
Michael_B

Если это унаследованное свойство, просто переопределите его

.container {
  width: 100%;
  display: flex;
  justify-content: space-between;
  padding-top: 50px;
  background: gray;
}

.container div {
    background: red;
    height: 245px;
    width: 100px;
}

/* definitions from a framework */
.container:before {
    content: '';
    display: table;
  }
.container:after {
    clear: both;
    content: '';
    display: table;
  }

/* definitions override */
.container.flexcontainer:before, 
.container.flexcontainer:after {
   display: none;  
}
<div class="container flexcontainer">
  <div></div>
  <div></div>
  <div></div>
</div>

4
vals

Вложил еще один div в родительский div и дал ему весь гибкий код, чтобы псевдоэлементы не влияли на него.

1
Landon Call

Если вам нужно сделать это, вы можете воспользоваться преимуществами автоматического маржинального поведения для флекс-элементов. Вам также необходимо обнулить левое поле первого изгибаемого дочернего элемента и равным образом правое поле последнего изгибаемого дочернего элемента. Смотри кодовый код ниже.

Flexbox и авто поля: https://www.w3.org/TR/css-flexbox-1/#auto-margins

Демонстрация Codepen: http://codepen.io/anderskleve/pen/EWvxqm

.container {
  width: 100%;
  display: flex;
  justify-content: space-between;
  padding-top: 50px;
  background: gray;

  div {
    background: red;
    height: 245px;
    width: 300px;
    margin: 0 auto;
  }

  div:first-child {
    margin-left: 0;
  }

  div:last-child {
    margin-right: 0;
  }

  &:before {
    content:'';
    display: table;
  }

  &:after {
    clear: both;
    content: '';
    display: table;
  }
}
0
anderskleve