Roberto Pezzali
Roberto Pezzali

Reputation: 2494

Smarter way to create this responsive css grid

I'm getting crazy with a grid. For my website I have a modular grid with a fixed size, 3 x 2. In this grid I can distribute, without space and with a 1 px margin between every element, some blocks.

I can have 5 types of block:

In this image I show some variants, and un the right the "tablet" version. My Grid

I have to generate the grid using code so I don't want to create X fixed templates to fill, I want a single template that adapt itself. Now I'm using float and some class for every variant.

For Example for first cover variant

<section class="cover variant-1">
  <div class="cover-block horizontal" id="block-1">
    <img alt="image" src="https://via.placeholder.com/900x350" />
  </div>
  <div class="cover-block small" id="block-2">
    <img alt="image" src="https://via.placeholder.com/450x350" />
  </div>
  <div class="cover-block square" id="block-3">
    <img alt="image" src="https://via.placeholder.com/450x350" />
  </div>
 <div class="cover-block horizontal" id="block-4">
    <img alt="image" src="https://via.placeholder.com/900x350" />
  </div>
</section>

And for the second cover variant

<section class="cover variant-2">
  <div class="cover-block big-square" id="block-1">
    <img alt="image" src="https://via.placeholder.com/900x700" />
  </div>
  <div class="cover-block vertical" id="block-2">
    <img alt="image" src="https://via.placeholder.com/450x700" />
  </div>
</section>

The CSS is

.cover {
  float: none;
  max-width: 1350px;
  max-height: 700px;
  margin: 0;
}
.cover .cover-block {
  float: left;
  position: relative;
  border: 0px solid #fff;
}
.cover .cover-block img {
  width: 100%;
  height: 100%;
}
.cover .cover-block.huge {
  width: 1350px;
  height: 700px;
}
.cover .cover-block.vertical {
  width: 450px;
  height: 700px;
}
.cover .cover-block.horizontal {
  width: 900px;
  height: 350px;
}
.cover .cover-block.big-square {
  width: 900px;
  height: 700px;
}
.cover .cover-block.square {
  width: 450px;
  height: 350px;
}
.cover .variant-1 #block-1 {
  border-width: 0 1px 0 0;
}
.cover .variant-1 #block-2 {
  border-width: 0 1px 0 0;
}
.cover .variant-1 #block-4 {
  border-width: 1px 1px 0 0;
}
.cover .variant-1 #block-5 {
  border-width: 1px 0 0 0;
}
.cover .variant-2 #block-1 {
  border-width: 0 1px 0 0;
}
.cover .variant-2 #block-3 {
  border-width: 1px 1px 0 0;
}
.cover .variant-2 #block-4 {
  border-width: 1px 0 0 0;
}
.cover .variant-2 #block-5 {
  display: none;
}

Whit the floats I have to define an ID for every block to handle the 1 pixel space just in one direction, and I have also a lot of media queries to have this grid responsive.

Is there a smarter way to design my grid, maybe using flexbox?

Here is the Codepen

Upvotes: 4

Views: 2755

Answers (3)

Soft CodeOn
Soft CodeOn

Reputation: 41

Well, I found a simple Grid code. That will create three or more grid item responsive for all displays.

<style>
/* Mobile first */
.grid {
  float: left;
  width: 100%;
}
/* Responsive column widths */
@media (min-width: 700px) {
  /* For Mobile three grid */
  .grid {
    width: 33.33333%;
  }
}
.wrapper {
  margin-bottom: 60px;
}
.wrapper:before,
.wrapper:after{
  content: ' ';
  display: grid;
  clear: both;
}
/* Main Style Begin's */
.grid {
  background-color: #8f1558;
  color: white;
  padding: 50px;
  box-sizing: border-box;
  moz-box-sizing: border-box;
  text-align: center;
}
.grid:nth-child(3n - 2) {
  background-color: #54158f;
}
.grid:nth-child(3n) {
  background-color: #8a0e37;
}
  <style>
