Cuadrícula de cuadrados receptivos

170

Me pregunto cómo haría para crear un diseño con cuadrados receptivos . Cada cuadrado tendría contenido alineado vertical y horizontalmente . El ejemplo específico se muestra a continuación ...

cuadrados receptivos con contenido

garethdn
fuente
Odio cómo las preguntas con excelentes respuestas se cierran al azar por personas con una perspectiva realmente pedante sobre cómo debería ser el stackoverflow. Si tienen respuestas buenas, aceptadas y votadas ... ¿por qué cerrarlas? ¿Dónde está la confusión que hay que tener? Claro, en su propia "cuadrícula de cuadrados receptivos" podría necesitar un poco, o mucho, de explicaciones, pero esta es una pregunta de más de 160 años con más de 400 respuestas. Estoy votando reabrir.
leinaD_natipaC

Respuestas:

416

Puede crear una cuadrícula de cuadrados receptiva con contenido centrado vertical y horizontalmente solo con CSS . Explicaré cómo en un proceso paso a paso, pero primero aquí hay 2 demostraciones de lo que puede lograr:

Cuadrícula 3x3 receptiva Imágenes cuadradas receptivas en una cuadrícula de 3x3

¡Ahora veamos cómo hacer estos cuadrados elegantes y sensibles!



1. Hacer los cuadrados receptivos:

El truco para mantener los elementos cuadrados (o cualquier otra relación de aspecto) es usar el porcentaje padding-bottom.
Nota al margen: también puede usar el relleno superior o el margen superior / inferior, pero el fondo del elemento no se mostrará.

Como el relleno superior se calcula de acuerdo con el ancho del elemento principal ( consulte MDN para referencia ), la altura del elemento cambiará de acuerdo con su ancho. Ahora puede mantener su relación de aspecto según su ancho.
En este punto puedes codificar:

HTML :

 <div></div>

CSS

div {
    width: 30%;
    padding-bottom: 30%; /* = width for a square aspect ratio */
}

Aquí hay un ejemplo de diseño simple de cuadrícula de 3 * 3 cuadrados usando el código anterior.

Con esta técnica, puede hacer cualquier otra relación de aspecto, aquí hay una tabla que proporciona los valores del relleno inferior de acuerdo con la relación de aspecto y un ancho del 30%.

 Aspect ratio  |  padding-bottom  |  for 30% width
------------------------------------------------
    1:1        |  = width         |    30%
    1:2        |  width x 2       |    60%
    2:1        |  width x 0.5     |    15%
    4:3        |  width x 0.75    |    22.5%
    16:9       |  width x 0.5625  |    16.875%




2. Agregar contenido dentro de los cuadrados

Como no puede agregar contenido directamente dentro de los cuadrados (expandiría su altura y los cuadrados ya no serían cuadrados), debe crear elementos secundarios (para este ejemplo estoy usando divs) dentro de ellos position: absolute;y colocar el contenido dentro de ellos . Esto eliminará el contenido del flujo y mantendrá el tamaño del cuadrado.

No olvide agregar position:relative;los divs principales para que los hijos absolutos se posicionen / dimensionen relativamente a sus padres.

Agreguemos algo de contenido a nuestra cuadrícula de cuadrados 3x3:

HTML :

<div class="square">
    <div class="content">
        .. CONTENT HERE ..
    </div>
</div>
... and so on 9 times for 9 squares ...

CSS :

.square {
    float:left;
    position: relative;
    width: 30%;
    padding-bottom: 30%; /* = width for a 1:1 aspect ratio */
    margin:1.66%;
    overflow:hidden;
}

.content {
    position:absolute;
    height:80%; /* = 100% - 2*10% padding */
    width:90%; /* = 100% - 2*5% padding */
    padding: 10% 5%;
}

RESULTADO <- con algo de formato para hacerlo bonito!



3. Centrando el contenido

Horizontalmente:

Esto es bastante fácil, sólo tiene que añadir text-align:centera .content.
RESULTADO

Alineamiento vertical

Esto se vuelve serio! El truco es usar

display:table;
/* and */
display:table-cell;
vertical-align:middle;

pero no podemos usar display:table;on .squareo .contentdivs porque entra en conflicto con position:absolute;lo que necesitamos crear dos hijos dentro de .contentdivs. Nuestro código se actualizará de la siguiente manera:

HTML :

<div class="square">
    <div class="content">
        <div class="table">
            <div class="table-cell">
                ... CONTENT HERE ...
            </div>
        </div>
    </div>
</div>
... and so on 9 times for 9 squares ...

CSS:

.square {
    float:left;
    position: relative;
    width: 30%;
    padding-bottom : 30%; /* = width for a 1:1 aspect ratio */
    margin:1.66%;
    overflow:hidden;
}

.content {
    position:absolute;
    height:80%; /* = 100% - 2*10% padding */
    width:90%; /* = 100% - 2*5% padding */
    padding: 10% 5%;
}
.table{
    display:table;
    height:100%;
    width:100%;
}
.table-cell{
    display:table-cell;
    vertical-align:middle;
    height:100%;
    width:100%;
}




Ya hemos terminado y podemos ver el resultado aquí:

