tutorial support registro plantillas para framework formularios formulario example ejemplos bonitos html css image css3 css-grid

html - support - grid area css



¿Cómo hacer que las imágenes permanezcan dentro de las filas de un contenedor de cuadrícula CSS? (3)

El siguiente código muestra el comportamiento previsto cuando cambio el tamaño de la ventana en Chrome 60 y en Firefox 55 (pero no en iOS Safari 10.3; esa es probablemente otra pregunta de por qué se comporta mal en Safari).

html, body { width: 100%; height: 100%; padding: 0; margin: 0; border: 0; background-color: lightgrey; } .container { box-sizing: border-box; width: 100%; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: repeat(3, calc((60vh - 12px)/3)); /*grid-template-rows: 1fr 1fr 1fr;*/ /*grid-template-rows: auto auto auto;*/ height: 60vh; border: 3px solid yellow; padding: 3px; /*grid-gap: 20px;*/ /* <-- would also mess things up */ } .tile { } img { box-sizing: border-box; display: block; object-fit: contain; width: 100%; height: 100%; margin: 0; border: 0; padding: 3px; }

<!-- The image is 200 x 100 px: a green and a blue square next to each other. --> <div class="container"> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> </div>

Es importante que la relación de aspecto de las imágenes (2: 1)

Se conserva. Yo también hubiera esperado:

grid-template-rows: 1fr 1fr 1fr;

o:

grid-template-rows: auto auto auto;

hace que las imágenes encajen dentro de las filas de la cuadrícula, pero ninguna de ellas lo hace. Con:

grid-template-rows: repeat(3, calc((60vh - 12px)/3));

Me sale el comportamiento deseado. ¿Cómo puedo evitar resolver las matemáticas yo mismo? En otras palabras, ¿qué debo hacer para que grid-template-rows: 1fr 1fr 1fr; (o algo similar) funciona?

Ya es difícil calcular la altura del elemento contenedor en CSS en la página real. El objetivo es resolverlo con un diseño de cuadrícula CSS; sin JavaScript y sin hacks de imágenes de fondo.

Actualización: Originalmente excluí el pirateo de la imagen de fondo por dos razones.

  1. Pensé (debido a algunos malentendidos) que la url de la imagen de fondo debe estar en el archivo CSS, pero este no es el caso: puedo usar estilos en línea y tenerlos en el HTML.

  2. Se sintió hackear. Después de haber visto lo complicado y desordenado que es con los contenedores flexibles anidados dentro de un contenedor de cuadrícula solo para que funcione en Safari, simplemente recurrí al hack de imágenes de fondo, ya que es significativamente más limpio y funciona en todos los navegadores probados (Chrome, Firefox, Safari).

Al final, no es la respuesta aceptada que ayudó a resolver mi problema.


No sé qué tan bien desea que se ajusten las imágenes, pero podría usar minmax() . minmax() permite establecer un valor mínimo y máximo para el tamaño de la fila de la cuadrícula. Establecer auto para el mínimo y 33% para el máximo les permitirá ser tan pequeños como sea necesario para el contenido, y hasta un 33% de la altura del contenedor de la cuadrícula, pero no más grande . Esto mantendrá todos sus elementos de cuadrícula juntos a una altura máxima del 99% de las 60vh que ocupa el contenedor de cuadrícula.

Esta no es exactamente la forma automática que esperaba obtener ... todavía está declarando un tamaño, incluso si es relativo. Evita el cálculo de aspecto torpe calc((60vh - 12px) / 3) , aunque no hay nada realmente malo en usar ese método, a menos que haya otras restricciones en su publicación.

Sin embargo, la respuesta de Kukkuz y restablecer la min-height es una mejor solución y es lo que me faltaba.

html, body { width: 100%; height: 100%; padding: 0; margin: 0; border: 0; background-color: lightgrey; } .container { box-sizing: border-box; width: 100%; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: repeat(3, minmax(auto, 33%)); height: 60vh; border: 3px solid yellow; padding: 3px; } .tile { display: grid; } img { box-sizing: border-box; display: block; object-fit: contain; width: 100%; height: 100%; margin: 0; border: 0; padding: 3px; }

