Allinea verticalmente un'immagine all'interno di un div con altezza reattiva


135

Ho il seguente codice che imposta un contenitore che ha un'altezza che cambia con la larghezza quando il browser viene ridimensionato (per mantenere le proporzioni quadrate).

HTML

<div class="responsive-container">
    <div class="dummy"></div>
    <div class="img-container">
        <IMG HERE>
    </div>
</div>

CSS

.responsive-container {
    position: relative;
    width: 100%;
    border: 1px solid black;
}

.dummy {
    padding-top: 100%; /* forces 1:1 aspect ratio */
}

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

Come posso allineare verticalmente l'IMG all'interno del contenitore? Tutte le mie immagini hanno altezze variabili e il contenitore non può avere un'altezza fissa / altezza della linea perché è reattivo ... Per favore aiutatemi!


1
Ecco una soluzione semplice FlexBox: stackoverflow.com/a/31977476/3597276
Michael Benjamin

Risposte:


381

Ecco una tecnica per allineare gli elementi incorporati all'interno di un genitore , orizzontalmente e verticalmente allo stesso tempo:

Allineamento verticale

1) In questo approccio, creiamo un inline-block(pseudo-) elemento come primo (o ultimo) figlio del genitore , e impostiamo la sua heightproprietà in modo 100%che prenda tutta l'altezza del suo genitore .

2) Inoltre, l'aggiunta vertical-align: middlemantiene gli elementi in-line (-block) al centro dello spazio della linea. Quindi, aggiungiamo quella dichiarazione CSS al primo figlio e al nostro elemento (l' immagine ) entrambi.

3) Infine, al fine di rimuovere il carattere dello spazio bianco tra gli elementi inline (-block) , potremmo impostare a zero la dimensione del carattere del genitorefont-size: 0; .

Nota: ho usato la tecnica di sostituzione dell'immagine di Nicolas Gallagher nel seguito.

Quali sono i vantaggi?

  • Il contenitore ( padre ) può avere dimensioni dinamiche.
  • Non è necessario specificare esplicitamente le dimensioni dell'elemento immagine.

  • Possiamo facilmente usare questo approccio per allineare un <div>elemento anche verticalmente ; che può avere un contenuto dinamico (altezza e / o larghezza). Si noti che è necessario reimpostare la font-sizeproprietà di divper visualizzare il testo interno. Demo online .

<div class="container">
    <div id="element"> ... </div>
</div>
.container {
    height: 300px;
    text-align: center;  /* align the inline(-block) elements horizontally */
    font: 0/0 a;         /* remove the gap between inline(-block) elements */
}

.container:before {    /* create a full-height inline block pseudo=element */
    content: ' ';
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    height: 100%;
}

#element {
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    font: 16px/1 Arial sans-serif;        /* <-- reset the font property */
}

Il risultato

Allinea verticalmente un elemento nel suo contenitore

Contenitore reattivo

Questa sezione non risponderà alla domanda poiché l'OP sa già come creare un contenitore reattivo. Tuttavia, ti spiego come funziona.

Per modificare l' altezza di un elemento contenitore con la sua larghezza (rispettando le proporzioni), è possibile utilizzare un valore percentuale per la paddingproprietà top / bottom .

Un valore percentuale sull'imbottitura superiore / inferiore o sui margini è relativo alla larghezza del blocco contenitore.

Per esempio:

.responsive-container {
  width: 60%;

  padding-top: 60%;    /* 1:1 Height is the same as the width */
  padding-top: 100%;   /* width:height = 60:100 or 3:5        */
  padding-top: 45%;    /* = 60% * 3/4 , width:height =  4:3   */
  padding-top: 33.75%; /* = 60% * 9/16, width:height = 16:9   */
}

Ecco la demo online . Commenta le linee dal basso e ridimensiona il pannello per vedere l'effetto.

Inoltre, potremmo applicare la paddingproprietà a un bambino fittizio o :before/ :afterpseudo-elemento per ottenere lo stesso risultato. Ma nota che in questo caso, il valore percentuale paddingè relativo alla larghezza della .responsive-containerstessa.

<div class="responsive-container">
  <div class="dummy"></div>
</div>
.responsive-container { width: 60%; }

.responsive-container .dummy {
  padding-top: 100%;    /*  1:1 square */
  padding-top: 75%;     /*  w:h =  4:3 */
  padding-top: 56.25%;  /*  w:h = 16:9 */
}

Demo n . 1 .
Demo n. 2 (utilizzo dello :afterpseudo-elemento)

Aggiunta del contenuto

L'uso della padding-topproprietà provoca un enorme spazio nella parte superiore o inferiore del contenuto, all'interno del contenitore .

Per rimediare, abbiamo avvolgere il contenuto da un elemento contenitore, rimuovere tale elemento dal flusso normale documento utilizzando il posizionamento assoluto , e infine espandere l'involucro (bu usando top, right, bottome leftproprietà) per riempire l'intero spazio del suo genitore, il contenitore .

Eccoci qui:

.responsive-container {
  width: 60%;
  position: relative;
}

.responsive-container .wrapper {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}

