Je travaille sur une mise en page flexbox imbriquée qui devrait fonctionner comme suit:
Le niveau le plus à l'extérieur ( ul#main
) est une liste horizontale qui doit s'étendre vers la droite lorsque d'autres éléments y sont ajoutés. S'il devient trop grand, il devrait y avoir une barre de défilement horizontale.
#main {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
overflow-x: auto;
/* ...and more... */
}
Chaque élément de cette liste ( ul#main > li
) a un en-tête ( ul#main > li > h2
) et une liste interne ( ul#main > li > ul.tasks
). Cette liste interne est verticale et doit être intégrée dans des colonnes si nécessaire. Lors de l'encapsulation dans plus de colonnes, sa largeur doit augmenter pour faire de la place pour plus d'éléments. Cette augmentation de largeur doit également s'appliquer à l'élément contenant de la liste externe.
.tasks {
flex-direction: column;
flex-wrap: wrap;
/* ...and more... */
}
Mon problème est que les listes internes ne s'enroulent pas lorsque la hauteur de la fenêtre devient trop petite. J'ai essayé beaucoup de falsification de toutes les propriétés flex, en essayant de suivre méticuleusement les directives de CSS-Tricks , mais pas de chance.
Ce JSFiddle montre ce que j'ai jusqu'à présent.
Résultat attendu (ce que je veux) :
Résultat réel (ce que j'obtiens) :
Résultat plus ancien (ce que j'ai obtenu en 2015) :
METTRE À JOUR
Après quelques recherches, cela commence à ressembler à un problème plus important. Tous les principaux navigateurs se comportent de la même manière , et cela n'a rien à voir avec l'imbrication de ma conception flexbox. Les dispositions de colonne Flexbox encore plus simples refusent d'augmenter la largeur de la liste lorsque les éléments sont enveloppés.
Cet autre JSFiddle démontre clairement le problème. Dans les versions actuelles de Chrome, Firefox et IE11, tous les éléments sont correctement enveloppés; la hauteur de la liste augmente en row
mode, mais sa largeur n'augmente pas en column
mode. De plus, il n'y a pas du tout de redistribution immédiate des éléments lors du changement de hauteur d'un column
mode, mais il y en a en row
mode.
Cependant, les spécifications officielles (regardez spécifiquement l'exemple 5) semblent indiquer que ce que je veux faire devrait être possible.
Quelqu'un peut-il trouver une solution de contournement à ce problème?
MISE À JOUR 2
Après de nombreuses expériences en utilisant JavaScript pour mettre à jour la hauteur et la largeur de divers éléments lors des événements de redimensionnement, j'en suis venu à la conclusion qu'il est trop complexe et trop difficile d'essayer de le résoudre de cette façon. De plus, l'ajout de JavaScript rompt définitivement le modèle de flexbox, qui doit être maintenu aussi propre que possible.
Pour l'instant, je reviens à la overflow-y: auto
place de flex-wrap: wrap
pour que le conteneur interne défile verticalement en cas de besoin. Ce n'est pas joli, mais c'est une voie à suivre qui au moins ne rompt pas trop la convivialité.
column wrap
ne pas étendre sa largeur lors de l'emballage. Voir code.google.com/p/chromium/issues/detail?id=247963 pour plus d'informations.Réponses:
Le problème
Cela ressemble à une lacune fondamentale dans la disposition flexible.
Un conteneur flexible dans le sens des colonnes ne se développera pas pour accueillir des colonnes supplémentaires. (Ce n'est pas un problème dans
flex-direction: row
.)Cette question a été posée plusieurs fois (voir la liste ci-dessous), sans réponse claire en CSS.
Il est difficile d'épingler cela comme un bogue car le problème se produit dans tous les principaux navigateurs. Mais cela soulève la question:
On pourrait penser qu'au moins l'un d'entre eux ferait les choses correctement. Je ne peux que spéculer sur la raison. C'était peut-être une implémentation techniquement difficile et a été mise de côté pour cette itération.
MISE À JOUR: le problème semble être résolu dans Edge v16.
Illustration du problème
L'OP a créé une démonstration utile illustrant le problème. Je le copie ici: http://jsfiddle.net/nwccdwLw/1/
Options de contournement
Solutions Hacky de la communauté Stack Overflow:
"Il semble que ce problème ne puisse pas être résolu uniquement avec CSS, je vous propose donc une solution JQuery."
"Il est curieux que la plupart des navigateurs n'aient pas implémenté correctement les conteneurs flex de colonne, mais la prise en charge des modes d'écriture est raisonnablement bonne. Par conséquent, vous pouvez utiliser un conteneur flex de ligne avec un mode d'écriture vertical."
Plus d'analyse
Rapport de bogue de chrome
Réponse de Mark Amery
Autres articles décrivant le même problème
la source
En retard à la fête, mais rencontrait toujours ce problème des années plus tard. J'ai fini par trouver une solution en utilisant la grille. Sur le conteneur, vous pouvez utiliser
J'ai un exemple sur CodePen qui bascule entre le problème de la flexbox et le correctif de la grille: https://codepen.io/MandeeD/pen/JVLdLd
la source
grid-row-end: span X;
si vous avez besoin que certains des éléments occupent plus de lignes.Il est malheureux que tant de grands navigateurs souffrent de ce bug après de nombreuses années. Envisagez une solution de contournement Javascript. Chaque fois que la fenêtre du navigateur est redimensionnée ou que du contenu est ajouté à l'élément, exécutez ce code pour le redimensionner à la largeur appropriée. Vous pouvez définir une directive dans votre cadre pour le faire à votre place.
la source
Je viens de trouver une solution de contournement PURE CSS vraiment géniale ici.
https://jsfiddle.net/gcob492x/3/
Le plus délicat: définir
writing-mode: vertical-lr
dans la liste div puiswriting-mode: horizontal-tb
dans l'élément de liste. J'ai dû peaufiner les styles dans le JSFiddle (supprimer une grande partie des styles d'alignement, qui ne sont pas nécessaires pour la solution).Remarque: le commentaire indique que cela ne fonctionne que dans les navigateurs basés sur Chromium, et non dans Firefox. Je n'ai personnellement testé que dans Chrome. Il est possible qu'il y ait un moyen de modifier cela pour le faire fonctionner dans d'autres navigateurs ou qu'il y ait eu des mises à jour de ces navigateurs qui font que cela fonctionne.
Grand bravo à ce commentaire: lorsque les éléments flexbox s'enroulent en mode colonne, le conteneur n'augmente pas sa largeur . Fouiller ce fil de discussion m'a conduit à https://bugs.chromium.org/p/chromium/issues/detail?id=507397#c39 qui m'a conduit à ce JSFiddle.
la source
Puisqu'aucune solution ou solution de contournement appropriée n'a encore été suggérée, j'ai réussi à obtenir le comportement demandé avec une approche légèrement différente. Au lieu de séparer la mise en page en 3 divs différents, j'ajoute tous les éléments en 1 div et crée la séparation avec quelques divs supplémentaires entre les deux.
La solution proposée est codée en dur, en supposant que nous avons 3 sections, mais peut être étendue à une section générique. L'idée principale est d'expliquer comment nous pouvons réaliser cette mise en page.
:before
sur chaque premier élément, nous pouvons localiser le titre de chaque section.space
crée un espace entre les sectionsspace
ne couvre pas toute la hauteur de la section, j'ajoute également:after
aux sections afin de le positionner avec une position absolue et un fond blanc.z-index: -1
.la source
Solution JS possible.
la source
columns
propriété style pourrait être un point de départ pour une solution de travail. Peut-être ajuster le nombre de colonnes et la largeur de l'ul.