web-dev-qa-db-fra.com

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

Je ne pense pas que cela fasse encore partie de la norme flexbox, mais y a-t-il une astuce pour suggérer ou forcer le wrapping 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. Ainsi, au lieu d'avoir (par exemple) des éléments de menu orphelins sur la ligne suivante, je casse au milieu du menu.

Voici le code HTML de départ:

<ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
    <li>Five</li>
</ul>

Et css:

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

J'aimerais quelque chose comme ce qui suit:

/* inside media query targeting width */
li:nth-child(2n) {
    flex-break: after;
}

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

131
theazureshadow

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%;
}

Cela oblige l'enfant à constituer 100% de la largeur du conteneur avant tout autre calcul. Comme le conteneur est configuré pour se rompre au cas où il n'y aurait pas assez d'espace, il le fera avant et après cet enfant.

109
luksak

==========================

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

EDIT: C’est très facile à faire avec Grid maintenant: https://codepen.io/anon/pen/mGONxv?editors=11

==========================

Je ne pense pas que vous puissiez casser après un article spécifique. Le mieux que vous puissiez faire est probablement de changer la base de flexibilité à vos points d'arrêt. Alors:

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 casser après un élément spécifique! Heydon Pickering a lancé un peu de magie css dans un article de A List Apart: http://alistapart.com/article/quantity-queries-for-css

EDIT 2: Regardez la réponse suivante: saut de ligne dans la flexbox multiligne

@luksak fournit également une excellente réponse

59
jbenjohnson

Il y a une partie de la spécification qui sonne comme ça ... directement dans les sections "algorithme de mise en page flexible" et "dimensionnement principal":

Sinon, à partir du premier élément non collecté, collectez les éléments consécutifs un par un jusqu'à la première fois que le prochain élément collecté ne rentre pas dans la taille principale interne du conteneur flexible ou jusqu'à ce qu'une rupture forcée se produise. Si le tout premier élément non récupéré ne convient pas, récupérez-le simplement dans la ligne. Une rupture est forcée lorsque 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 ressemble certainement à ceci (mis à part le fait que les sauts de page doivent être destinés à l'impression), lors de la mise en page d'une structure potentiellement multi-lignes flex (que je prends d'une autre partie de la spécification en est une sans flex-wrap: nowrap) un page-break-after: always ou break-after: always devrait provoquer un casser 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é ceci et cela n'a pas été implémenté de cette façon dans ...

  • Safari (jusqu'à 7)
  • Chrome (jusqu'à 43 dev)
  • Opéra (jusqu'à 28 dev et 12.16)
  • IE (jusqu'à 11)

Cela fonctionne comme cela (pour moi du moins) ressemble à:

  • Firefox (28+)

Échantillon à http://codepen.io/morewry/pen/JoVmVj .

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

Mais le sujet a été repris sur la liste de diffusion et, quoi que cela puisse paraître, ce n'est apparemment pas ce qu'ils voulaient dire, à l'exception de la pagination. Il n’ya donc aucun moyen d’emballer avant ou après une boîte particulière dans un agencement flexible sans imbriquer des agencements flexibles successifs à l’intérieur d’enfants flexibles ou de manipuler des largeurs spécifiques (par exemple, flex-basis: 100%).

Ceci est profondément énervant, bien sûr, car travailler avec l’implémentation de Firefox confirme mes soupçons sur le fait que cette fonctionnalité est incroyablement utile. Outre l’amélioration de l’alignement vertical, cette absence évite une grande partie de l’utilité de la disposition flexible dans de nombreux scénarios. Le fait d'ajouter des balises d'emballage avec des dispositions flexibles imbriquées pour contrôler le point auquel une ligne est renvoyée augmente la complexité du code HTML et du code CSS et, malheureusement, rend fréquemment order inutile. De même, le fait de forcer la largeur d'un élément sur 100% réduit le potentiel "réactif" de la structure flexible ou nécessite un grand nombre de requêtes très spécifiques ou de sélecteurs de comptage (par exemple, les techniques permettant d'obtenir le résultat général mentionné dans les autres réponses).

Au moins les flotteurs avaient clear. On espère que quelque chose sera ajouté à un moment ou à un autre.

26
morewry

Définir une largeur minimale sur les éléments enfants créera également un point d'arrêt. Par exemple, briser tous les 3 éléments,

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

S'il y a 4 éléments, le 4ème élément sera entièrement recouvert à 100%. S'il y a 5 éléments, les 4ème et 5ème éléments vont se terminer et prendre chacun 50%.

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

flex-wrap: wrap
10
David Ortiz

La seule chose qui semble fonctionner est de définir flex-wrap: wrap; sur le conteneur et de leur donner en quelque sorte le nom de l'enfant que vous souhaitez extraire après pour qu'il occupe toute la largeur, de sorte que width: 100%; fonctionne.

Si, toutefois, vous ne pouvez pas étendre l'élément à 100% (par exemple, s'il s'agit d'un <img>), vous pouvez lui appliquer une marge, comme width: 50px; margin-right: calc(100% - 50px).

2
fiatjaf