hauteur de ligne en pourcentage ne fonctionne pas

87

J'ai un problème avec la hauteur de ligne que je n'arrive pas à comprendre.

Le code suivant va centrer une image dans un div:

CSS

.bar {
    height: 800px;
    width: 100%;
    line-height:800px;
    background-color: #000;
    text-align: center; 
}

.bar img {
    vertical-align: middle;   
}

HTML

<div class="bar">
    <img src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

Cependant, si je change la hauteur de ligne à 100%, alors la hauteur de ligne ne prend pas effet (ou du moins ne devient pas 100% du div).

Exemple jsfiddle

Quelqu'un sait-il ce que je fais mal?

J'ai mal à la tête
la source

Réponses:

194

line-height: 100%signifie 100% de la taille de la police pour cet élément, et non 100% de sa hauteur. En fait, la hauteur de ligne est toujours par rapport à la taille de la police, et non la hauteur, à moins que sa valeur utilise une unité de longueur absolue ( px, pt, etc.).

BoltClock
la source
3
Ah. Ce sont toujours les erreurs stupides qui m'attirent. Merci! J'accepterai votre réponse quand elle me le permettra.
Ma tête me fait mal
1
Apparemment, les auteurs ont pensé à tort que personne ne voudrait définir la taille de la police / la hauteur de la ligne par rapport à la hauteur de l'élément ...
Andy
1
@Andy: La bonne (?) Nouvelle est que cela sera bientôt rendu possible grâce à l'utilisation de variables en cascade . Seulement quelques années d'attente ...
BoltClock
@BoltClock ah, cool! Ce sera sympa. Merci de me le faire savoir!
Andy
vh est une exception. Dans CSS3, si vous le définissez sur 100vh, cela fonctionnera comme certains développeurs le souhaitent. Notez cependant que cela ne fonctionne pas sur les anciens navigateurs qui ne prennent pas en charge CSS3.
Philll_t
97

Je sais que cette question est ancienne, mais j'ai trouvé ce qui pour moi est la solution de contournement parfaite.

J'ajoute ce css à la div que je veux centrer:

div:before {
  content: "";
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

Cela fonctionne à chaque fois et c'est propre.

Edit: Juste pour terminer, j'utilise scss et j'ai un mixin pratique que j'inclus sur chaque parent qui est des enfants directs que je veux centrer verticalement:

@mixin vertical-align($align: middle) {
  &:before {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: $align;
    // you can add font-size 0 here and restore in the children to prevent
    // the inline-block white-space to mess the width of your elements
    font-size: 0;
  }
  & > * {
    vertical-align: $align;
    // although you need to know the font-size, because "inherit" is 0
    font-size: 14px;
  }
}

Explication complète: div:beforeajoutera un élément à l'intérieur du div, mais avant l'un de ses enfants. Lors de l'utilisation :beforeou :afternous devons utiliser une content:déclaration sinon rien ne se passera, mais pour notre objectif, le contenu peut être vide. Ensuite, nous disons à l'élément d'être aussi grand que son parent, tant que la hauteur de son parent est définie et que cet élément est au moins un bloc en ligne. vertical-aligndéfinit la position verticale de soi par rapport au parent, par opposition à text-aligncela fonctionne différemment.

La @mixindéclaration est pour les utilisateurs sass et elle serait utilisée comme ceci:

div {
    @include vertical-align(middle)
}
santiago arizti
la source
Bien que les autres réponses soient toutes correctes, c'est probablement la solution la plus propre et la plus élégante au problème ci-dessus.
mstation
Pas la réponse, mais le plus utile!
Alex
Pouvez-vous expliquer ce qui se passe là-bas en détail? Je ne comprends pas tout à fait
Valdrinium
1
@Valdrinit je modifierai la réponse avec plus d'explications
santiago arizti
36

Lorsque vous utilisez le pourcentage comme hauteur de ligne, il n'est pas basé sur le conteneur div, mais plutôt sur la taille de la police.

Locrizak
la source
22

line-height: 100% serait un moyen facile de centrer verticalement des éléments, s'il était calculé par rapport au conteneur, mais ce serait trop facile, donc cela ne fonctionne pas.

Donc, à la place, c'est juste une autre façon de dire hauteur de ligne: 1em (non?)

Une autre façon de centrer verticalement un élément serait:

.container {
     position:relative;
}
.center {
     position:absolute;
     top:0; left:0; bottom:0; right:0;
     margin: auto;
     /* for horiz left-align, try "margin: auto auto auto 0" */
}
Rolf
la source
1
Cela ne fonctionne pas pour moi ... je ne sais pas si je manque quelque chose.
clifgriffin
1
@clifgriffin, essayez de définir une largeur et une hauteur fixes à la fois sur le conteneur et sur l'enfant "central", en vous assurant que l'enfant est plus petit que le conteneur. L'enfant doit se retrouver centré horizontalement et verticalement dans le conteneur.
Rolf
22
ce serait trop facile, donc ça ne marche pas +1 :-)
elipoultorak
@clifgriffin assurez-vous que le conteneur a la largeur et la hauteur correctes, vous pourriez tout centrer dans un div de la même taille. C'était l'ajustement que je devais faire.
David Carrigan le
@ user3576887 "ce serait trop facile, donc ça ne marche pas" est exactement la raison pour laquelle je vote contre cela - il y a une très bonne raison pour laquelle cela ne fonctionne pas comme vous le souhaiteriez ici, et cela ne devrait pas être obscurci à des fins de divertissement, de critique ou quoi que ce soit censé être.
TheThirdMan
11

