Je veux avoir un menu vertical avec une hauteur spécifique.
Chaque enfant doit remplir la hauteur du parent et avoir un texte aligné au milieu.
Le nombre d'enfants est aléatoire, je dois donc travailler avec des valeurs dynamiques.
Div .container
contient un nombre aléatoire d'enfants ( .item
) qui doivent toujours remplir la hauteur du parent. Pour y parvenir, j'ai utilisé flexbox.
Pour créer des liens avec du texte aligné au milieu, j'utilise la display: table-cell
technique. Mais l'utilisation des affichages de table nécessite l'utilisation d'une hauteur de 100%.
Mon problème est que cela .item-inner { height: 100% }
ne fonctionne pas dans le webkit (Chrome).
- Existe-t-il une solution à ce problème?
- Ou existe-t-il une technique différente pour que tous
.item
remplissent la hauteur du parent avec le texte aligné verticalement au milieu?
Exemple ici jsFiddle, devrait être visualisé dans Firefox et Chrome
.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
.item {
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
height: 100%;
width: 100%;
display: table;
}
a {
background: orange;
display: table-cell;
vertical-align: middle;
}
<div class="container">
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
</div>
css
google-chrome
webkit
flexbox
Ricardo Castañeda
la source
la source
top:0
etleft:0
le faire apparaître comme prévu.Réponses:
Solution
Utilisez des conteneurs flex imbriqués.
Débarrassez-vous des hauteurs de pourcentage. Débarrassez-vous des propriétés de la table. Débarrassez-vous
vertical-align
. Évitez le positionnement absolu. Restez avec Flexbox tout au long.Appliquer
display: flex
à l'élément flexible (.item
), ce qui en fait un conteneur flexible. Cela définit automatiquementalign-items: stretch
, qui indique à l'enfant (.item-inner
) d'étendre la hauteur totale du parent.Important: supprimez les hauteurs spécifiées des éléments flexibles pour que cette méthode fonctionne. Si un enfant a une hauteur spécifiée (par exemple
height: 100%
), alors il ignorera laalign-items: stretch
venue du parent. Pour que lastretch
valeur par défaut fonctionne, la taille de l'enfant doit être calculée àauto
(explication complète ).Essayez ceci (pas de modification du HTML):
Afficher l'extrait de code
Démo jsFiddle
Explication
Cela ne fonctionne pas car vous utilisez le pourcentage de hauteur d'une manière qui n'est pas conforme à l'implémentation traditionnelle de la spécification.
En d'autres termes, pour que le pourcentage de hauteur fonctionne sur un enfant entrant, le parent doit avoir une hauteur définie.
Dans votre code, le conteneur de niveau supérieur a une hauteur définie:
.container { height: 20em; }
Le conteneur de troisième niveau a une hauteur définie:
.item-inner { height: 100%; }
Mais entre eux, le conteneur de deuxième niveau -
.item
- n'a pas de hauteur définie. Webkit voit cela comme un lien manquant..item-inner
dit à Chrome: donnez-moiheight: 100%
. Chrome regarde le parent (.item
) pour référence et répond: 100% de quoi? Je ne vois rien (en ignorant laflex: 1
règle qui existe). En conséquence, il s'appliqueheight: auto
(hauteur du contenu), conformément à la spécification.Firefox, d'autre part, accepte désormais la hauteur de flexion d'un parent comme référence pour le pourcentage de taille de l'enfant. IE11 et Edge acceptent également les hauteurs flexibles.
En outre, Chrome acceptera
flex-grow
comme référence parent adéquate s'il est utilisé en conjonction avecflex-basis
(toute valeur numérique fonctionne (auto
ne le sera pas), y comprisflex-basis: 0
). Cependant, à ce jour, cette solution échoue dans Safari.Afficher l'extrait de code
Quatre solutions
1. Spécifiez une hauteur sur tous les éléments parents
Une solution multi-navigateur fiable consiste à spécifier une hauteur sur tous les éléments parents. Cela empêche les liens manquants, que les navigateurs Webkit considèrent comme une violation de la spécification.
Notez que
min-height
etmax-height
ne sont pas acceptables. Ce doit être laheight
propriété.Plus de détails ici: Utilisation de la
height
propriété CSS et des valeurs de pourcentage2. Positionnement relatif et absolu CSS
S'applique
position: relative
au parent etposition: absolute
à l'enfant.Taille l'enfant
height: 100%
etwidth: 100%
, ou utiliser les propriétés offset:top: 0
,right: 0
,bottom: 0
,left: 0
.Avec un positionnement absolu, la hauteur en pourcentage fonctionne sans hauteur spécifiée sur le parent.
3. Supprimez les conteneurs HTML inutiles (recommandé)
Y a-t-il besoin de deux conteneurs autour
button
? Pourquoi ne pas supprimer.item
ou.item-inner
, ou les deux? Bien que lesbutton
éléments échouent parfois en tant que conteneurs flexibles , ils peuvent être des éléments flexibles. Envisagez de fairebutton
un enfant de.container
ou.item
et de supprimer la majoration gratuite.Voici un exemple:
Afficher l'extrait de code
4. Conteneurs Flex imbriqués (recommandé)
Débarrassez-vous des hauteurs de pourcentage. Débarrassez-vous des propriétés de la table. Débarrassez-vous
vertical-align
. Évitez le positionnement absolu. Restez avec Flexbox tout au long.Appliquer
display: flex
à l'élément flexible (.item
), ce qui en fait un conteneur flexible. Cela définit automatiquementalign-items: stretch
, qui indique à l'enfant (.item-inner
) d'étendre la hauteur totale du parent.Important: supprimez les hauteurs spécifiées des éléments flexibles pour que cette méthode fonctionne. Si un enfant a une hauteur spécifiée (par exemple
height: 100%
), alors il ignorera laalign-items: stretch
venue du parent. Pour que lastretch
valeur par défaut fonctionne, la taille de l'enfant doit être calculée àauto
(explication complète ).Essayez ceci (pas de modification du HTML):
Afficher l'extrait de code
jsFiddle
la source
Solution: Retirer
height: 100%
en .item-intérieur et ajouterdisplay: flex
à .itemDémo: https://codepen.io/tronghiep92/pen/NvzVoo
la source
La spécification d'un attribut flex au conteneur a fonctionné pour moi:
Cela garantit que la hauteur est définie et ne croît pas non plus.
la source
Pour Mobile Safari, il existe un correctif du navigateur. vous devez ajouter -webkit-box pour les appareils iOS.
Ex.
si vous utilisez une
align-items: stretch;
propriété pour l'élément parent, supprimez l'height : 100%
élément de l'élément enfant.la source
J'ai eu un problème similaire dans iOS 8, 9 et 10 et les informations ci-dessus n'ont pas pu le résoudre, mais j'ai découvert une solution après une journée de travail. Certes, cela ne fonctionnera pas pour tout le monde, mais dans mon cas, mes articles étaient empilés dans une colonne et avaient 0 hauteur alors qu'il aurait dû être la hauteur du contenu. Changer le CSS pour être en ligne et envelopper a résolu le problème. Cela ne fonctionne que si vous avez un seul élément et qu'ils sont empilés, mais comme cela m'a pris un jour pour le découvrir, j'ai pensé que je devrais partager ma solution!
la source
J'ai eu un bug similaire, mais en utilisant un nombre fixe pour la hauteur et non un pourcentage. C'était aussi un conteneur flexible à l'intérieur du corps (qui n'a pas de hauteur spécifiée). Il est apparu que sur Safari, mon conteneur flexible avait une hauteur de 9 pixels pour une raison quelconque, mais dans tous les autres navigateurs, il affichait la bonne hauteur de 100 pixels spécifiée dans la feuille de style.
J'ai réussi à le faire fonctionner en ajoutant à la fois les propriétés
height
etmin-height
à la classe CSS.Les éléments suivants ont fonctionné pour moi sur Safari 13.0.4 et Chrome 79.0.3945.130:
J'espère que cela t'aides!
la source