web-dev-qa-db-fra.com

Grille de carrés réactifs

Je me demande comment je pourrais créer une mise en page avec carrés réactifs. Chaque carré aurait aligné verticalement et horizontalement contenu. L'exemple spécifique est affiché ci-dessous ...

responsive squares with content

157
garethdn

Vous pouvez créer une grille de carrés sensible avec un contenu centré verticalement et horizontalement avec CSS. J'expliquerai comment procéder étape par étape, mais voici d'abord deux démonstrations de ce que vous pouvez réaliser:

Responsive 3x3 square gridResponsive square images in a 3x3 grid

Voyons maintenant comment créer ces carrés très réactifs!



1. Faire les carrés sensibles:

Le truc pour garder les éléments carrés (ou tout autre rapport d'aspect) est d'utiliser le pourcentage padding-bottom.
Note latérale: vous pouvez aussi utiliser le remplissage supérieur ou la marge supérieure/inférieure, mais l’arrière-plan de l’élément ne s’affiche pas.

Comme le remplissage supérieur est calculé en fonction de la largeur de l'élément parent ( Voir MDN pour référence ), la hauteur de l'élément va changer en fonction de sa largeur. Vous pouvez maintenant conserver ses proportions en fonction de sa largeur.
À ce stade, vous pouvez coder:

HTML:

 <div></div>

CSS

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

Voici une exemple de mise en page simple de 3 * 3 carrés utilisant le code ci-dessus.

Avec cette technique, vous pouvez créer n’importe quel autre rapport de format, voici un tableau donnant les valeurs de remplissage du bas en fonction du rapport de format et d’une largeur 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. Ajouter du contenu à l'intérieur des carrés

Comme vous ne pouvez pas ajouter de contenu directement à l'intérieur des carrés (cela augmenterait leur hauteur et les carrés ne seraient plus des carrés), vous devez créer des éléments enfants (pour cet exemple, j'utilise des divs) à l'intérieur d'eux avec position: absolute; et mettre le contenu à l'intérieur. Cela retirera le contenu du flux et conservera la taille du carré.

N'oubliez pas d'ajouter position:relative; sur les div parents afin que les enfants absolus soient positionnés/dimensionnés par rapport à leurs parents.

Ajoutons du contenu à notre grille de carrés 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%;
}

RÉSULTAT <- avec un peu de formatage pour le rendre joli!



3.Centrage du contenu

Horizontalement:

C'est assez facile, il vous suffit d'ajouter text-align:center à .content.
RÉSULTAT

Alignement vertical

Cela devient sérieux! L'astuce consiste à utiliser

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

mais nous ne pouvons pas utiliser display:table; sur .square ou .content divs car il est en conflit avec position:absolute; nous devons donc créer deux enfants dans .content divs. Notre code sera mis à jour comme suit:

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




Nous avons terminé et nous pouvons jeter un coup d’œil au résultat ici:

LIVE PULLSCREEN RESULT

violon éditable ici


392
web-tiki

Vous pouvez utiliser des unités vw (largeur de vue), qui rendraient les carrés réactifs en fonction de la largeur de l'écran.

Une rapide maquette de ceci serait:

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>
13
jbutler483

La réponse acceptée est excellente, mais cela peut être fait avec flexbox.

Voici un système de grille écrit avec syntaxe BEM qui permet d'afficher 1 à 10 colonnes par ligne.

Si la dernière ligne est incomplète (par exemple, vous choisissez d'afficher 5 cellules par ligne et s'il y a 7 éléments), les éléments suivants seront centrés horizontalement. Pour contrôler l'alignement horizontal des éléments de fin, modifiez simplement la propriété justify-content) sous la classe .square-grid.

.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%;
}
.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%;
}
<div class='square-grid'>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
  <div class='square-grid__cell square-grid__cell--7'>
    <div class='square-grid__content'>
      Some content
    </div>
  </div>
</div>

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

Ceci est testé en FF et Chrome.

8
Patrick Berkeley

J'ai écrit une bibliothèque, qui s'appelle simpleGrid, ce qui ne fait que ça, et le truc sympa à ce sujet, c'est que il peut gérer n'importe quel nombre d'éléments sans problèmes de performances. Il ajuste automatiquement le nombre d'éléments par ligne.

Si vous souhaitez que chaque élément ait un rapport de format spécifique, vous devez utiliser une astuce , ce qui est joli. Facile.

1
vsync

J'utilise cette solution pour les boites réactives de différentes rations:

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

Voir la démo sur JSfiddle.net

0
mitjajez