Niño con altura máxima: 100% desborda padre

Estoy tratando de entender lo que parece ser un comportamiento inesperado para mí:

Tengo un elemento con una altura máxima del 100% dentro de un contenedor que también usa una altura máxima pero, inesperadamente, el elemento secundario desborda al elemento primario:

Caso de prueba: 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%; } 

Sin embargo, esto se soluciona si al padre se le asigna una altura explícita:

Caso de prueba: http://jsfiddle.net/bq4Wu/17/

 .container { height: 200px; } 

¿Alguien sabe por qué el niño no respetaría la altura máxima de su padre en el primer ejemplo? ¿Por qué se requiere una altura explícita?

Cuando se especifica un porcentaje para max-height en un niño, es un porcentaje de la altura real del padre, no la max-height del padre, por extraño que parezca . Lo mismo se aplica al max-width .

Entonces, cuando no se especifica una altura explícita en el elemento primario, entonces no se calcula la altura base para la altura max-height del niño, max-height max-height calcula para none , lo que permite que el niño sea lo más alto posible. La única otra restricción que actúa sobre el niño ahora es el max-width de su elemento primario, y dado que la imagen es más alta que ancha, desborda la altura del contenedor hacia abajo, para mantener su relación de aspecto sin dejar de ser tan grande como posible en general.

Cuando especifica una altura explícita para el padre, entonces el niño sabe que tiene que ser como máximo el 100% de esa altura explícita. Eso le permite estar limitado a la altura del padre (mientras mantiene su relación de aspecto).

 .container { background: blue; padding: 10px; max-height: 200px; max-width: 200px; float: left; margin-right: 20px; } .img1 { display: block; max-height: 100%; max-width: 100%; } .img2 { display: block; max-height: inherit; max-width: inherit; } 
  

Encontré una solución aquí: http://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/

El truco es posible porque existe una relación entre ANCHO y ARRIBA-ABAJO de un elemento. Asi que:

padre:

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

hijo ( eliminar todos los CSS relacionados con el ancho , es decir, ancho: 100%):

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

Tal vez alguien más pueda explicar las razones detrás de su problema, pero puede resolverlo especificando la altura del contenedor y luego estableciendo que la altura de la imagen sea del 100%. Es importante que el width de la imagen aparezca antes de la height .

      

Lo más cerca que puedo llegar a esto es este ejemplo:

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

El principal problema es que la altura toma el porcentaje de altura de los contenedores, por lo que busca una altura explícitamente establecida en el contenedor principal, no su altura máxima.

La única forma de esto hasta cierto punto que puedo ver es el violín arriba donde puedes ocultar el desbordamiento, pero luego el relleno sigue actuando como espacio visible para que fluya la imagen, por lo que reemplaza con un borde sólido en su lugar (y luego añadiendo border-box para que sea 200px si ese es el ancho que necesita)

No estoy seguro de si esto encajaría con lo que necesita, pero lo mejor que puedo llegar a ser.

Puede usar la propiedad object-fit

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

Como sugerido aquí

Una explicación completa de esta propiedad por Chris Mills en Dev.Opera

Y una aún mejor en CSS-Tricks

Es compatible con

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

Acabo de comprobar que vivaldi y cromo también lo soportan (no me sorprende)

Actualmente no es compatible con IE, pero … ¿a quién le importa ? Además, iOS admite object-fit, pero no object-position, pero pronto lo hará.

Una buena solución es no usar altura en el padre y usarla solo en el niño con View Port :

Ejemplo de Fiddle: 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; } 

Aquí hay una solución para una pregunta recientemente abierta marcada como un duplicado de esta pregunta. La etiqueta excedía la altura máxima del padre

.

Roto: Fiddle

Trabajando: Fiddle

En este caso, agregando display:flex a las 2 tags padre

fue la respuesta

Su contenedor no tiene una altura.

Añadir altura: 200px;

a los contenedores CSS y el gatito permanecerá dentro.