peut-être pas joli, mais ça marche, et c'est sémantique;

<div class="bar" style="display: table; text-align: center;">
    <img style="display: table-cell; vertical-align: middle;" src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>

display: table-cell donne à un élément la capacité unique de table d'aligner verticalement (au moins je pense que c'est unique)

Johan Olsson
la source
Merci pour la réponse, j'ai essayé votre code mais cela ne semble pas fonctionner pour moi.
J'ai mal à la tête
hmm, c'est un peu étrange; si vous pouvez publier une partie de votre code pour que je puisse l'examiner de plus près, je pourrais peut-être vous aider davantage
Johan Olsson
Olsson - Je viens de coller votre code dans un JSFiddle et cela n'a pas fonctionné. Merci pour l'offre d'aide - mais je peux me permettre de définir une hauteur de ligne absolue pour le moment. Si cela change, j'examinerai plus en détail votre réponse. Merci encore pour votre aide!
Ma tête me fait mal
6

Il s'agit d'une réponse très tardive, mais dans les navigateurs modernes, en supposant que l'élément parent représente également 100% de la hauteur de l'écran, vous pouvez utiliser l' vhunité de fenêtre. VIOLON

line-height: 100vh;

Prise en charge du navigateur

FelisPhasma
la source
Une utilisation légitime rare de vh au lieu de%.
cytsunny
1

Cette solution fonctionne dans IE9 et au-dessus. Tout d'abord, nous définissons la position supérieure de l'enfant à 50% (milieu du parent). Ensuite, en utilisant la translaterègle, décalez l'enfant de la moitié de sa hauteur réelle. Le principal avantage est que nous n'avons pas besoin de définir la taille de l'enfant, elle est calculée dynamiquement par le navigateur. JSFiddle

.bar {
    height: 500px;
    text-align: center;
    background: green;
}
.bar img {
    position: relative;
    top: 50%;
    transform: translate(0, -50%);
}
Webars
la source
1

Une approche plus moderne consiste à utiliser flexbox pour cela, c'est plus simple et plus propre. Cependant, flexbox est un paradigme complètement différent de ce que inline-block, floatou positionétait autrefois.

Pour aligner les éléments à l'intérieur de .parentvous, procédez comme suit:

.parent {
  display: flex;
  align-items: center;
}

C'est à peu près tout. Les enfants des flexparents sont automatiquement convertis en éléments enfants flexibles.

Vous devriez en savoir plus sur flexbox, un bon point de départ est cette feuille de triche: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

santiago arizti
la source
0

Vous pouvez définir la hauteur de ligne en fonction de la hauteur de cet élément. Si la hauteur de l'élément 200px signifie que vous devez définir la hauteur de ligne sur 200px pour centrer le texte.

span {
  height: 200px;
  width: 200px; 
  border: 1px solid black;
  line-height: 200px; 
  display: block;
}
<span>Im vertically center</span>

Raja
la source