Ecco la demo online .


Stare tutti insieme

<div class="responsive-container">
  <div class="dummy"></div>

  <div class="img-container">
    <img src="http://placehold.it/150x150" alt="">
  </div>
</div>
.img-container {
  text-align:center; /* Align center inline elements */
  font: 0/0 a;       /* Hide the characters like spaces */
}

.img-container:before {
  content: ' ';
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.img-container img {
  vertical-align: middle;
  display: inline-block;
}

Ecco la DEMO DI LAVORO .

Ovviamente, potresti evitare di usare lo ::beforepseudo-elemento per la compatibilità del browser e creare un elemento come primo figlio di .img-container:

<div class="img-container">
    <div class="centerer"></div>
    <img src="http://placehold.it/150x150" alt="">
</div>
.img-container .centerer {
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

DEMO AGGIORNATA .

Utilizzando le max-*proprietà

Per mantenere l'immagine all'interno della scatola di larghezza inferiore, è possibile impostare max-heighte max-widthproprietà sull'immagine:

.img-container img {
    vertical-align: middle;
    display: inline-block;
    max-height: 100%;  /* <-- Set maximum height to 100% of its parent */
    max-width: 100%;   /* <-- Set maximum width to 100% of its parent */
}

Ecco la DEMO AGGIORNATA .


1
Ciao Hashem, grazie mille per la tua risposta: ha funzionato come per magia per i browser desktop, anche quando si ridimensionano a larghezze inferiori. Ma sfortunatamente le immagini appaiono fuori posizione, sotto il div contenitore, su dispositivo mobile (Android v2.3.5). Qualche idea su una soluzione per questo?
user1794295

3
@ user1794295 Ho provato questo violino su tre dispositivi Android con Android v2.3 (Galaxy S II, Galaxy Note, Motorola Droid 4) tramite browserstack.com, tutto funziona come mi aspettavo. Puoi trovare il risultato qui: browserstack.com/screenshots /… . Fornisci uno screenshot o fai un test specifico del tuo problema. Ti aiuterò il più possibile.
Hashem Qolami,

1
Ciao, ecco alcuni screenshot: browserstack.com/screenshots/… - come puoi vedere con dispositivi più piccoli (ad es. Xperia, LG Nexus 4) le immagini compaiono sotto i contenitori ... cosa sta succedendo ?!
user1794295

3
@HashemQolami Questa è la cosa CSS più incredibile, da quando ho iniziato a costruire siti Web :).
Alexander Solonik,

1
Grazie per font-size: 0;!
Johannes Liebermann,

47

Con flexbox questo è facile:

VIOLINO

Basta aggiungere quanto segue al contenitore di immagini:

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex; /* add */
    justify-content: center; /* add to align horizontal */
    align-items: center; /* add to align vertical */
}

2
Questa soluzione funziona ed è molto più elegante nel mio caso. CSS3 Flex è fantastico!
Daniel Bonnell,

2
Non funziona in Safari :( Penso che il problema sia flessibile
yennefer,

1
@yennefer per safari usa il -webkit-prefisso o prova una libreria come prefixfree.js :)
QUB3X

Questo non funziona quando l'altezza del contenitore è reattiva (in percentuale).
Jenlampton,

1
Soluzione perfetta!
Nirus,

16

Usa questo CSS, poiché hai già il markup per esso:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
}

.img-container > img {
  margin-top:-50%;
  margin-left:-50%;  
}

Ecco un JsBin funzionante: http://jsbin.com/ihilUnI/1/edit

Questa soluzione funziona solo per le immagini quadrate (perché un valore percentuale margine superiore dipende dalla larghezza del contenitore, non dall'altezza). Per immagini di dimensioni casuali, è possibile effettuare le seguenti operazioni:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); /* add browser-prefixes */
}

Soluzione JsBin funzionante: http://jsbin.com/ihilUnI/2/edit


Spiacente, non funziona per me - questo sta solo riducendo la dimensione delle immagini a metà della larghezza del contenitore.
user1794295

2
Non vedo come ciò possa accadere dal CSS che ho citato. Fornisci un campione funzionante che posso vedere in modo da poter migliorare la mia risposta. PS: ho anche fornito un'altra soluzione :)
Tibos,

11

È possibile centrare un'immagine, sia in orizzontale che in verticale, utilizzando margin: autoe il posizionamento assoluto. Anche:

  1. È possibile abbandonare il markup aggiuntivo utilizzando gli pseudo elementi.
  2. È possibile visualizzare la parte centrale delle immagini GRANDI usando i valori negativo sinistro, superiore, destro e inferiore.

.responsive-container {
  margin: 1em auto;
  min-width: 200px;       /* cap container min width */
  max-width: 500px;       /* cap container max width */
  position: relative;     
  overflow: hidden;       /* crop if image is larger than container */
  background-color: #CCC; 
}
.responsive-container:before {
  content: "";            /* using pseudo element for 1:1 ratio */
  display: block;
  padding-top: 100%;
}
.responsive-container img {
  position: absolute;
  top: -999px;            /* use sufficiently large number */
  bottom: -999px;
  left: -999px;
  right: -999px;
  margin: auto;           /* center horizontally and vertically */
}
<p>Note: images are center-cropped on &lt;400px screen width.
  <br>Open full page demo and resize browser.</p>