<!-- The image is 200 x 100 px: a green and a blue square next to each other. --> <div class="container"> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> </div>


Puede usar grid-template-rows: 1fr 1fr 1fr y, lo que es más importante, debe restablecer los valores min-width y min-height de los elementos de la cuadrícula que por defecto son auto (tanto como el contenido).

Para proporcionar un tamaño mínimo predeterminado más razonable para los elementos de la cuadrícula, esta especificación define que el valor automático de min-width / min-height también aplica un tamaño mínimo automático en el eje especificado a los elementos de la cuadrícula cuyo desbordamiento es visible y que abarcan al menos uno pista cuya función de tamaño de pista mínima es automática. (El efecto es análogo al tamaño mínimo automático impuesto a los artículos flexibles).

Fuente: W3C

Esto es similar a la regla del elemento de flexión automática con flexboxes . Vea la demostración a continuación donde los restablezco a cero :

html, body { width: 100%; height: 100%; padding: 0; margin: 0; border: 0; background-color: lightgrey; } .container { box-sizing: border-box; width: 100%; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr 1fr; height: 60vh; border: 3px solid yellow; padding: 3px; /*grid-gap: 20px;*/ /* <-- would also mess things up */ } .tile { min-width: 0; min-height: 0; } img { box-sizing: border-box; display: block; object-fit: contain; width: 100%; height: 100%; margin: 0; border: 0; padding: 3px; }

<!-- The image is 200 x 100 px: a green and a blue square next to each other. --> <div class="container"> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> </div>


Tiene las imágenes establecidas en height: 100% . ¿Pero el 100% de qué? 100% del contenedor? 100% de la ventana gráfica? 100% de la fila? Si es así, ¿cuál es la altura de la fila?

Chrome y Firefox hacen una suposición educada sobre tus intenciones. Han implementado algoritmos diseñados para ir más allá de la guía de especificaciones con el fin de mejorar la experiencia del usuario. Llaman a estas modificaciones "interventions" .

Safari no hace esto. Safari se adhiere estrictamente al lenguaje de especificaciones, que establece que una altura porcentual en un elemento debe tener una altura definida en el padre, de lo contrario se ignora.

Estas diferencias del navegador se explican con más detalle aquí:

  • Error de Safari de altura de fila de cuadrícula CSS
  • Chrome / Safari no llena el 100% de la altura del padre flexible

Luego debe considerar que los elementos de la cuadrícula, por defecto, no pueden ser más pequeños que su contenido. Si sus filas están establecidas en 1fr , pero las imágenes son más altas que el espacio asignado, las filas deben expandirse. Puede anular este comportamiento con min-height: 0 / min-width: 0 o overflow con cualquier valor que no sea visible .

Este comportamiento se explica con más detalle aquí:

  • Evite que los elementos de la cuadrícula se estiren en el diseño de cuadrícula CSS
  • ¿Por qué el elemento flexible no reduce el tamaño del contenido?

Aún así, una vez que tenga en cuenta la guía anterior, probablemente pueda hacer que su diseño funcione en Safari con una combinación de propiedades de cuadrícula y flex:

* { box-sizing: border-box; } body { display: flex; flex-direction: column; height: 100vh; margin: 0; background-color: lightgrey; } header, footer { flex: 0 0 100px; background-color: tomato; display: flex; align-items: center; justify-content: center; } .container { flex: 1; min-height: 0; display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: auto; padding: 3px; } .tile { display: flex; flex-direction: column; justify-content: center; min-height: 0; } img { max-width: 100%; max-height: 100%; object-fit: contain; padding: 3px; }

<header>HEADER</header> <!-- The image is 200 x 100 px: a green and a blue square next to each other. --> <div class="container"> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> <div class="tile"> <img src="https://i.stack.imgur.com/qbpIG.png" alt="." /> </div> </div> <footer>FOOTER</footer>

jsFiddle