RESULTADO EN PANTALLA COMPLETA EN VIVO

violín editable aquí


web-tiki
fuente
2
@ d.raev sí. Los porcentajes de relleno y márgenes se calculan de acuerdo con el ancho del elemento primario. Verifique aquí el relleno developer.mozilla.org/en-US/docs/Web/CSS/padding
web-tiki
44
Esto es genial. Solo un aviso para los demás: si está usando * { box-sizing: border-box; }, deberá ajustar la altura y el ancho en .content div al 100%. :)
Rob Flaherty
2
¿Cuál es el cálculo detrás del valor del margen? ¿Qué pasa si quiero establecer una cuadrícula de 5x5?
kiwi1342
2
@ kiwi1342 la suma de todos los márgenes + todo el ancho de una fila debe ser igual al 100%. Por lo tanto, para una cuadrícula de 5x5, podría usar un ancho del 18% con márgenes del 1% en cada lado de los elementos.
web-tiki
1
Fantástico. Solo un aviso: para centrar horizontal y verticalmente, simplemente convierta el .content en un flexbox conjustify-content: center; align-items: center; flex-flow: column nowrap;
NonameSL
14

Podría usar unidades vw (ancho de vista), lo que haría que los cuadrados respondan de acuerdo con el ancho de la pantalla.

Una maqueta rápida de esto sería:

html,
body {
  margin: 0;
  padding: 0;
}
div {
  height: 25vw;
  width: 25vw;
  background: tomato;
  display: inline-block;
  text-align: center;
  line-height: 25vw;
  font-size: 20vw;
  margin-right: -4px;
  position: relative;
}
/*demo only*/

div:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: inherit;
  width: inherit;
  background: rgba(200, 200, 200, 0.6);
  transition: all 0.4s;
}
div:hover:before {
  background: rgba(200, 200, 200, 0);
}
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>

jbutler483
fuente
44
No uses el margin-left: -4px;uso margin-right:-4px. En su lugar, no se meta con la inconsistencia en mincharspace, sino que se establece en un tamaño de fuente principal de contenedor a 0 y no para los elementos secundarios restablecidos a 1rem(relative-em)
Roko C. Buljan
9

La respuesta aceptada es excelente, sin embargo, esto se puede hacer con flexbox.

Aquí hay un sistema de cuadrícula escrito con sintaxis BEM que permite mostrar de 1 a 10 columnas por fila.

Si la última fila está incompleta (por ejemplo, elige mostrar 5 celdas por fila y hay 7 elementos), los elementos finales se centrarán horizontalmente. Para controlar la alineación horizontal de los elementos finales, simplemente cambie la justify-contentpropiedad debajo de la .square-gridclase.

.square-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.square-grid__cell {
  background-color: rgba(0, 0, 0, 0.03);
  box-shadow: 0 0 0 1px black;
  overflow: hidden;
  position: relative;
}

.square-grid__content {
  left: 0;
  position: absolute;
  top: 0;
}

.square-grid__cell:after {
  content: '';
  display: block;
  padding-bottom: 100%;
}

// Sizes  Number of cells per row

.square-grid__cell--10 {
  flex-basis: 10%;
}

.square-grid__cell--9 {
  flex-basis: 11.1111111%;
}

.square-grid__cell--8 {
  flex-basis: 12.5%;
}

.square-grid__cell--7 {
  flex-basis: 14.2857143%;
}

.square-grid__cell--6 {
  flex-basis: 16.6666667%;
}

.square-grid__cell--5 {
  flex-basis: 20%;
}

.square-grid__cell--4 {
  flex-basis: 25%;
}

.square-grid__cell--3 {
  flex-basis: 33.333%;
}

.square-grid__cell--2 {
  flex-basis: 50%;
}

.square-grid__cell--1 {
  flex-basis: 100%;
}

Fiddle: https://jsfiddle.net/patrickberkeley/noLm1r45/3/

Esto se prueba en FF y Chrome.

Patrick Berkeley
fuente
3
Aún así, está utilizando el relleno inferior para fijar la altura, por lo que en realidad es la misma respuesta que la aceptada. La única diferencia es cómo se hizo la cuadrícula, no la cuadrícula cuadrada.
extempl
0

Utilizo esta solución para cajas receptivas de diferentes raciones:

HTML:

<div class="box ratio1_1">
  <div class="box-content">
            ... CONTENT HERE ...
  </div>
</div>

CSS:

.box-content {
  width: 100%; height: 100%;
  top: 0;right: 0;bottom: 0;left: 0;
  position: absolute;
}
.box {
  position: relative;
  width: 100%;
}
.box::before {
    content: "";
    display: block;
    padding-top: 100%; /*square for no ratio*/
}
.ratio1_1::before { padding-top: 100%; }
.ratio1_2::before { padding-top: 200%; }
.ratio2_1::before { padding-top: 50%; }
.ratio4_3::before { padding-top: 75%; }
.ratio16_9::before { padding-top: 56.25%; }

Ver demo en JSfiddle.net

mitjajez
fuente
2
Sería beneficioso si explicaras más sobre tu respuesta ... o incluso incluyeras un JSFiddle
Wavesailor