<div class="wrapper">
  <div class="grid"><h1>WELCOME FIRST GRID</h1></div>
  <div class="grid"><h1>WELCOME SECOND GRID</h1></div>
  <div class="grid"><h1>WELCOME THIRD GRID</h1></div>
</div>

Want to add more grids then just put a <div> inside the first closing </div> after that adjust the width size in a mobile media query. suppose if I need 4 grid then I will put 25% instead 33.333% for responsive. Good Luck.

Upvotes: 0

Danield
Danield

Reputation: 125443

The CSS Grid Layout Module would be the perfect tool to produce these layouts.

From the opening lines of the spec:

Grid Layout is a new layout model for CSS that has powerful abilities to control the sizing and positioning of boxes and their contents. Unlike Flexible Box Layout, which is single-axis–oriented, Grid Layout is optimized for 2-dimensional layouts: those in which alignment of content is desired in both dimensions.

Basically, the relevant code boils down to this:

.container {
  display: grid; /* 1 */
  grid-template-columns: repeat(3, 80px); /* 2 */
  grid-template-rows: repeat(2, 80px); /* 2 */
  margin: 20px;
}

1) Make the container element a grid container

2) Set the grid with 3 columns and 2 rows with a given length (here 80px).

Then for each 'block' variation - just set how much each block spans with the grid-column and grid-row properties.

For example:

horizontal, a 2 x 1 block

becomes:

.horizontal {
  grid-column: span 2;
  grid-row: span 1;
}

Note that by default a grid item will span one column and one row - so the 'square' block doesn't need to be defined.

.container {
  display: grid;
  grid-template-columns: repeat(3, 80px);
  grid-template-rows: repeat(2, 80px);
  margin: 20px;
}
@media (max-width: 1200px) {
  .container.supports-tablet {
    grid-template-columns: repeat(2, 80px);
    grid-template-rows: repeat(3, 80px);
  }
  .container.supports-tablet:after {
    content: "tablet view!!!";
    color: red;
  }
}
.container div {
  border: 1px solid blue;
  margin-left: -1px;
  margin-bottom: -1px;
}
.huge {
  grid-column: span 3;
  grid-row: span 2;
  
}
.big-square {
  grid-column: span 2;
  grid-row: span 2;
}

.horizontal {
  grid-column: span 2;
  grid-row: span 1;
}
.vertical {
  grid-column: span 1;
  grid-row: span 2;
}
<div class="container supports-tablet">
  <div class="horizontal">horizontal</div>
  <div>square</div>
  <div>square</div>
  <div class="horizontal">horizontal</div>
</div>

<div class="container">
  <div class="big-square">big-square</div>
  <div class="vertical">vertical</div>
</div>
<div class="container">
  <div class="vertical">vertical</div>
  <div class="horizontal">horizontal</div>
  <div class="horizontal">horizontal</div>
</div>
<div class="container">
  <div class="horizontal">horizontal</div>
  <div class="vertical">vertical</div>
  <div>square</div>
  <div>square</div>
</div>

<div class="container">
  <div class="huge">huge</div> 
</div>

<div class="container">
  <div class="vertical">vertical</div>
  <div>square</div>
  <div class="vertical">vertical</div>
  <div>square</div>
</div>

Codepen demo


NB:

To make the above layouts responsive (for tablet etc) you would have to decide how the overall grid will change to support that layout.

Notice that in the one example image with tablet view - the grid switches from being 3 X 2 to 2 X 3 - this can easily be done with a media query which redefines the grid with 2 columns and 3 rows.


Browser Support - Caniuse

Currently supported by Chrome (Blink), Safari and Firefox, with partial support from IE and Edge

Upvotes: 3

Aotik
Aotik

Reputation: 348

So Flexbox would indeed be the way forward for such grid systems. I've made a pen for you to see how it would work.

The first row shows equal columns, and the second and third rows are split into 3 columns. (See how the classes one and two are made and you should figure the rest out yourself)

https://codepen.io/Aotik/pen/BZyLBe

This is inspired by my framework, Blossom. You can see more about Blossom's grid system here http://getblossom.io/design/grid

Upvotes: 0

Related Questions