Griglia di quadrati reattivi


170

Mi chiedo come farei per creare un layout con quadrati reattivi . Ogni quadrato avrebbe contenuto allineato verticalmente e orizzontalmente . L'esempio specifico viene visualizzato di seguito ...

quadrati reattivi con contenuto


Odio come le domande con grandi risposte vengano chiuse casualmente da persone con una visione veramente pedante su come dovrebbe essere lo stackoverflow. Se hanno risposte valide, accettate e votate ... perché chiuderlo ??? Dov'è la confusione? Certo, sulla sua "griglia di quadrati reattivi" potrebbe essere necessario un po ', o molto, di spiegare, ma questa è una domanda di 7 anni, 160+ con una risposta di 400+. Sto votando riaprendo.
leinaD_natipaC

Risposte:


416

Puoi creare una griglia reattiva di quadrati con contenuto centrato verticalmente e orizzontalmente solo con CSS . Spiegherò come procedere passo per passo, ma prima ecco due demo di ciò che puoi ottenere:

Griglia quadrata 3x3 reattiva Immagini quadrate reattive in una griglia 3x3

Ora vediamo come realizzare questi fantastici quadrati reattivi!



1. Realizzare i quadrati reattivi:

Il trucco per mantenere gli elementi quadrati (o qualunque altra proporzione) è usare la percentuale padding-bottom.
Nota a margine: puoi usare anche il padding superiore o il margine superiore / inferiore ma lo sfondo dell'elemento non verrà visualizzato.

Poiché l'imbottitura superiore viene calcolata in base alla larghezza dell'elemento principale ( vedere MDN per riferimento ), l'altezza dell'elemento cambierà in base alla sua larghezza. Ora puoi mantenere le proporzioni in base alla sua larghezza.
A questo punto puoi codificare:

HTML :

 <div></div>

CSS

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

Ecco un semplice esempio di layout della griglia di 3 * 3 quadrati usando il codice sopra.

Con questa tecnica, puoi creare qualsiasi altro formato, ecco una tabella che riporta i valori dell'imbottitura inferiore in base al formato e alla larghezza 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. Aggiunta di contenuto all'interno dei quadrati

Poiché non puoi aggiungere contenuti direttamente all'interno dei quadrati (aumenterebbe la loro altezza e i quadrati non sarebbero più quadrati) devi creare elementi figlio (per questo esempio sto usando div) al loro interno position: absolute;e inserire il contenuto al loro interno . Ciò eliminerà il contenuto dal flusso e manterrà le dimensioni del quadrato.

Non dimenticare di aggiungere position:relative;i div genitori in modo che i figli assoluti siano posizionati / dimensionati relativamente al loro genitore.

Aggiungiamo alcuni contenuti alla nostra griglia di quadrati 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%;
}

RISULTATO <- con un po 'di formattazione per renderlo carino!



3.Centro del contenuto

Orizzontalmente:

Questo è abbastanza semplice, basta aggiungere text-align:centera .content.
RISULTATO

Allineamento verticale

Questo diventa serio! Il trucco è usare

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

ma non possiamo usare display:table;su .squareo .contentdiv perché in conflitto con position:absolute;così abbiamo bisogno di creare due bambini all'interno .contentdiv. Il nostro codice verrà aggiornato come segue:

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




Abbiamo finito e possiamo dare un'occhiata al risultato qui:

RISULTATO A SCHERMO INTERO LIVE

violino modificabile qui



2
@ d.raev sì. I rilievi e i margini percentuali vengono calcolati in base alla larghezza del genitore. Controlla qui per il padding developer.mozilla.org/en-US/docs/Web/CSS/padding
web-tiki,

4
Questo è fantastico Solo un * { box-sizing: border-box; }avvertimento per gli altri: se stai usando dovrai regolare l'altezza e la larghezza nel div .content al 100%. :)
Rob Flaherty,

2
qual è il calcolo dietro il valore del margine? cosa succede se voglio impostare una griglia 5x5?
kiwi1342,

2
@ kiwi1342 la somma di tutti i margini + tutta la larghezza di una riga deve essere uguale al 100%. Pertanto, per una griglia 5x5, è possibile utilizzare una larghezza del 18% con margini dell'1% su ciascun lato degli elementi.
web-tiki,

1
Fantastico. Solo un avvertimento: per centrare in orizzontale e in verticale, basta trasformare il .content in un flexbox conjustify-content: center; align-items: center; flex-flow: column nowrap;
NonameSL

14

È possibile utilizzare le unità vw (view-width), che renderebbero i quadrati reattivi in ​​base alla larghezza dello schermo.

Un rapido esempio di questo sarebbe:

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>


4
Non usare l' margin-left: -4px;uso margin-right:-4px. Piuttosto non si scherza con l'incoerenza in mincharspace ma si imposta su una dimensione del carattere padre wrapper su 0 e che per gli elementi figlio reimpostati su 1rem(relative-em)
Roko C. Buljan

9

La risposta accettata è ottima, tuttavia è possibile farlo flexbox.

Ecco un sistema a griglia scritto con sintassi BEM che consente di visualizzare 1-10 colonne per riga.

Se l'ultima riga è incompleta (ad esempio, si sceglie di mostrare 5 celle per riga e vi sono 7 elementi), gli elementi finali verranno centrati orizzontalmente. Per controllare l'allineamento orizzontale degli elementi finali, è sufficiente modificare la justify-contentproprietà nella .square-gridclasse.

.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/

Questo è testato in FF e Chrome.


3
Tuttavia, stai usando il padding-bottom per fissare l'altezza, quindi in realtà è la stessa risposta accettata. L'unica differenza è la struttura della griglia, non la griglia quadrata.
esempio

0

Uso questa soluzione per scatole reattive di razioni diverse:

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

Guarda la demo su JSfiddle.net


2
sarebbe utile se spiegassi di più sulla tua risposta ... o includessi anche un JSFiddle
Wavesailor,
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.