Comment combiner flexbox et défilement vertical dans une application pleine hauteur?

101

Je souhaite utiliser une application pleine hauteur utilisant flexbox. J'ai trouvé ce que je veux en utilisant l'ancien module de mise en page flexbox ( display: box;et d'autres choses) dans ce lien: application pleine hauteur CSS3 Flexbox et débordement

C'est une solution correcte pour les navigateurs qui ne prennent en charge que l'ancienne version des propriétés CSS flexbox.

Si je veux essayer d'utiliser les nouvelles propriétés flexbox, je vais essayer d'utiliser la deuxième solution dans le même lien répertorié comme un hack: utiliser un conteneur avec height: 0px;. Cela fait montrer un défilement vertical.

Je n'aime pas beaucoup cela car cela pose d'autres problèmes et c'est plus une solution de contournement qu'une solution.

html, body {
    height: 100%;    
}
#container {
	display: flex;
	flex-direction: column;
	height: 100%;
}
#container article {
	flex: 1 1 auto;
	overflow-y: scroll;
}
#container header {
    background-color: gray;
}
#container footer {
    background-color: gray;
}
<section id="container" >
    <header id="header" >This is a header</header>
    <article id="content" >
        This is the content that
        <br />
        With a lot of lines.
        <br />
        With a lot of lines.
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
    </article>
    <footer id="footer" >This is a footer</footer>
</section>

J'ai également préparé un JSFiddle avec un exemple de base: http://jsfiddle.net/ch7n6/

Il s'agit d'un site Web HTML pleine hauteur et le pied de page se trouve en bas à cause des propriétés flexbox de l'élément de contenu. Je vous suggère de déplacer la barre entre le code CSS et le résultat pour simuler différentes hauteurs.

José Cabo
la source
Ce n'est pas le comportement que vous recherchez? jsfiddle.net/ch7n6/2
cimmanon
2
jsfiddle.net/ch7n6/3 Oui! C'est. : D Mais je ne comprends pas pourquoi j'ai besoin d'indiquer une hauteur pour obtenir l'effet. Quoi qu'il en soit, réglage: hauteur: 1px; oeuvres
José Cabo
Maintenant, j'ai changé la hauteur en une hauteur min. Bien mieux. Merci.
José Cabo
1
@ JoséCabo +1 - belle hauteur de truc: 0 pour afficher le défilement vertical! Pouvez-vous expliquer pourquoi cela fonctionne?
Danield
1
Vous devez appliquer flex-shrink:0à la fois l'en-tête et le pied de page.
Saorikido

Réponses:

202

Merci à https://stackoverflow.com/users/1652962/cimmanon qui m'a donné la réponse.

La solution consiste à définir une hauteur pour l'élément déroulant vertical. Par exemple:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    height: 0px;
}

L'élément sera a la hauteur car FlexBox il recalcule sauf si vous voulez un min-height de sorte que vous pouvez utiliser height: 100px;qu'il est exactement le même que:min-height: 100px;

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    height: 100px; /* == min-height: 100px*/
}

Donc la meilleure solution si vous voulez un min-heightdans le scroll vertical:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 100px;
}

Si vous voulez juste un défilement vertical complet au cas où il n'y aurait pas assez d'espace pour voir l'article:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0px;
}

Le code final: http://jsfiddle.net/ch7n6/867/

José Cabo
la source
2
L'utilisation min-heightdans Chrome ne fonctionne pas, cela affecte en quelque sorte la taille du pied de page. En utilisant heightcependant, donne le résultat souhaité.
phant0m
1
Essayez de placer cette hauteur là où "auto". J'ai étudié cela et je pense que le bon endroit est cette propriété. Donc, au lieu d'utiliser min-height et height, utilisez-le.
José Cabo
height: 0correction de certains sauts de 2 pixels lorsque le contenu débordait par rapport à quand ce n'est pas le cas. Si étrange. Merci encore.
ProblemsOfSumit
@Sumit, pouvez-vous nous donner une idée du problème auquel vous êtes confronté?
José Cabo
J'ai ouvert le lien violon et ne semble plus fonctionner sur Chrome (fonctionne sous Firefox). La barre de défilement a disparu. Quelqu'un a-t-il une idée de la façon dont cela fonctionne à nouveau?
paris
61

Éditeur de spécifications Flexbox ici.

C'est une utilisation encouragée de flexbox, mais il y a quelques choses que vous devriez modifier pour un meilleur comportement.

  • N'utilisez pas de préfixes. La flexbox sans préfixe est bien prise en charge dans la plupart des navigateurs. Commencez toujours par sans préfixe et ajoutez uniquement des préfixes si nécessaire pour le prendre en charge.

  • Étant donné que votre en-tête et votre pied de page ne sont pas destinés à être flexibles, ils devraient tous les deux être flex: none;définis dessus. À l'heure actuelle, vous avez un comportement similaire en raison de certains effets qui se chevauchent, mais vous ne devriez pas vous y fier à moins que vous ne vouliez vous confondre accidentellement plus tard. (La valeur par défaut est flex:0 1 auto, donc ils commencent à leur hauteur automatique et peuvent rétrécir mais pas croître, mais ils sont également overflow:visiblepar défaut, ce qui déclenche leur valeur par défaut min-height:autopour les empêcher de diminuer du tout. Si vous définissez un overflowsur eux, le comportement des min-height:autochangements (passer à zéro plutôt qu'au contenu min) et ils seront soudainement écrasés par l' <article>élément extra-haut .)

  • Vous pouvez également simplifier le jeu <article> flex- il suffit de régler flex: 1;et vous serez prêt à partir. Essayez de vous en tenir aux valeurs communes de https://drafts.csswg.org/css-flexbox/#flex-common à moins que vous n'ayez une bonne raison de faire quelque chose de plus compliqué - elles sont plus faciles à lire et couvrent la plupart des comportements vous voudrez invoquer.

Xanthir
la source
21

La spécification actuelle dit ceci concernant flex: 1 1 auto:

Dimensionnent l'élément en fonction des propriétés width/ height, mais les rend totalement flexibles, de sorte qu'ils absorbent tout espace libre le long de l'axe principal. Si tous les éléments sont soit flex: auto, flex: initialou flex: none, tout espace libre positif après que les articles ont été de taille seront distribués uniformément sur les articles avec flex: auto.

http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#flex-common

Il me semble que si vous dites qu'un élément mesure 100 px de haut, il est traité plus comme une taille "suggérée", pas comme un absolu. Parce qu'il est autorisé à rétrécir et à grandir, il prend autant de place qu'il le permet. C'est pourquoi l'ajout de cette ligne à votre élément "principal" fonctionne: height: 0(ou tout autre petit nombre).

Cimmanon
la source