Grade de quadrados responsivos

170

Estou pensando em como criar um layout com quadrados responsivos . Cada quadrado teria conteúdo alinhado vertical e horizontalmente . O exemplo específico é exibido abaixo ...

quadrados responsivos com conteúdo

garethdn
fonte
Eu odeio como perguntas com ótimas respostas são fechadas aleatoriamente por pessoas com uma perspectiva realmente pedante sobre como deve ser o fluxo de pilha. Se eles têm respostas boas, aceitas e votadas ... por que fechá-la ??? Onde está a confusão? Certamente, em sua própria "grade de quadrados responsivos", pode ser necessário um pouco, ou muito, de explicação, mas essa é uma pergunta de 7 anos, mais de 160 anos e mais de 400 respostas. Estou votando para reabrir.
leinaD_natipaC

Respostas:

416

Você pode criar uma grade de quadrados responsiva com conteúdo centralizado na vertical e na horizontal apenas com CSS . Vou explicar como em um processo passo a passo, mas primeiro aqui estão duas demos do que você pode conseguir:

Grade quadrada 3x3 responsiva Imagens quadradas responsivas em uma grade 3x3

Agora vamos ver como fazer esses quadrados responsivos sofisticados!



1. Fazendo os quadrados responsivos:

O truque para manter os elementos quadrados (ou qualquer outra razão de aspecto) é usar porcentagem padding-bottom.
Nota lateral: você também pode usar o preenchimento superior ou a margem superior / inferior, mas o plano de fundo do elemento não será exibido.

Como o preenchimento superior é calculado de acordo com a largura do elemento pai ( consulte MDN para referência ), a altura do elemento muda de acordo com sua largura. Agora você pode manter sua proporção de acordo com sua largura.
Neste ponto, você pode codificar:

HTML :

 <div></div>

CSS

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

Aqui está um exemplo de layout simples da grade de quadrados 3 * 3 usando o código acima.

Com esta técnica, você pode fazer qualquer outra proporção, aqui está uma tabela que fornece os valores do preenchimento inferior de acordo com a proporção e uma largura de 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. Adicionando conteúdo dentro dos quadrados

Como você não pode adicionar conteúdo diretamente dentro dos quadrados (isso aumentaria sua altura e os quadrados não seriam mais quadrados), você precisa criar elementos filhos (neste exemplo, estou usando divs) dentro deles position: absolute;e colocar o conteúdo dentro deles . Isso retirará o conteúdo do fluxo e manterá o tamanho do quadrado.

Não se esqueça de adicionar position:relative;as divs pai, para que os filhos absolutos sejam posicionados / dimensionados em relação ao pai.

Vamos adicionar algum conteúdo à nossa grade de quadrados 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 <- com alguma formatação para torná-lo bonito!



3.Centralizar o conteúdo

Horizontalmente:

Isso é muito fácil, você só precisa adicionar text-align:centerao .content.
RESULTADO

Alinhamento vertical

Isso se torna sério! O truque é usar

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

mas não podemos usar display:table;on .squareou .contentdivs porque ele entra em conflito com, position:absolute;então precisamos criar dois filhos dentro de .contentdivs. Nosso código será atualizado da seguinte forma:

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




Terminamos agora e podemos dar uma olhada no resultado aqui:

RESULTADO AO VIVO EM Tela Cheia

violino editável aqui


web-tiki
fonte
2
@ d.raev sim. Os percentuais de preenchimento e margens são calculados de acordo com a largura do pai. Verifique aqui o padding developer.mozilla.org/pt-BR/docs/Web/CSS/padding
web-tiki
4
Isso é ótimo. Apenas um * { box-sizing: border-box; }alerta para os outros: se você estiver usando, será necessário ajustar a altura e a largura na div .content para 100%. :)
Rob Flaherty
2
qual é o cálculo por trás do valor da margem? e se eu quiser definir uma grade 5x5?
Kiwi1342 # /
2
@ kiwi1342 a soma de todas as margens + toda a largura de uma linha deve ser igual a 100%. Portanto, para uma grade 5x5, você pode usar 18% de largura com margens de 1% em cada lado dos elementos.
Web-tiki
1
Fantástico. Apenas um heads-up: Centro Para horizontalmente e verticalmente, basta fazer o .content um flexbox comjustify-content: center; align-items: center; flex-flow: column nowrap;
NonameSL
14

Você pode usar unidades vw (largura da visualização), o que tornaria os quadrados responsivos de acordo com a largura da tela.

Uma rápida maquete disso seria:

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
fonte
4
Não use margin-left: -4px;use margin-right:-4px. Prefiro não mexa com inconsistência na mincharspace mas definido para um invólucro pai font-size a 0 e que para os elementos filhos redefinir a 1rem(relativa-em)
Roko C. Buljan
9

A resposta aceita é ótima, no entanto, isso pode ser feito flexbox.

Aqui está um sistema de grade escrito com sintaxe BEM que permite que 1 a 10 colunas sejam exibidas por linha.

Se a última linha estiver incompleta (por exemplo, você escolhe mostrar 5 células por linha e há 7 itens), os itens finais serão centralizados horizontalmente. Para controlar o alinhamento horizontal dos itens à direita, basta alterar a justify-contentpropriedade na .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/

Isso é testado no FF e no Chrome.

Patrick Berkeley
fonte
3
Ainda assim, você está usando o fundo de preenchimento para fixar a altura; portanto, é a mesma resposta que aceita. A única diferença é como a grade é feita, e não a grade quadrada.
extempl
0

Eu uso esta solução para caixas responsivas de diferentes rações:

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

Veja a demonstração em JSfiddle.net

mitjajez
fonte
2
seria benéfico se você explicou mais sobre a sua resposta ... ou até mesmo incluir um jsFiddle
Wavesailor