229 votes

Comment spécifier un élément après lequel envelopper dans le flexbox CSS ?

Je ne pense pas que cela fasse encore partie de la norme flexbox standard, mais y a-t-il peut-être un truc pour suggérer ou forcer le retour à la ligne après un certain élément? J'aimerais répondre à différentes tailles de page et envelopper une liste différemment sans balisage supplémentaire, de manière à ce qu'au lieu d'avoir (par exemple) des éléments de menu isolés sur la ligne suivante, je casse au milieu du menu.

Voici le HTML de départ :

    Un
    Deux
    Trois
    Quatre
    Cinq

Et le CSS :

ul {
    display: flex;
    flex-wrap: wrap;
}

J'aimerais quelque chose comme ce qui suit :

/* à l'intérieur d'une requête media ciblant la largeur */
li:nth-child(2n) {
    flex-break: after;
}

Voir le jsfiddle pour une configuration plus complète : http://jsfiddle.net/theazureshadow/ww8DR/

203voto

luksak Points 662

Vous pouvez accomplir cela en définissant ceci sur le conteneur :

ul {
    display: flex;
    flex-wrap: wrap;
}

Et sur l'enfant, vous définissez ceci :

li:nth-child(2n) {
    flex-basis: 100%;
}

ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
}

li:nth-child(4n) {
  flex-basis: 100%;
}

  1
  2
  3
  4

Cela fait en sorte que l'enfant prenne 100% de la largeur du conteneur avant tout autre calcul. Comme le conteneur est configuré pour se diviser en cas de manque d'espace, il le fait avant et après cet enfant. Vous pourriez donc utiliser un élément div vide pour forcer le saut de ligne entre l'élément précédant et suivant.

86voto

jbenjohnson Points 1773

\=========================

Voici un article avec votre liste complète d'options: https://tobiasahlin.com/blog/flexbox-break-to-new-row/

EDIT: C'est vraiment facile à faire avec Grid maintenant: https://codepen.io/anon/pen/mGONxv?editors=1100

\=========================

Je ne pense pas que vous puissiez sauter après un élément spécifique. Le mieux que vous puissiez probablement faire est de changer le flex-basis à vos points de rupture. Donc:

ul {
  flex-flow: row wrap;
  display: flex;
}

li {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 50%;
}

@media (min-width: 40em;){
li {
  flex-basis: 30%;
}

Voici un exemple: http://cdpn.io/ndCzD

\============================================

EDIT: VOUS POUVEZ sauter après un élément spécifique ! Heydon Pickering a déchaîné quelques tours de magie css dans un article d'A List Apart: http://alistapart.com/article/quantity-queries-for-css

EDIT 2: Veuillez consulter cette réponse: Saut de ligne dans flexbox multi-ligne

@luksak fournit également une excellente réponse

36voto

morewry Points 1112

Il y a une partie de la spécification qui semble vraiment ressembler à ceci... juste dans les sections "algorithme de disposition flexible" et "dimension principale" :

Sinon, à partir du premier élément non collecté, collectez des éléments consécutifs un par un jusqu'à la première fois que le prochain élément collecté ne rentrerait plus dans la taille principale intérieure du conteneur flexible, ou jusqu'à ce qu'une rupture forcée soit rencontrée. Si le tout premier élément non collecté ne rentrerait pas, collectez-le juste dans la ligne. Une rupture est forcée là où les propriétés CSS2.1 page-break-before/page-break-after [CSS21] ou CSS3 break-before/break-after [CSS3-BREAK] spécifient une rupture de fragmentation.

De http://www.w3.org/TR/css-flexbox-1/#main-sizing

Cela semble vraiment (à part le fait que les sauts de page devraient être pour l'impression), lors de la mise en page d'une disposition flexible potentiellement multi-ligne (que je tire d'une autre partie de la spécification est une sans flex-wrap: nowrap), un page-break-after: always ou break-after: always devrait provoquer une rupture, ou passer à la ligne suivante.

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

.child {
  flex-grow: 1;
}

.child.break-here {
  page-break-after: always;
  break-after: always;
}

Cependant, j'ai essayé cela et cela n'a pas été implémenté de cette manière dans...

  • Safari (jusqu'à 7)
  • Chrome (jusqu'à 43 dev)
  • Opera (jusqu'à 28 dev & 12.16)
  • IE (jusqu'à 11)

Cela fonctionne comme prévu (pour moi, du moins) dans :

  • Firefox (28+)

Exemple sur http://codepen.io/morewry/pen/JoVmVj.

Je n'ai trouvé aucune autre demande dans le suivi des bogues, donc je l'ai signalé sur https://code.google.com/p/chromium/issues/detail?id=473481.

Mais le sujet en est venu à la liste de diffusion et, peu importe comment cela semble, ce n'est apparemment pas ce qu'ils voulaient impliquer, sauf peut-être pour la pagination. Ainsi, il n'y a pas de moyen de passer avant ou après une boîte particulière dans une disposition flexible sans imbriquer des dispositions flexibles successives à l'intérieur des enfants flexibles ou jouer avec des largeurs spécifiques (par exemple, flex-basis: 100%).

C'est extrêmement frustrant, bien sûr, car travailler avec l'implémentation de Firefox confirme ma suspicion que la fonctionnalité est incroyablement utile. Outre l'alignement vertical amélioré, le manque annule une grande partie de l'utilité de la disposition flexible dans de nombreux scénarios. Devoir ajouter des balises d'enveloppement supplémentaires avec des dispositions flexibles imbriquées pour contrôler le point où une ligne se termine augmente la complexité à la fois de l'HTML et du CSS et, malheureusement, rend souvent order inutile. De même, forcer la largeur d'un élément à 100% réduit le potentiel "responsive" de la disposition flexible ou nécessite beaucoup de requêtes spécifiques ou de sélecteurs de compte (par exemple, les techniques qui peuvent accomplir le résultat général dont vous avez besoin mentionnées dans les autres réponses).

Au moins, les flottants avaient clear. Quelque chose pourrait être ajouté à un moment donné pour cela, espérons-le.

14voto

David Ortiz Points 200

Définir une largeur minimale sur les éléments enfants créera également un point de rupture. Par exemple, en cassant tous les 3 éléments,

flex-grow: 1;
min-width: 33%; 

S'il y a 4 éléments, le 4ème élément se mettra à la ligne en prenant les 100%. S'il y a 5 éléments, les 4ème et 5ème éléments se mettront à la ligne et prendront chacun 50%.

Assurez-vous d'avoir un élément parent avec,

flex-wrap: wrap

3voto

fiatjaf Points 954

La seule chose qui semble fonctionner est de définir flex-wrap: wrap; sur le conteneur, puis de somehow faire en sorte que l'enfant que vous voulez faire sortir remplisse toute la largeur, donc width: 100%; devrait fonctionner.

Cependant, si vous ne pouvez pas étirer l'élément à 100% (par exemple, s'il s'agit d'une ), vous pouvez lui appliquer une marge, par exemple width: 50px; margin-right: calc(100% - 50px).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X