La solution la plus simple et la plus fiable consiste à insérer des éléments flexibles aux bons endroits. S'ils sont suffisamment larges ( width: 100%
), ils forceront un saut de ligne.
.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>
Mais c'est moche et pas sémantique. Au lieu de cela, nous pourrions générer des pseudo-éléments à l'intérieur du conteneur flexible et les utiliser order
pour les déplacer aux bons endroits.
.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>
Mais il y a une limitation: le conteneur flexible ne peut avoir qu'un ::before
et un ::after
pseudo-élément. Cela signifie que vous ne pouvez forcer que 2 sauts de ligne.
Pour résoudre ce problème, vous pouvez générer les pseudo-éléments à l'intérieur des éléments flexibles plutôt que dans le conteneur flex. De cette façon, vous ne serez pas limité à 2. Mais ces pseudo-éléments ne seront pas des éléments flexibles, ils ne pourront donc pas forcer les sauts de ligne.
Mais heureusement, CSS Display L3 a introduit display: contents
(actuellement uniquement pris en charge par Firefox 37):
L'élément lui-même ne génère aucune boîte, mais ses enfants et pseudo-éléments génèrent toujours des boîtes comme d'habitude. Aux fins de la génération et de la mise en page des boîtes, l'élément doit être traité comme s'il avait été remplacé par ses enfants et pseudo-éléments dans l'arborescence du document.
Vous pouvez donc appliquer display: contents
aux enfants du conteneur flexible et envelopper le contenu de chacun dans un emballage supplémentaire. Ensuite, les éléments flexibles seront ces enveloppes supplémentaires et les pseudo-éléments des enfants.
.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>
Alternativement, selon Fragmenting Flex Layout et CSS Fragmentation , Flexbox autorise les interruptions forcées en utilisant break-before
, break-after
ou leurs alias 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>
Les sauts de ligne forcés dans Flexbox ne sont pas encore largement pris en charge, mais cela fonctionne sur Firefox.