it-swarm.com.ru

Как указать разрывы строк в многострочном flexbox макете?

Есть ли способ сделать разрыв строки в многострочном flexbox?

Например, разбить после каждого третьего элемента в этот CodePen .

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  height: 100px;
  background: gold;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px;
}
.item:nth-child(3n) {
  background: silver;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

Подобно

.item:nth-child(3n){
  /* line-break: after; */    
}
176
Artem Svirskyi

Самое простое и надежное решение - вставлять гибкие элементы в нужных местах. Если они достаточно широкие (width: 100%), они вызовут разрыв строки.

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(4n - 1) {
  background: silver;
}
.line-break {
  width: 100%;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="line-break"></div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="line-break"></div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="line-break"></div>
  <div class="item">10</div>
</div>

Но это некрасиво и не семантически. Вместо этого мы могли бы генерировать псевдоэлементы внутри flex-контейнера и использовать order, чтобы переместить их в нужные места.

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(3n) {
  background: silver;
}
.container::before, .container::after {
  content: '';
  width: 100%;
  order: 1;
}
.item:nth-child(n + 4) {
  order: 1;
}
.item:nth-child(n + 7) {
  order: 2;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>

Но есть ограничение: гибкий контейнер может иметь только псевдоэлемент ::before и ::after. Это означает, что вы можете форсировать только 2 перевода строки.

Чтобы решить эту проблему, вы можете сгенерировать псевдоэлементы внутри элементов flex, а не в контейнере flex. Таким образом, вы не будете ограничены 2. Но эти псевдоэлементы не будут гибкими элементами, поэтому они не смогут вызвать разрывы строк.

Но, к счастью, CSS Display L представил display: contents (в настоящее время поддерживается только Firefox 37):

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

Таким образом, вы можете применить display: contents к дочерним элементам гибкого контейнера и обернуть содержимое каждого из них в дополнительную оболочку. Тогда гибкими элементами будут те дополнительные обертки и псевдоэлементы дочерних элементов.

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  display: contents;
}
.item > div {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px;
}
.item:nth-child(3n) > div {
  background: silver;
}
.item:nth-child(3n)::after {
  content: '';
  width: 100%;
}
<div class="container">
  <div class="item"><div>1</div></div>
  <div class="item"><div>2</div></div>
  <div class="item"><div>3</div></div>
  <div class="item"><div>4</div></div>
  <div class="item"><div>5</div></div>
  <div class="item"><div>6</div></div>
  <div class="item"><div>7</div></div>
  <div class="item"><div>8</div></div>
  <div class="item"><div>9</div></div>
  <div class="item"><div>10</div></div>
</div>

В качестве альтернативы, в соответствии с Фрагментирование разметки Flex и Фрагментация CSS , Flexbox разрешает принудительные перерывы с помощью break-before , break-after или их псевдонимы CSS 2.1:

.item:nth-child(3n) {
  page-break-after: always; /* CSS 2.1 syntax */
  break-after: always; /* New syntax */
}
.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(3n) {
  page-break-after: always;
  background: silver;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

Принудительные разрывы строк в flexbox пока широко не поддерживаются, но это работает в Firefox.

263
Oriol

У @Oriol отличный ответ, к сожалению, по состоянию на октябрь 2017 года, ни display:contents, ни page-break-after широко не поддерживаются, лучше сказать, что это Firefox, который поддерживает это, но не других игроков, я придумал следующий "взлом", который я считаю лучше чем жесткое кодирование в перерыве после каждого третьего элемента, потому что это сделает очень трудным сделать страницу удобной для мобильных устройств.

Как уже говорилось, это взлом, и недостатком является то, что вам нужно добавить довольно много дополнительных элементов, но это работает и работает в разных браузерах даже на устаревшем IE11.

"Хаком" является простое добавление дополнительного элемента после каждого элемента div, для которого установлено значение display:none, а затем используется css nth-child, чтобы решить, какой из этих элементов должен быть на самом деле сделан видимым, вызывая торможение строки следующим образом:

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(3n-1) {
  background: silver;
}
.breaker {display:none;}
.breaker:nth-child(3n) {
  display:block;
  width:100%;
  height:0;
 }
<div class="container">
  <div class="item">1</div><p class=breaker></p>
  <div class="item">2</div><p class=breaker></p>
  <div class="item">3</div><p class=breaker></p>
  <div class="item">4</div><p class=breaker></p>
  <div class="item">5</div><p class=breaker></p>
  <div class="item">6</div><p class=breaker></p>
  <div class="item">7</div><p class=breaker></p>
  <div class="item">8</div><p class=breaker></p>
  <div class="item">9</div><p class=breaker></p>
  <div class="item">10</div><p class=breaker></p>
</div>
20
Emil Borconi

С моей точки зрения, более семантически использовать <hr>элементы как разрывы строк между элементами flex.

<div class="container">
  <div>1</div>
  <div>2</div>
  <hr>
  <div>3</div>
  <div>2</div>
  ...
</div>

CSS следующий

.container {
  display: flex;
  flex-flow: wrap;
}

.container hr {
  width: 100%;
}

Протестировано в Chrome 66, Firefox 60 и Safari 11.

17
Petr Stepanov

Вы хотите семантический перенос строки?

Затем рассмотрите возможность использования <br>. W3Schools может предложить вам, что BR только для написания стихов (мой скоро будет), но вы можете изменить стиль, чтобы он действовал как блочный элемент шириной 100%, который переместит ваш контент на следующую строку. Если 'br' предлагает перерыв, тогда это кажется мне более подходящим, чем использование hr или 100% div, и делает HTML более читабельным.

Вставьте <br> туда, где вам нужны разрывы строк, и стилизуйте его следующим образом.

 // Use `>` to avoid styling `<br>` inside your boxes 
 .container > br 
 {
    width: 100%;
    content: '';
 }

Вы можете отключить <br> с помощью медиа-запросов , установив display: в block или none, в зависимости от ситуации (я включил пример этого, но оставил его закомментированным).

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

И вы можете поставить столько, сколько хотите, с разными классами или именами :-)

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}

.container > br
{
  width: 100%;
  content: '';
}

// .linebreak1 
// { 
//    display: none;
// }

// @media (min-width: 768px) 
// {
//    .linebreak1
//    {
//       display: block;
//    }
// }
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <br class="linebreak1"/>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

Не нужно ограничиваться тем, что говорит W3Schools:

enter image description here

8
Simon_Weaver

Я думаю, что традиционный способ является гибким и довольно простым для понимания:

Markup

<div class="flex-grid">
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-3">.col-3</div>
    <div class="col-9">.col-9</div>

    <div class="col-6">.col-6</div>
    <div class="col-6">.col-6</div>
</div>

Создайте grid.css файл:

.flex-grid {
  display: flex;
  flex-flow: wrap;
}

.col-1 {flex: 0 0 8.3333%}
.col-2 {flex: 0 0 16.6666%}
.col-3 {flex: 0 0 25%}
.col-4 {flex: 0 0 33.3333%}
.col-5 {flex: 0 0 41.6666%}
.col-6 {flex: 0 0 50%}
.col-7 {flex: 0 0 58.3333%}
.col-8 {flex: 0 0 66.6666%}
.col-9 {flex: 0 0 75%}
.col-10 {flex: 0 0 83.3333%}
.col-11 {flex: 0 0 91.6666%}
.col-12 {flex: 0 0 100%}

[class*="col-"] {
  margin: 0 0 10px 0;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

@media (max-width: 400px) {
  .flex-grid {
    display: block;
  }
}

Я создал пример (jsfiddle)

Попробуйте изменить размер окна до 400px, это отзывчиво !!

6
Moshe Quantz