Responsive Square Mesh Layout

I want to create a grid with sensitive squares.

It seems to me that I can do this using the CSS Grid layout, but the problem is setting the height of each square equal to the width.

There is also a problem with installing a gutter between each square.

Would it be better to use flexbox?

Currently, my HTML looks like this, but it will be dynamic, so more squares can be added. And, of course, it should be responsive, so it’s ideal to use a media query to collapse it to one column.

<div class="square-container"> <div class="square"> <div class="content"> </div> </div> <div class="square"> <div class="content spread"> </div> </div> <div class="square"> <div class="content column"> </div> </div> </div> 

Using the css grid, this is how much I got

 .square-container{ display: grid; grid-template-columns: 30% 30% 30%; .square { } } 

I managed to do a little work with flexbox and use the space between the square alignments with a nice gutter, but he was still trying to get a height corresponding to the width of each square.

I was not able to find examples of how this is done using flexbox or the grid, but any examples would be appreciated as well.

thanks

+18
source share
3 answers

padding-bottom trick most commonly used to achieve this goal.

You can combine it with both Flexbox and CSS Grid, and since using percent for margins / indents gives conflicting results for flex / grid elements, you can add an additional wrapper or, as here, use a pseudo element, so the percent element is not flex / grid element.


Edit: Please note that the update is made for specification. , which should now give consistent results when used on flex / grid elements. Keep in mind that the problem still occurs in older versions.


Note that if you add content to the content element, it must be absolute in order to maintain a square aspect ratio.

Violin Demonstration - Flexbox

 .square-container { display: flex; flex-wrap: wrap; } .square { position: relative; flex-basis: calc(33.333% - 10px); margin: 5px; border: 1px solid; box-sizing: border-box; } .square::before { content: ''; display: block; padding-top: 100%; } .square .content { position: absolute; top: 0; left: 0; height: 100%; width: 100%; } 
 <div class="square-container"> <div class="square"> <div class="content"> </div> </div> <div class="square"> <div class="content spread"> </div> </div> <div class="square"> <div class="content column"> </div> </div> <div class="square"> <div class="content spread"> </div> </div> <div class="square"> <div class="content column"> </div> </div> </div> 

CSS Grid Version

 .square-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); grid-gap: 10px; } .square { position: relative; border: 1px solid; box-sizing: border-box; } .square::before { content: ''; display: block; padding-top: 100%; } .square .content { position: absolute; top: 0; left: 0; height: 100%; width: 100%; } 
 <div class="square-container"> <div class="square"> <div class="content"> </div> </div> <div class="square"> <div class="content spread"> </div> </div> <div class="square"> <div class="content column"> </div> </div> <div class="square"> <div class="content spread"> </div> </div> <div class="square"> <div class="content column"> </div> </div> </div> 
+16
source

Try using percentage view units> .

jsFiddle

 .square-container { display: grid; grid-template-columns: repeat(3, 30vw); grid-template-rows: 30vw; grid-gap: 2.5vw; padding: 2.5vw; background-color: gray; } .square { background-color: lightgreen; } body { margin: 0; /* remove default margins */ } 
 <div class="square-container"> <div class="square"> <div class="content"></div> </div> <div class="square"> <div class="content spread"></div> </div> <div class="square"> <div class="content column"></div> </div> </div> 

From the specification:

5.1.2. Percentage of video vmin length: units vw , vh , vmin , vmax

The percentages in the viewport refer to the size of the initial containing block. When the height or width of the initial containing block changes accordingly.

  • vw unit - equal to 1% of the width of the original containing block.
  • vh unit - equal to 1% of the height of the original containing the block.
  • vmin unit - equals less than vw or vh .
  • vmax unit is equal to more than vw or vh .
+8
source

You can use the fact that the indentation is calculated based on the width and set the padding-top: 100% directly for the square mesh elements (the mesh elements will now be square).


Update 2019

Please note that for flexible elements as well as mesh elements this did not work previously - see the post related in the comments to this answer:

Now that there is a consensus between browsers (newer versions) regarding the same behavior for padding for flexible and grid elements, you can use this solution.

See the demo below:

 .square-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); grid-gap: 10px; } .square { background: cadetblue; padding-top: 100%; /* padding trick directly on the grid item */ box-sizing: border-box; position: relative; } .square .content { /* absolutely positioned */ position: absolute; top: 0; right:0; left: 0; bottom: 0; } 
 <div class="square-container"> <div class="square"> <div class="content"> some content here</div> </div> <div class="square"> <div class="content"> some content here</div> </div> <div class="square"> <div class="content"> some content here</div> </div> <div class="square"> <div class="content"> some content here</div> </div> <div class="square"> <div class="content column">some content here and there is a lot of text here</div> </div> <div class="square"> <div class="content spread">text</div> </div> <div class="square"> <div class="content column">some text here</div> </div> </div> 
+1
source

Source: https://habr.com/ru/post/1272310/


All Articles