Bambino con altezza massima: 100% trabocca genitore


139

Sto cercando di capire cosa mi sembra un comportamento inaspettato:

Ho un elemento con un'altezza massima del 100% all'interno di un contenitore che utilizza anche un'altezza massima ma, inaspettatamente, il bambino trabocca il genitore:

Caso di prova: http://jsfiddle.net/bq4Wu/16/

.container {  
    background: blue; 
    padding: 10px; 
    max-height: 200px; 
    max-width: 200px; 
}

img { 
    display: block;
    max-height: 100%; 
    max-width: 100%; 
}

Ciò è risolto, tuttavia, se al genitore viene assegnata un'altezza esplicita:

Caso di prova: http://jsfiddle.net/bq4Wu/17/

.container {  
    height: 200px;
}

Qualcuno sa perché il bambino non onorerebbe l'altezza massima del suo genitore nel primo esempio? Perché è richiesta un'altezza esplicita?

Risposte:


209

Quando specifichi una percentuale per max-heightsu un bambino, è una percentuale dell'altezza effettiva del genitore, non di quella del genitore max-height, stranamente . Lo stesso vale per max-width.

Quindi, quando non specifichi un'altezza esplicita sul genitore, non esiste un'altezza di base per il max-heightcalcolo del bambino , quindi max-heightcalcola a none, permettendo al bambino di essere il più alto possibile. L'unico altro vincolo che agisce sul bambino ora è quello max-widthdel suo genitore, e poiché l'immagine stessa è più alta di quanto sia larga, trabocca l'altezza del contenitore verso il basso, al fine di mantenere le proporzioni pur rimanendo il più grande possibile nel complesso.

Quando si esegue specificare un altezza esplicita per il genitore, allora il bambino sa che deve essere al massimo 100% di tale altezza esplicito. Ciò consente di essere vincolato all'altezza del genitore (pur mantenendo le proporzioni).


4
Questa è una spiegazione utile, in particolare mescolata con l'input del mio amico: "altezza massima: 100% (figlio) di altezza massima: 100% (genitore) = 0 - ecco perché tuo figlio non sta onorando il suo valore genitore".
iamkeir,

8
Non sono sicuro di quale risposta accettare - questa risponde al "perché".
iamkeir,

Ho solo risposto al "perché" perché non sono sicuro di quale sia il tuo obiettivo in quanto non è esplicitamente menzionato. Forse, se ci approfondisci, posso rispondere.
BoltClock

Ho accettato questo in quanto risponde alla mia vera domanda, grazie. Si prega di notare che la risposta di Daniel di seguito offre una soluzione.
iamkeir,

Nel mio caso, ho display: flex; flex-direction: columnrisolto il problema e ho aggiunto la barra di scorrimento che volevo.
xdevs23

73

Ho giocato un po '. Su un'immagine più grande in Firefox, ho ottenuto un buon risultato con l'utilizzo del valore della proprietà eredita. Questo ti aiuterà?

.container {
    background: blue;
    padding: 10px;
    max-height: 100px;
    max-width: 100px;
    text-align:center;
}

img {
    max-height: inherit;
    max-width: inherit;
}

Non sono sicuro di quale risposta accettare - questa risponde alla "correzione".
iamkeir,

Ha accettato @BoltClock per aver risposto al perché, ma grazie per aver offerto una correzione.
iamkeir,

1
Oltre a @BoltClock, la mia risposta è esattamente fare quello che dice. CSS sta solo dicendo al computer come gestire un elemento, ma dopo i calcoli avrà delimitato tutti i valori fino ai valori di base necessari per il rendering, come altezza, larghezza, colore, coordinate, ... La proprietà eredita sta dicendo all'img di accetta il valore "calcolato" del genitore. Quindi ottieni i valori calcolati per altezza e larghezza nelle tue proprietà css di altezza massima e larghezza massima.
Daniel,

2
Questo non funziona quando max:height: 100%invece di un'altezza fissa: jsfiddle.net/umbreak/n6czk9xt/1
Didac Montero

2
Non posso dichiarare larghezza e altezza come fisse perché il mio layout è reattivo dispaly: flex;. Ho aperto un nuovo thread: Ho aperto un nuovo thread: stackoverflow.com/questions/29732391/… Tuttavia, nel caso peggiore, potrei usare Jquery per recuperare la larghezza e l'altezza reali di img e impostarle nel div dell'immagine principale.
Didac Montero,

7

Ho trovato una soluzione qui: http://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/

Il trucco è possibile perché esiste una relazione tra WIDTH e PADDING-BOTTOM di un elemento. Così:

genitore:

container {
  height: 0;
  padding-bottom: 66%; /* for a 4:3 container size */
  }

figlio ( rimuovi tutti i CSS relativi alla larghezza , cioè larghezza: 100%):

img {
  max-height: 100%;
  max-width: 100%;
  position: absolute;     
  display:block;
  margin:0 auto; /* center */
  left:0;        /* center */
  right:0;       /* center */
  }

5

