Altura igual de elementos dentro del elemento de cuadrícula con diseño de cuadrícula CSS
grid height (2)
¿Es posible?
tldr; Sí.
Codepen Demo # 2 (Usa SASS y es configurable)
La dificultad aquí es que cada artículo es una cuadrícula dentro de sí mismo y, por lo tanto, un artículo no tiene conocimiento de otro. Debido a esto, no hay forma de que un componente de un artículo, como un encabezado, se ajuste de acuerdo con la altura de un encabezado en otro artículo.
En realidad, hay una manera de lograr esto con las cuadrículas de CSS y sin cambiar ningún marcado.
Podríamos ''aplanar'' la estructura con CSS de modo que todos los componentes de todos los artículos sean parte de una sola cuadrícula CSS: el contenedor de artículos.
Esto es posible sin siquiera cambiar el marcado actual configurando los artículos con
display: contents
display: contenido ( caniuse )
De caniuse :
display: contents
hace que los elementos secundarios de un elemento aparezcan como si fueran elementos directos del elemento primario del elemento, ignorando el elemento mismo. Esto puede ser útil cuando se debe ignorar un elemento contenedor cuando se usa la cuadrícula CSS o técnicas de diseño similares.
Entonces, si configuramos los artículos con
display: contents
.container article {
display: contents;
}
Ahora todos los encabezados, secciones y pies de página se convierten en elementos de cuadrícula (directos) (del contenedor, que tiene
display:grid
) que podemos organizar usando la propiedad
grid-template-areas
.
.container {
display: grid;
grid-column-gap: 1em; /* horizontal gap between articles */
grid-template-columns: repeat(3, 1fr);
grid-template-areas: "header1 header2 header3"
"section1 section2 section3"
"footer1 footer2 footer3"
"header4 header5 header6"
"section4 section5 section6"
"footer4 footer5 footer6"
}
Dado que cada encabezado / sección / pie de página ocupa exactamente una celda, esto los obliga a ocupar la misma altura vertical . Entonces, por ejemplo, header1, header2 y header3 tendrán la misma altura, independientemente de su contenido.
Ahora configure las propiedades del
grid-area
la
grid-area
en cada una de las celdas.
article:nth-child(1) header {
grid-area: header1;
}
article:nth-child(2) header {
grid-area: header2;
}
article:nth-child(3) header {
grid-area: header3;
}
article:nth-child(4) header {
grid-area: header4;
}
article:nth-child(1) section {
grid-area: section1;
}
...
article:nth-child(4) section {
grid-area: section4;
}
article:nth-child(1) footer {
grid-area: footer1;
}
...
article:nth-child(4) footer {
grid-area: footer4;
}
Finalmente, establezca un espacio vertical entre cada fila de artículos (comenzando desde la segunda fila de artículos):
article:nth-child(n + 4) header {
margin-top: 1em;
}
Manifestación:
body {
width: 100%;
max-width: 1024px;
margin: auto;
}
.container {
display: grid;
grid-column-gap: 1em;
grid-template-columns: repeat(3, 1fr);
grid-template-areas: "header1 header2 header3"
"section1 section2 section3"
"footer1 footer2 footer3"
"header4 header5 header6"
"section4 section5 section6"
"footer4 footer5 footer6"
}
.container article {
display: contents;
}
article header {
background-color: #eeeeee;
}
article section {
background-color: #cccccc;
}
article footer {
background-color: #dddddd;
}
article:nth-child(n + 4) header {
margin-top: 1em;
}
article:nth-child(1) header {
grid-area: header1;
}
article:nth-child(2) header {
grid-area: header2;
}
article:nth-child(3) header {
grid-area: header3;
}
article:nth-child(4) header {
grid-area: header4;
}
article:nth-child(1) section {
grid-area: section1;
}
article:nth-child(2) section {
grid-area: section2;
}
article:nth-child(3) section {
grid-area: section3;
}
article:nth-child(4) section {
grid-area: section4;
}
article:nth-child(1) footer {
grid-area: footer1;
}
article:nth-child(2) footer {
grid-area: footer2;
}
article:nth-child(3) footer {
grid-area: footer3;
}
article:nth-child(4) footer {
grid-area: footer4;
}
<div class="container">
<article>
<header>
<h2>Header</h2>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
</footer>
</article>
<article>
<header>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
<p>Footer</p>
</footer>
</article>
<article>
<header>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
<p>Content</p>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
</footer>
</article>
<article>
<header>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
<p>Footer</p>
</footer>
</article>
</div>
Codepen Demo)
Por supuesto, en lugar de usar las propiedades
grid-template-areas
+
grid-area
, podríamos usar las propiedades
grid-row
+
grid-column
para lograr el mismo resultado -
Codepen demo
Nota: Me doy cuenta de que lo anterior es detallado y no exactamente una solución óptima, pero mi punto aquí es que es posible . Además, podríamos usar bucles SASS para hacer que ese código sea mucho más limpio y también configurable .
Sería bueno si hubiera alguna forma de
repetir un patrón
usando
grid-template-areas
, algo como:
pseudocódigo (no legal):
grid-template-areas: repeat("header1 header2 header3"
"section1 section2 section3"
"footer1 footer2 footer3")
... entonces podríamos obtener una solución más dinámica que funcionaría para la solución de
n
artículos estableciendo el área de cuadrícula usando nth-child como:
article:nth-child(3n + 1) header {
grid-area: header1;
}
etc. ... pero no creo que sea posible en este momento (¿o tal vez no sea necesario porque las subgrids podrán hacer esto?)
NÓTESE BIEN:
Grid Layout Module Level 2 presenta
subgrids
que harán que este problema sea más fácil de resolver y sin tener que usar
display: contents
¿Debo usar display: table?
Para el diseño que necesita,
display:table
no ayudará mucho.
En primer lugar, tendrías que reestructurar totalmente tu marcado para agrupar los
componentes del artículo
según lo dispuesto para los artículos, tendrías que hackear para diseñar la tabla para que parezca ''artículos'', pero incluso así, las tablas no se ajustan para que tú '' necesitaría envolver cada tres artículos en una tabla separada ... incluso si fuera posible, sería realmente complicado y difícil de mantener.
Tengo una secuencia de artículos dentro de un div de 4+ de longitud, sin ninguna etiqueta de fila de redondeo.
Necesito representarlo como una tabla de 3 artículos (columnas) por fila, probablemente con
display: grid
.
Cada artículo tiene un encabezado, una sección y un pie de página.
¿Cómo implementaría una altura igual para cada encabezado, una altura igual para cada sección y un pie de página de igual altura, alineado con la parte inferior del artículo, dentro de cada fila de artículos?
¿Es posible?
¿Debo usar
display: table
?
PD: Necesito cambiar el número de artículos por fila dinámicamente, dependiendo del ancho de la pantalla. Gracias
HTML:
body {
width: 100%;
max-width: 1024px;
margin: auto;
}
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.container article {
display: grid;
}
article header {
background-color: #eeeeee;
}
article section {
background-color: #cccccc;
}
article footer {
background-color: #dddddd;
}
<div class="container">
<article>
<header>
<h2>Header</h2>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
</footer>
</article>
<article>
<header>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
<p>Footer</p>
</footer>
</article>
<article>
<header>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
<p>Content</p>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
</footer>
</article>
<article>
<header>
<h2>Header</h2>
</header>
<section>
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
</section>
<footer>
<p>Footer</p>
<p>Footer</p>
</footer>
</article>
</div>
NB: JS está en desuso.
https://codepen.io/yudnikov/pen/mBvbGW?editors=1100#0
Esta solución :
grid-auto-rows: 1fr;
ha sido propuesto como un duplicado, que no lo es. Solo dará a los artículos la misma altura, mientras que, por ejemplo, los encabezados de cada artículo permanecen de diferente tamaño.
Originalmente tuve este problema:
Y la solución
grid-auto-rows: 1fr
resulta en esto:
La idea más simple que viene a mi mente es usar procentage. Por ejemplo:
.container{
width: 30%;
height: 80%;
}
Para tener un control total sobre su diseño, consulte la Referencia de valores predeterminados de CSS:
https://www.w3schools.com/cssref/css_default_values.asp
Para diferentes dispositivos, solo use archivos CSS separados ...