Podział linii w multi-line flexbox
Czy istnieje sposób na złamanie linii w multiple line flexbox?
Na przykład, aby złamać po każdym 3 pozycji w tym pisaku
.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>
Jak
.item:nth-child(3n){
/* line-break: after; */
}
7 answers
Najprostszym i najbardziej niezawodnym rozwiązaniem jest wstawianie elementów flex we właściwe miejsca. Jeśli są wystarczająco szerokie (width: 100%
), wymusi przerwanie linii.
.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>
Ale To jest brzydkie i nie semantyczne. Zamiast tego możemy wygenerować pseudoelementy wewnątrz kontenera flex i użyć order
, aby przenieść je we właściwe miejsca.
.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>
Ale jest ograniczenie: kontener flex może mieć tylko ::before
i ::after
pseudo-element. Oznacza to, że możesz wymusić tylko 2 przerwy w linii.
Aby to rozwiązać, możesz wygenerować pseudoelementy wewnątrz elementów flex zamiast w kontenerze flex. W ten sposób nie będziesz ograniczony do 2. Ale te pseudoelementy nie będą elementami flex, więc nie będą w stanie wymusić łamania linii.
Ale na szczęście CSS Display L3 wprowadził display: contents
(obecnie obsługiwane tylko przez Firefoksa 37):
Sam element nie generuje wszelkie pudełka, ale jego dzieci i pseudoelementy nadal normalnie generują pola. Do celów generowanie i układ pudełka, element musi być traktowany tak, jakby miał został zastąpiony jego potomkami i pseudoelementami w dokumencie drzewo.
Możesz więc nałożyć display: contents
na dzieci pojemnika flex i zawinąć zawartość każdego z nich w dodatkową owijkę. Następnie elementy flex będą tymi dodatkowymi owijkami i pseudoelementami dzieci.
.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>
Alternatywnie, zgodnie z Fragmentowaniem układu Flex i fragmentacją CSS , Flexbox umożliwia wymuszone łamanie za pomocą break-before
, break-after
lub ich aliasy 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>
Wymuszone podziały linii w flexbox nie są jeszcze szeroko obsługiwane, ale działa na Firefoksie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-28 19:48:37
@Oriol ma doskonałą odpowiedź, niestety od października 2017, ani display:contents
, ani {[3] } jest szeroko obsługiwany, lepiej powiedzieć, że chodzi o Firefoksa, który obsługuje to, ale nie innych graczy, mam pochodzić z następujących "hack", które uważam za lepsze niż hard coding w przerwie po każdym 3rd element, bo to sprawi, że bardzo trudno zrobić stronę mobilną przyjazny.
Jak powiedział, że to hack, a wadą jest to, że trzeba dodać sporo dodatkowych elementów dla nic, ale robi sztuczkę i działa między przeglądarką nawet na datowanym IE11.
"hack" polega na dodaniu dodatkowego elementu po każdym div, który jest ustawiony na display:none
, a następnie użyciu css nth-child
, aby zdecydować, który z nich powinien być widoczny, wymuszając hamulec linii w taki sposób:
.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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 00:06:08
Z mojego punktu widzenia bardziej semantyczne jest użycie <hr>
elementy jako podziały linii pomiędzy elementami flex.
<div class="container">
<div>1</div>
<div>2</div>
<hr>
<div>3</div>
<div>2</div>
...
</div>
CSS jest następujący
.container {
display: flex;
flex-flow: wrap;
}
.container hr {
width: 100%;
}
Testowane w Chrome 66, Firefox 60 i Safari 11.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 01:06:32
Myślę, że tradycyjny sposób jest elastyczny i dość łatwy do zrozumienia:
Znaczniki
<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>
Utwórz siatkę.css plik:
.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;
}
}
Stworzyłem przykład (jsfiddle)
Spróbuj zmienić rozmiar okna poniżej 400px, to reaguje!!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-14 14:45:12
Chcesz semantycznego linebreak?
Następnie rozważ użycie <br>
. W3C może zasugerować, że BR
jest tylko do pisania wierszy (mój już wkrótce), ale możesz zmienić styl, aby zachowywał się jak element bloku o szerokości 100%, który przesunie zawartość do następnej linii. Jeśli 'br' sugeruje przerwę, to wydaje mi się bardziej odpowiednie niż użycie hr
lub 100% {[6] } i sprawia, że html jest bardziej czytelny.
Wstaw <br>
tam, gdzie potrzebujesz linebreaks i stylizuj go w ten sposób.
// Use `>` to avoid styling `<br>` inside your boxes
.container > br
{
width: 100%;
content: '';
}
Możesz wyłączyć <br>
za pomocą zapytań o media , ustawiając display:
na block
lub none
odpowiednio (dodałem przykład tego, ale zostawiłem komentarz).
Możesz użyć order:
, aby ustawić kolejność w razie potrzeby.
I możesz umieścić tyle, ile chcesz, z różnymi klasami lub nazwami: -)
.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>
Nie musisz ograniczać się do tego, co mówi W3C:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-22 08:32:02
.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>
Możesz spróbować zawijać elementy w element dom, jak tutaj. dzięki temu nie musisz znać wielu css, tylko posiadanie dobrej struktury rozwiąże problem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-06 17:56:02
Dla przyszłych pytań, możliwe jest również, aby to zrobić za pomocą właściwości float
i wyczyszczenie go w każdym 3 elementach.
.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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 19:36:54