È possibile utilizzare la proprietà adatta all'oggetto

.cover {
    object-fit: cover;
    width: 150px;
    height: 100px;
}

Come suggerito qui

Una spiegazione completa di questa proprietà di Chris Mills in Dev.Opera

E ancora meglio in Trucchi CSS

È supportato in

  • Chrome 31+
  • Safari 7.1+
  • Firefox 36+
  • Opera 26+
  • Android 4.4.4+
  • iOS 8+

Ho appena verificato che anche vivaldi e cromo lo supportino (nessuna sorpresa qui)

Al momento non è supportato su IE, ma ... a chi importa ? Inoltre, iOS supporta l'adattamento degli oggetti, ma non la posizione dell'oggetto, ma lo farà presto.


Bella alternativa! Immagino che anche il flex-box potrebbe essere di aiuto, se il gradevole degrado in IE è accettabile.
iamkeir,

3

Ecco una soluzione per una domanda aperta di recente contrassegnata come duplicata di questa domanda. Il <img>tag stava superando l'altezza massima del genitore <div>.

Rotto: violino

Lavorare: violino

In questo caso, l'aggiunta display:flexai 2 <div>tag principali è stata la risposta


3

Invece di andare con l'altezza massima: 100% / 100%, un approccio alternativo per riempire tutto lo spazio sarebbe usare position: absolutecon top / bottom / left / right impostato su 0.

In altre parole, l'HTML sarebbe simile al seguente:

<div class="flex-content">
  <div class="scrollable-content-wrapper">
    <div class="scrollable-content">
      1, 2, 3
    </div>
   </div>
</div>
.flex-content {
  flex-grow: 1;
  position: relative;
  width: 100%;
  height: 100%;
}

.scrollable-content-wrapper {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow: auto;
}

.scrollable-content {
}

Puoi vedere un esempio dal vivo su Codesandbox - Overflow in CSS Flex / Grid


2

Forse qualcun altro può spiegare i motivi alla base del tuo problema, ma puoi risolverlo specificando l'altezza del contenitore e quindi impostando l'altezza dell'immagine su 100%. È importante che widthl'immagine venga visualizzata prima di height.

<html>
    <head>
        <style>
            .container {  
                background: blue; 
                padding: 10px;
                height: 100%;
                max-height: 200px; 
                max-width: 300px; 
            }

            .container img {
                width: 100%;
                height: 100%
            }
        </style>
    </head>
    <body>
        <div class="container">
            <img src="http://placekitten.com/400/500" />
        </div>
    </body>
</html>

Se vogliono che il contenitore diventi più piccolo se l'immagine è più piccola di 200x200, allora sì, deve essere fatto con altezza minima / altezza massima.
cimmanon,

2

Il più vicino che posso arrivare a questo è questo esempio:

http://jsfiddle.net/YRFJQ/1/

o

.container {  
  background: blue; 
  border: 10px solid blue; 
  max-height: 200px; 
  max-width: 200px; 
  overflow:hidden;
  box-sizing:border-box;
}

img { 
  display: block;
  max-height: 100%; 
  max-width: 100%; 
}

Il problema principale è che l'altezza prende la percentuale dell'altezza del contenitore, quindi cerca un'altezza esplicitamente impostata nel contenitore padre, non la sua altezza massima.

L'unico modo per ovviare a questo in qualche modo che posso vedere è il violino sopra dove puoi nascondere l'overflow, ma poi il riempimento funge ancora da spazio visibile per far fluire l'immagine, quindi funziona invece la sostituzione con un bordo solido (e quindi aggiungendo border-box per renderlo 200px se questa è la larghezza di cui hai bisogno)

Non sono sicuro se questo si adatterebbe a ciò di cui hai bisogno, ma il meglio che riesco a capire.


Purtroppo ritagliare l'immagine non è l'ideale. Grazie per la tua indicazione, comunque.
iamkeir,

1

Una buona soluzione è non usare l'altezza sul genitore e usarla solo sul figlio con Visualizza porta :

Esempio di violino: https://jsfiddle.net/voan3v13/1/

body, html {
  width: 100%;
  height: 100%;
}
.parent {
  width: 400px;
  background: green;
}

.child {
  max-height: 40vh;
  background: blue;
  overflow-y: scroll;
}

1

I contenitori generalmente già avvolgono bene il loro contenuto. Spesso non funziona anche al contrario: i bambini non riempiono bene i loro antenati. Quindi, imposta i valori di larghezza / altezza sull'elemento più interno anziché sull'elemento più esterno e lascia che gli elementi esterni avvolgano il loro contenuto.

.container {
    background: blue;
    padding: 10px;
}

img {
    display: block;
    max-height: 200px;
    max-width: 200px;
}

Bel colpo, mi piace questo.
iamkeir,

0

Il tuo contenitore non ha un'altezza.

Aggiungi altezza: 200 px;

ai contenitori css e il gattino rimarrà all'interno.


Grazie per l'input, ma l'ho identificato nel PO.
iamkeir,
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.