Разрыв линии в многострочном flexbox
есть ли способ сделать разрыв строки в нескольких строках flexbox?
например, чтобы сломать после каждого 3-го пункта в этой ручке
.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; */
}
7 ответов
самым простым и надежным решением является вставка элементов flex в нужных местах. Если они достаточно широки (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>
но есть ограничение: flex контейнер может иметь только ::before
и ::after
псевдо-элемент. Это означает, что вы можете заставить только 2 разрыва линии.
чтобы решить эту проблему, вы можете генерировать псевдоэлементы внутри элементов flex вместо контейнера flex. Таким образом, вы не будете ограничены 2. Но эти псевдо-элементы не будут гибкими элементами, поэтому они не смогут заставить разрывы линий.
но, к счастью, CSS дисплей L3 ввел display: contents
(в настоящее время только поддерживается Firefox 37):
сам элемент не генерирует никаких ящиков, но его дочерние элементы и псевдо-элементы по-прежнему генерируют коробки как обычно. Для целей генерация и компоновка коробки, элемент должен рассматриваться как были заменены его дочерними и псевдоэлементами в документе дерево.
таким образом, вы можете применить display: contents
к детям контейнера гибкого трубопровода, и оборачивает содержание каждого одного внутри дополнительного обертка. Тогда элементы flex будут теми дополнительными обертками и псевдоэлементами детей.
.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>
кроме того, по данным Фрагментация Гибкого Макета и фрагментация 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.
@Oriol имеет отличный ответ, К сожалению, по состоянию на октябрь 2017 года, ни display:contents
, ни page-break-after
широко поддерживается, лучше сказать, что речь идет о Firefox, который поддерживает это, но не другие игроки, я придумал следующий "хак", который я считаю лучше, чем жесткое кодирование в перерыве после каждого 3-го элемента, потому что это сделает его очень трудно сделать страницу мобильной дружественной.
как сказал, что это хак и недостатком является то, что вам нужно добавить довольно много лишних элементы ни для чего, но он делает трюк и работает кросс-браузер даже на датированном 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>
С моей точки зрения это больше смысловая использовать <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.
Я думаю, что традиционный способ является гибким и достаточно легко понять:
разметки
<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>
создать решетки.в 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, он реагирует!!
вы хотите семантический linebreak?
тогда подумайте об использовании <br>
. W3C может предложить вам, что BR
только для написания стихов (Мой скоро), но вы можете изменить стиль, чтобы он вел себя как элемент блока 100% ширины, который подтолкнет ваш контент к следующей строке. Если "br" предлагает перерыв, то мне кажется более подходящим, чем использование hr
или 100% div
и делает html более читаемым.
вставить <br>
где вам нужны linebreaks и стиль такой.
// Use `>` to avoid styling `<br>` inside your boxes
.container > br
{
width: 100%;
content: '';
}
вы можете отключить <br>
С медиа-запросы, установив display:
to 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>
нет необходимости ограничивать сам на что W3C говорит:
.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;
}
<div class="container">
<div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
<div class="item">10</div>
</div>
вы можете попробовать обернуть элементы в элемент dom, как здесь. с этим вам не нужно знать много css, просто имея хорошую структуру, решит проблему.
для будущих вопросов также можно сделать это с помощью float
свойство и очистка его в каждом из 3 элементов.
вот пример, который я сделал.
.grid {
display: inline-block;
}
.cell {
display: inline-block;
position: relative;
float: left;
margin: 8px;
width: 48px;
height: 48px;
background-color: #bdbdbd;
font-family: 'Helvetica', 'Arial', sans-serif;
font-size: 14px;
font-weight: 400;
line-height: 20px;
text-indent: 4px;
color: #fff;
}
.cell:nth-child(3n) + .cell {
clear: both;
}
<div class="grid">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
<div class="cell">7</div>
<div class="cell">8</div>
<div class="cell">9</div>
<div class="cell">10</div>
</div>