line-height come percentuale non funziona


87

Sto riscontrando un problema con l'altezza della linea che non riesco a capire.

Il codice seguente centrerà un'immagine all'interno di 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>

Tuttavia, se cambio l'altezza della linea al 100%, l'altezza della linea non ha effetto (o almeno non diventa il 100% del div).

Esempio jsfiddle

Qualcuno sa cosa sto sbagliando?

Risposte:


195

line-height: 100%indica il 100% della dimensione del carattere per quell'elemento, non il 100% della sua altezza. Infatti, l'altezza della riga è sempre relativa alla dimensione del font, non l'altezza, a meno che il suo valore utilizza un'unità di lunghezza assoluta ( px, ptecc).


3
Ah. Sono sempre gli stupidi errori che mi prendono. Grazie! Accetterò la tua risposta quando me lo permetterà.
Mi fa male la testa

1
Apparentemente gli autori delle specifiche hanno erroneamente pensato che nessuno avrebbe voluto impostare la dimensione del carattere / altezza della riga rispetto all'altezza dell'elemento ...
Andy

1
@ Anddy: La buona (?) Notizia è che questo sarà presto reso possibile grazie all'uso di variabili a cascata . Solo pochi anni di attesa ...
BoltClock

@BoltClock ah, bene! Sarebbe carino. Grazie per avermi fatto sapere!
Andy

vh è un'eccezione. In CSS3, se lo imposti come 100vh, funzionerà effettivamente come alcuni sviluppatori potrebbero volerlo. Tieni presente, tuttavia, che non funziona su browser meno recenti che non supportano CSS3.
Philll_t

99

So che questa domanda è vecchia, ma ho trovato quello che per me è la soluzione perfetta.

Aggiungo questo css al div che voglio centrare:

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

Funziona ogni volta ed è pulito.

Modifica: solo per motivi di completamento, uso scss e ho un pratico mixin che includo su ogni genitore che è figli diretti che voglio avere centrato verticalmente:

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

Spiegazione completa: div:beforeaggiungerà un elemento all'interno del div, ma prima dei suoi figli. Quando si utilizza :beforeo :afterdobbiamo usare una content:dichiarazione altrimenti non accadrà nulla, ma per il nostro scopo il contenuto può essere vuoto. Quindi diciamo all'elemento di essere alto quanto il suo genitore, purché l'altezza del suo genitore sia definita e questo elemento sia almeno inline-block. vertical-aligndefinisce la posizione verticale del sé rispetto al genitore, al contrario di text-alignciò che funziona in modo diverso.

La @mixindichiarazione è per gli utenti sass e sarebbe usata in questo modo:

div {
    @include vertical-align(middle)
}

Sebbene le altre risposte siano tutte corrette, questa è probabilmente la soluzione più pulita ed elegante al problema sopra.
mstation

Non la risposta, ma molto utile!
Alex

Potresti spiegare in dettaglio cosa sta succedendo lì? Non ho capito bene
Valdrinium

1
@Valdrinit Modificherò la risposta con ulteriori spiegazioni
santiago arizti

36

Quando usi la percentuale come altezza della riga, non si basa sul contenitore div, ma piuttosto sulla dimensione del carattere.


22

line-height: 100% sarebbe un modo semplice per centrare verticalmente gli elementi, se fosse calcolato in relazione al contenitore, ma sarebbe troppo facile, quindi non funziona.

Quindi, invece, è solo un altro modo per dire line-height: 1em (giusto?)

Un altro modo per centrare verticalmente un elemento sarebbe:

.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" */
}

1
Questo non funziona per me ... non sono sicuro se mi manchi qualcosa.
clifgriffin

1
@clifgriffin, prova a impostare una larghezza e un'altezza fisse sia sul contenitore che sul bambino "centrale", assicurandoti che il bambino sia più piccolo del contenitore. Il bambino dovrebbe finire centrato orizzontalmente e verticalmente all'interno del contenitore.
Rolf

23
sarebbe troppo facile, quindi non funziona +1 :-)
elipoultorak

@clifgriffin assicurati che il contenitore abbia la larghezza e l'altezza corrette, potresti centrare tutto in un div della stessa dimensione. Questo era l'adeguamento che dovevo fare.
David Carrigan,

@ user3576887 "sarebbe troppo facile, quindi non funziona" è esattamente il motivo per cui sto facendo un downvoting - c'è un ottimo motivo per cui non funziona come vorresti qui, e questo non dovrebbe essere oscurato a scopo di intrattenimento, critica o qualunque cosa dovrebbe essere.
TheThirdMan

11

potrebbe non essere carino, ma funziona e la sua semantica;

<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 dà a un elemento la capacità unica della tabella di allinearsi verticalmente (almeno penso che sia unico)


Grazie per la risposta, ho provato il tuo codice ma non sembra funzionare per me.
Mi fa male la testa

hmm, questo è un po 'strano; se puoi pubblicare parte del tuo codice in modo che io possa esaminarlo più da vicino, potrei essere in grado di aiutarti di più
Johan Olsson,

Olsson - Ho appena incollato il tuo codice in un JSFiddle e non ha funzionato. Grazie per l'offerta di aiuto, ma per ora posso farla franca impostando un'altezza di linea assoluta. Se questo cambia, approfondirò la tua risposta. Grazie ancora per l'aiuto!
Mi fa male la testa

6

Questa è una risposta molto tarda, tuttavia nei browser moderni, supponendo che anche l'elemento genitore sia il 100% dell'altezza dello schermo, è possibile utilizzare l' vhunità di visualizzazione. VIOLINO

line-height: 100vh;

Supporto del browser


Un raro uso legittimo di vh invece di%.
cytsunny

1

Questa soluzione funziona in IE9 e versioni successive. Per prima cosa impostiamo la prima posizione del bambino al 50% (al centro del genitore). Quindi, usando la translateregola, sposta il bambino verso l'alto di metà della sua altezza effettiva. Il vantaggio principale è che non abbiamo bisogno di definire l'altezza del bambino, è calcolata dinamicamente dal browser. JSFiddle

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

1

Un approccio più moderno è quello di utilizzare flexbox per questo, è più semplice e pulito. Tuttavia, FlexBox è un paradigma completamente diverso da quello inline-block, floato positiondi una volta.

Per allineare gli oggetti dentro di .parentte:

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

Questo è tutto. I figli dei flexgenitori vengono convertiti automaticamente in elementi figlio flessibili.

Dovresti leggere di più su flexbox, un buon punto di partenza è questo cheat sheet: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


0

Puoi impostare l' altezza della linea in base all'altezza dell'elemento. Se l'altezza dell'elemento 200px significa che devi impostare l'altezza della riga su 200px per centrare il testo.

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


0

Questa è la soluzione moderna in cui è necessario impostare il seguente CSS nel div contenitore o div esterno.

.outer-div {
  display: flex;
  justify-content: center;
  align-items: center; 
}

Un'altra soluzione seguente può essere applicata all'elemento che si vuole centrare verticalmente. Nota che il div esterno o contenitore dovrebbe essere

.inner-div {
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate(-50%,-50%);
    text-align: center;
}

Si noti che la posizione div esterna o contenitore deve essere relativa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.