<div class="responsive-container">
  <img src="http://lorempixel.com/400/400/sports/9/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/400/200/sports/8/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/200/400/sports/7/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/200/200/sports/6/">
</div>


Grazie! il tuo img css .responsive-container era l'unico che ha funzionato per me.
Diogo Garcia,

4

Prova questo

  .responsive-container{
          display:table;
  }
  .img-container{
          display:table-cell;
          vertical-align: middle;
   }

Mi dispiace che non funzioni, penso che il mio .img-containersia assolutamente posizionato - questo è necessario per mantenere le proporzioni quadrate / altezza dinamica.
user1794295

2

Ecco una tecnica che ti consente di centrare QUALSIASI contenuto sia in verticale che in orizzontale!

Fondamentalmente, hai solo bisogno di due contenitori e assicurati che i tuoi elementi soddisfino i seguenti criteri.

Il contenitore esterno:

  • avrebbe dovuto display: table;

Il contenitore interno:

  • avrebbe dovuto display: table-cell;
  • avrebbe dovuto vertical-align: middle;
  • avrebbe dovuto text-align: center;

La casella del contenuto:

  • avrebbe dovuto display: inline-block;

Se usi questa tecnica, aggiungi semplicemente la tua immagine (insieme a qualsiasi altro contenuto che desideri seguire) nella casella del contenuto.

Demo:

body {
    margin : 0;
}

.outer-container {
    position : absolute;
    display: table;
    width: 100%;
    height: 100%;
    background: #ccc;
}

.inner-container {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

.centered-content {
    display: inline-block;
    background: #fff;
    padding : 12px;
    border : 1px solid #000;
}

img {
   max-width : 120px;
}
<div class="outer-container">
   <div class="inner-container">
     <div class="centered-content">
        <img src="https://i.stack.imgur.com/mRsBv.png" />
     </div>
   </div>
</div>

Vedi anche questo violino !


2

Mi sono imbattuto in questo thread alla ricerca di una soluzione che:

  • utilizza il 100% della larghezza dell'immagine fornita
  • mantiene le proporzioni dell'immagine
  • mantiene l'immagine allineata verticalmente al centro
  • funziona con browser che non supportano completamente la flessibilità

Testando alcune delle soluzioni pubblicate sopra non ne ho trovata una che soddisfi tutti questi criteri, quindi ho messo insieme questa semplice che potrebbe essere utile per altre persone che hanno bisogno di fare lo stesso:

.container {
  width: 30%;
  float: left;
  border: 1px solid turquoise;
  margin-right: 3px;
  margin-top: 3px;
}

.container:last-of-kind {
  margin-right: 0px;
}

.image-container {
  position: relative;
  overflow: hidden;
  padding-bottom: 70%;
  /* this is the desired aspect ratio */
  width: 100%;
}

.image-container img {
  position: absolute;
  /* the following 3 properties center the image on the vertical axis */
  top: 0;
  bottom: 0;
  margin: auto;
  /* uses image at 100% width (also meaning it's horizontally center) */
  width: 100%;
}
<div class="container">
  <div class="image-container">
    <img src="http://placehold.it/800x800" class="img-responsive">
  </div>
</div>

<div class="container">
  <div class="image-container">
    <img src="http://placehold.it/800x800" class="img-responsive">
  </div>
</div>

<div class="container">
  <div class="image-container">
    <img src="http://placehold.it/800x800" class="img-responsive">
  </div>
</div>

Esempio di lavoro su JSFiddle


0

Provare

html

<div class="responsive-container">
     <div class="img-container">
         <IMG HERE>
     </div>
</div>

CSS

.img-container {
    position: absolute;
    top: 0;
    left: 0;
height:0;
padding-bottom:100%;
}
.img-container img {
width:100%;
}

0

codice HTML

<div class="image-container"> <img src=""/> </div>

codice css

img
{
  position: relative;
  top: 50%;
  transform: translateY(-50%);
 }

Sebbene questo frammento di codice sia il benvenuto e possa fornire qualche aiuto, sarebbe notevolmente migliorato se includesse una spiegazione di come affronta la domanda. Senza questo, la tua risposta ha un valore educativo molto inferiore: ricorda che in futuro stai rispondendo alla domanda per i lettori, non solo per la persona che chiede ora! Si prega di modificare la risposta di aggiungere una spiegazione, e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni.
Toby Speight,

0

Crea un altro div e aggiungi "dummy" e "img-container" all'interno del div

Fai HTML e CSS come segue

html , body {height:100%;}
.responsive-container { height:100%; display:table; text-align:center; width:100%;}
.inner-container {display:table-cell; vertical-align:middle;}
<div class="responsive-container">
    <div class="inner-container">
		<div class="dummy">Sample</div>
		<div class="img-container">
			Image tag
		</div>
	</div>	
</div>

Invece del 100% per il "contenitore reattivo" puoi dare l'altezza che desideri.,

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.