Siatka responsywnych kwadratów

170

Zastanawiam się, jak zabrałbym się do stworzenia układu z responsywnymi kwadratami . Każdy kwadrat miałby zawartość wyrównaną w pionie i poziomie . Konkretny przykład przedstawiono poniżej ...

responsywne kwadraty z zawartością

garethdn
źródło
Nienawidzę tego, jak pytania ze świetnymi odpowiedziami są po prostu przypadkowo zamykane przez ludzi z naprawdę pedantycznym spojrzeniem na to, jak powinien wyglądać stackoverflow. Jeśli mają dobre, zaakceptowane, zaopiniowane odpowiedzi ... po co je zamknąć ??? Gdzie jest zamieszanie? Jasne, sama „siatka elastycznych kwadratów” może wymagać trochę lub dużo wyjaśnień, ale to jest 7-letnie pytanie, ponad 160 i ponad 400 odpowiedzi. Głosuję na ponowne otwarcie.
leinaD_natipaC

Odpowiedzi:

416

Elastyczną siatkę kwadratów z zawartością wyśrodkowaną w pionie i poziomie można utworzyć tylko za pomocą CSS . Wyjaśnię, jak krok po kroku, ale najpierw przedstawiam 2 dema tego, co możesz osiągnąć:

Czuła kwadratowa siatka 3x3 Elastyczne kwadratowe obrazy w siatce 3x3

Zobaczmy teraz, jak stworzyć te fantazyjne, responsywne kwadraty!



1. Tworzenie responsywnych kwadratów:

Sztuczka polegająca na utrzymywaniu kwadratowych elementów (lub jakichkolwiek innych proporcjach) polega na użyciu procentów padding-bottom.
Uwaga dodatkowa: możesz również użyć dopełnienia górnego lub marginesu górnego / dolnego, ale tło elementu nie będzie wyświetlane.

Ponieważ dopełnienie od góry jest obliczane zgodnie z szerokością elementu nadrzędnego ( patrz MDN ), wysokość elementu będzie się zmieniać zgodnie z jego szerokością. Możesz teraz zachować proporcje zgodnie z jego szerokością.
W tym momencie możesz zakodować:

HTML :

 <div></div>

CSS

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

Oto prosty przykład układu siatki 3 * 3 kwadratów przy użyciu powyższego kodu.

Dzięki tej technice możesz wykonać dowolny inny współczynnik proporcji, oto tabela podająca wartości wypełnienia dolnego zgodnie ze współczynnikiem proporcji i 30% szerokości.

 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. Dodanie zawartości wewnątrz kwadratów

Ponieważ nie możesz dodawać treści bezpośrednio do kwadratów (zwiększyłoby to ich wysokość, a kwadraty nie byłyby już kwadratami), musisz utworzyć elementy potomne (w tym przykładzie używam elementów div) wewnątrz nich z position: absolute; i umieścić zawartość w nich . Spowoduje to usunięcie zawartości z przepływu i zachowanie rozmiaru kwadratu.

Nie zapomnij o dodaniu position:relative;nadrzędnych elementów DIV, aby bezwzględne elementy podrzędne były ustawione / dopasowane do ich rozmiaru nadrzędnego.

Dodajmy trochę treści do naszej siatki kwadratów 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%;
}

WYNIK <- z pewnym formatowaniem, aby było ładnie!



3.Centrowanie treści

Poziomo:

Jest to dość proste, wystarczy dodać text-align:centerdo .content.
WYNIK

Wyrównanie w pionie

To staje się poważne! Sztuczka polega na użyciu

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

ale nie możemy używać display:table;on .squareani .contentdiv, ponieważ jest to sprzeczne z, position:absolute;więc musimy utworzyć dwoje dzieci w .contentelementach div. Nasz kod zostanie zaktualizowany w następujący sposób:

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




Skończyliśmy i możemy spojrzeć na wynik tutaj:

WYNIK NA ŻYWO NA PEŁNYM EKRANIE

edytowalne skrzypce tutaj


web-tiki
źródło
2
@ d.raev yes. Procentowe wypełnienia i marginesy są obliczane na podstawie szerokości rodzica. Sprawdź tutaj dopełnienie developer.mozilla.org/en-US/docs/Web/CSS/padding
web-tiki
4
To jest świetne. * { box-sizing: border-box; }Uwaga dla innych: jeśli używasz , musisz ustawić wysokość i szerokość w elemencie div .content na 100%. :)
Rob Flaherty
2
jaki jest rachunek za wartość depozytu zabezpieczającego? co jeśli chcę ustawić siatkę 5x5?
kiwi1342
2
@ kiwi1342 suma wszystkich marginesów i całej szerokości wiersza musi być równa 100%. Tak więc w przypadku siatki 5x5 można użyć 18% szerokości z 1% marginesami po każdej stronie elementów.
web-tiki
1
Fantastyczny. Tylko jedna uwaga: aby wyśrodkować w poziomie i w pionie, po prostu utwórz z .content flexbox zjustify-content: center; align-items: center; flex-flow: column nowrap;
NonameSL
14

Możesz użyć jednostek vw (szerokość widoku), które sprawią, że kwadraty będą reagować zgodnie z szerokością ekranu.

Szybka makieta tego byłaby:

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
źródło
4
Nie margin-left: -4px;używaj margin-right:-4px. Raczej nie zadzieraj z niespójnością w mincharspace, ale ustaw rozmiar czcionki nadrzędnej opakowania na 0, a następnie dla elementów potomnych zresetuj do 1rem(względne-em)
Roko C. Buljan
9

Przyjęta odpowiedź jest świetna, ale można to zrobić flexbox.

Oto system siatki napisany ze składnią BEM, który umożliwia wyświetlenie od 1 do 10 kolumn w każdym wierszu.

Jeśli ostatni wiersz jest niekompletny (na przykład zdecydujesz się pokazać 5 komórek w każdym wierszu i jest 7 elementów), końcowe elementy zostaną wyśrodkowane w poziomie. Aby kontrolować poziome wyrównanie końcowych elementów, po prostu zmień justify-contentwłaściwość pod .square-gridklasą.

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

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

Jest to testowane w FF i Chrome.

Patrick Berkeley
źródło
3
Nadal używasz dopełnienia do dołu do ustalenia wysokości, więc jest to w rzeczywistości ta sama odpowiedź, co zaakceptowano. Jedyną różnicą jest sposób wykonania siatki, a nie kwadratu.
przykład
0

Używam tego rozwiązania do responsywnych pudełek o różnych porcjach:

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

Zobacz demo na JSfiddle.net

mitjajez
źródło
2
byłoby korzystne, gdybyś wyjaśnił więcej na temat swojej odpowiedzi ... lub nawet dołączył JSFiddle
Wavesailor