CSS Grid Repeat Grid Layout - css

I am creating a repeating grid system, in which I need to repeat the same structure as the first 7 items. Divs A to G is generating the result I want and all other div are coming on right position column wise but only H and M (The first and sixth item in new row and) not taking the desired height.
H need to equal to height of I and J combine and M need to be equal to K and L's combine height, same as A and F:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, [col] 1fr);
grid-template-rows: repeat(10, [row] auto);
grid-gap: 1em;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
display: flex;
align-items: center;
}
.box:nth-of-type(7n+1) {
grid-column: col / span 2;
}
.box:nth-of-type(7n+3) {
grid-column: col 3 / span 1;
}
.box:nth-of-type(7n+4),
.box:nth-of-type(7n+5) {
grid-column: col 1 / span 1;
}
.box:nth-child(7n+6) {
grid-column: col 2 / span 2;
}
.box:nth-child(7n+7) {
grid-column: col 1 / span 3;
}
.box:first-child {
grid-row: row / span 2;
}
.box:nth-child(2) {
grid-row: row;
}
.box:nth-child(3) {
grid-row: row 2;
}
.box:nth-child(4) {
grid-row: row 3;
}
.box:nth-child(5) {
grid-row: row 4;
}
.box:nth-child(6) {
grid-row: row 3 / span 2;
}
<div class="wrapper">
<div class="box">A</div>
<div class="box">B</div>
<div class="box">C</div>
<div class="box">D</div>
<div class="box">E</div>
<div class="box">F</div>
<div class="box">G</div>
<!-- items with same spans need to be repeted -->
<div class="box">H</div>
<div class="box">I</div>
<div class="box">J</div>
<div class="box">K</div>
<div class="box">L</div>
<div class="box">M</div>
<div class="box">N</div>
</div>

First of all I simplified your code:
using only the nth-child logic for the row-column sizing,
removed grid-template-rows and the naming of the grid lines,
The issue we have now is that the boxes E and F are out of place from the rows:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* grid-template-rows: repeat(10, [row] auto); */
grid-gap: 1em;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
display: flex;
align-items: center;
}
.box:nth-of-type(7n+1) {
grid-column: span 2;
grid-row: span 2;
}
.box:nth-child(7n+6) {
grid-column: span 2;
grid-row: span 2;
}
.box:nth-child(7n+7) {
grid-column: span 3;
}
<div class="wrapper">
<div class="box">A</div>
<div class="box">B</div>
<div class="box">C</div>
<div class="box">D</div>
<div class="box">E</div>
<div class="box">F</div>
<div class="box">G</div>
<!-- items with same spans need to be repeted -->
<div class="box">H</div>
<div class="box">I</div>
<div class="box">J</div>
<div class="box">K</div>
<div class="box">L</div>
<div class="box">M</div>
<div class="box">N</div>
</div>
Now you can shift the F to the last two columns using grid-column: 2 / 4 and then use grid-auto-flow: dense to pull it up - see demo below:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
/*grid-template-rows: repeat(10, [row] auto);*/
grid-auto-flow: dense; /* fills in the spaces */
grid-gap: 1em;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
display: flex;
align-items: center;
}
.box:nth-of-type(7n+1) {
grid-column: span 2;
grid-row: span 2;
}
.box:nth-of-type(7n+5) {
grid-column: 1;
}
.box:nth-child(7n+6) {
grid-column: 2 / 4; /* changed */
grid-row: span 2;
}
.box:nth-child(7n+7) {
grid-column: span 3;
}
<div class="wrapper">
<div class="box">A</div>
<div class="box">B</div>
<div class="box">C</div>
<div class="box">D</div>
<div class="box">E</div>
<div class="box">F</div>
<div class="box">G</div>
<!-- items with same spans need to be repeted -->
<div class="box">H</div>
<div class="box">I</div>
<div class="box">J</div>
<div class="box">K</div>
<div class="box">L</div>
<div class="box">M</div>
<div class="box">N</div>
</div>

Related

How to make my grid cell same size after spanding it over the next cell?

enter image description here
How do I make my grid cell same size after spanning it over the next cell? This is what I have tried so far
.factory {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
height: 600px;
gap: 10px;
margin-top: 100px;
padding: 10px;
}
.factory>div {
background-color: gray;
border: 1px green solid;
}
.image-1 {
width: 100%;
height: auto;
}
.div-3 {
grid-column: 3 / span 5;
}
.div-5 {
grid-column: 1 / span 2;
}
<div class="factory">
<div class="div-1">box1</div>
<div class="div-2">box2</div>
<div class="div-3">box3</div>
<div class="div-5">box5</div>
<div class="div-6">box6</div>
</div>
As you can see box6 is smaller than the rest of the boxes.
Your issue is that on div-3 you try to span 5 columns after it has started at column 3 which will make the browser attempt to add 5 more columns to the grid.
.div-3 {
grid-column: 3 / span 5;
}
You can either remove this section completely because you have already specified in your grid-template-columns: 1fr 1fr 2fr; that the third column should be double the space of the first two.
Another option would be to span 1
.div-3 {
grid-column: 3 / span 1;
}
You can see this clearly by using the inspection tools.
.factory {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
height: 600px;
gap: 10px;
margin-top: 100px;
padding: 10px;
}
.factory>div {
background-color: gray;
border: 1px green solid;
}
.image-1 {
width: 100%;
height: auto;
}
/*.div-3 {
grid-column: 3 / span 5;
}*/
.div-5 {
grid-column: 1 / span 2;
}
<div class="factory">
<div class="div-1">box1</div>
<div class="div-2">box2</div>
<div class="div-3">box3</div>
<div class="div-5">box5</div>
<div class="div-6">box6</div>
</div>

How to overlap elements in css using grid

I want to place box 2 on top of both other boxes by half of them, however, even having explicitly defined grid-template-columns propriety to 1fr it automatically creates another column.
Here is my attempt
index.html
<div class="grid-overlap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
style.scss
.grid-overlap {
max-width: 40rem;
width: 95%;`your text`
margin: 2rem auto;
gap: 1rem;
display: grid;
grid-template-rows: repeat(4, 1fr);
grid-template-columns: 1fr;
.box {
width: 300px;
height: 300px;
margin: 0 auto;
text-align: center;
font-size: 3rem;
}
.box:nth-child(1) {
grid-row: 1 / 3;
background-color: dodgerblue;
}
.box:nth-child(2) {
background-color: red;
grid-row: 2 / 4;
z-index: 100;
}
.box:nth-child(3) {
grid-row: 3 / 5;
background-color: tomato;
}
}
Thanks in advance.
I am giving one example of overlap, try to see how it works and use it in your use case.
.grid-overlap {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.grid-overlap .box:nth-child(1) {
grid-row: 1/3;
grid-column: 1/3;
background-color: dodgerblue;
}
.grid-overlap .box:nth-child(2) {
background-color: rgba(255, 0, 0, 0.6);
grid-row: 2/4;
grid-column: 2/4;
}
<div class="grid-overlap">
<div class="box">1</div>
<div class="box">2</div>
</div>
Looking at the grid we can see that the second square starts in the middle of the first one and that the last one is positioned at one quarter along and three quarters down the first square.
This leads to a grid of width 6 and height 7 square cells.
As it's not possible to have both the grid imensions set at 300px and the width of the grid to be defined in rems (and % units) this snippet drops the 300px settings and sets the overall grid to be the width as defined in the question and the aspect ratio 6/7.
Note that the grid gap is not set (defaults to 0) as no gap was shown in the picture given in the question.
body {
width: 100vw;
height: 100vh;
}
.grid-overlap {
max-width: 40rem;
width: 95%;
aspect-ratio: 6 / 7;
margin: 2rem auto;
gap: 1rem;
gap: 0;
display: grid;
grid-template-rows: repeat(7, 1fr);
grid-template-columns: repeat(6, 1fr);
}
.box {
/*width: 300px;
height: 300px;*/
width: 100%;
height: 100%;
margin: 0 auto;
text-align: center;
font-size: 3rem;
}
.box:nth-child(1) {
grid-column: 1 / span 4;
grid-row: 1 / span 4;
background-color: dodgerblue;
}
.box:nth-child(2) {
background-color: red;
grid-column: 3 / span 4;
grid-row: 3 / span 4;
z-index: 100;
}
.box:nth-child(3) {
grid-column: 2/ span 4;
grid-row: 4 / span 4;
background-color: tomato;
}
<body>
<div class="grid-overlap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
</body>
If the important dimensions were the 300px then use those to set the width of the overall grid.

How could I do this by grid layout? [duplicate]

This question already has answers here:
Make a div span two rows in a grid
(2 answers)
Closed 12 months ago.
There are three children dive in a parent container (div):
.grid-container {
display: grid;
.grid-container > div {
height:auto;
width: auto;
}
<div class="grid-container">
<div class="item1">Header</div>
<div class="item2">Menu</div>
<div class="item3">Main</div>
</div>
Please find the following code. This will help you in making the required structure.
:root {
--wrapper: 100vw;
--gutter: 10px;
--noOfColumns: 4;
--noOfGutters: calc(var(--noOfColumns) - 1);
--ratioA: 16;
--ratioB: 9;
--factor: calc(var(--ratioB) / var(--ratioA));
--rh: calc(( (var(--wrapper) - (var(--noOfGutters) * var(--gutter)))
/ var(--noOfColumns)) * var(--factor));
}
.grid {
max-width: var(--wrapper);
display: grid;
grid-template-columns: repeat(var(--noOfColumns), 1fr);
grid-auto-flow: dense;
grid-auto-rows: minmax(var(--rh), auto);
}
.grid__item {
background-color: steelBlue;
padding: 20px;
}
.grid__item--lg {
grid-column: span 2;
grid-row: span 2;
background-color: coral;
}
.grid__item--right {
grid-column: 3/span 2;
}
.grid__item--db {
grid-column: span 2;
background-color: lightBlue;
}
.steelBlue {
background-color: steelBlue;
}
<div class="grid">
<div class="grid__item grid__item--lg grid__item--right">1</div>
<div class="grid__item grid__item--db">2</div>
<div class="grid__item grid__item--db steelBlue">3</div>
</div>

Define a new row in css grid

Is there a way in css grid of saying 'after the second column, start another row'?
It seems straightforward enough defining how much height and width you want a grid cell to take up, but defining where you want cells to appear requires a lot of syntax - I feel like I'm missing something.
Like this layout:
main {
display: grid;
grid-gap: 10px;
max-width: 700px;
margin: 0 auto;
}
.block {
height: 200px;
}
.block--one {
background: coral;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
.block--two {
background: cornflowerblue;
grid-column-start: 2;
grid-column-end: 6;
grid-row-start: 1;
grid-row-end: 2;
}
.block--three {
background: burlywood;
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 2;
grid-row-end: 4;
}
.block--four {
background: lightseagreen;
grid-column-start: 4;
grid-column-end: 6;
grid-row-start: 2;
grid-row-end: 4;
}
<main>
<div class="block block--one"></div>
<div class="block block--two"></div>
<div class="block block--three"></div>
<div class="block block--four"></div>
</main>
Shouldn't it be achievable with something like this?
main {
display: grid;
grid-gap: 10px;
max-width: 700px;
margin: 0 auto;
grid-template-rows: 2fr 2fr;
grid-template-columns: 2fr 4fr 5fr 1fr;
}
.block {
height: 200px;
}
.block--one {
background: coral;
}
.block--two {
background: cornflowerblue;
}
.block--three {
background: burlywood;
}
.block--four {
background: lightseagreen;
}
<main>
<div class="block block--one"></div>
<div class="block block--two"></div>
<div class="block block--three"></div>
<div class="block block--four"></div>
</main>
You can simplify the code by using a shorthand property.
In your first example, you're using all long-hand properties. For example, you have this:
.block--two {
background: cornflowerblue;
grid-column-start: 2;
grid-column-end: 6;
grid-row-start: 1;
grid-row-end: 2;
}
Like with other CSS features, such as borders, margins and padding, there's a shorthand property to consolidate multiple lines of code.
In this case, there's the grid-area property, which shortens the code above to:
grid-area { 1 / 2 / 2 / 6 }
The values flow in this order:
grid-row-start
grid-column-start
grid-row-end
grid-column-end
main {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-auto-rows: 200px;
grid-gap: 10px;
max-width: 700px;
margin: 0 auto;
}
.block--one {
background: coral;
/* no need to specify placement here; default aligns to row 1, column 1 */
}
.block--two {
background: cornflowerblue;
grid-area: 1 / 2 / 2 / -1;
}
.block--three {
background: burlywood;
grid-area: 2 / 1 / 3 / 4;
}
.block--four {
background: lightseagreen;
grid-area: 2 / 4 / 3 / -1;
}
<main>
<div class="block block--one"></div>
<div class="block block--two"></div>
<div class="block block--three"></div>
<div class="block block--four"></div>
</main>
More details: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-area
A good way of defining the rows and columns can be by using grid-template-areas and grid-area which can define how many rows and columns a grid area should take up. This is especially helpful when changing the layout with #media tags, you only have to change the one attribute.
From your row and column definitions I can add each block to take up the space that I want it to.
See example for 2 rows by 4 columns for the 4 blocks.
main {
display: grid;
grid-gap: 10px;
max-width: 700px;
margin: 0 auto;
grid-template-rows: 2fr 2fr;
grid-template-columns: 2fr 4fr 5fr 1fr;
grid-template-areas:
"block1 block2 block2 block2"
"block3 block3 block4 block4";
}
.block {
height: 200px;
}
.block--one {
grid-area: block1;
background: coral;
}
.block--two {
grid-area: block2;
background: cornflowerblue;
}
.block--three {
grid-area: block3;
background: burlywood;
}
.block--four {
grid-area: block4;
background: lightseagreen;
}
<main>
<div class="block block--one"></div>
<div class="block block--two"></div>
<div class="block block--three"></div>
<div class="block block--four"></div>
</main>
main {
display: grid;
grid-gap: 10px;
max-width: 700px;
margin: 0 auto;
grid-auto-flow: row;
}
.block {
height: 200px;
}
.block--one {
background: coral;
grid-column: 1;
}
.block--two {
background: cornflowerblue;
grid-column: 2/ 6;
}
.block--three {
background: burlywood;
grid-column: 1 / 4;
}
.block--four {
background: lightseagreen;
grid-column: 4 / 6;
}
<main>
<div class="block block--one"></div>
<div class="block block--two"></div>
<div class="block block--three"></div>
<div class="block block--four"></div>
</main>
grid-auto-flow: row; Will start on new row if the element is not able to fit on the current row

CSS Grid row/column gap on specific elements? [duplicate]

This question already has answers here:
Setting different lengths for grid gaps in CSS Grid
(2 answers)
Can grid-row-gap / grip-column-gap be overridden for a single gutter?
(1 answer)
Closed 4 years ago.
I have created the grid below using CSS Grid and I am wondering if it's possible to have a gap only between specific elements within the grid, rather than applying a universal gap to all grid elements. Here's what I have right now:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
}
.box {
background-color:#444;
color:#fff;
padding:20px;
font-size:150%;
}
.a {
grid-column: col / span 2;
grid-row: row 1 / 3;
}
.b {
grid-column: col 3 / span 1;
grid-row: row ;
}
.c {
grid-column: col 3 / span 1;
grid-row: row 2 ;
}
.d {
grid-column: col / span 1;
grid-row: row 3;
}
.e {
grid-column: col 2 / span 1;
grid-row: row 3;
}
.f {
grid-column: col 3 / span 1;
grid-row: row 3;
}
.g {
grid-column: col / span 1;
grid-row: row 4;
}
.h {
grid-column: col 2 / span 1;
grid-row: row 4;
}
.i {
grid-column: col 3 / span 1;
grid-row: row 4;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
</div>
I would like to remove the gap between the top 2 rows on the right side and between each cell on the rows below that. I would like to keep the cells broken up as they are now because the layout will be different on desktop. Here's a graphical representation of what I'm going for:
It's impossible to change the gap on specific elements.
However, you can reference specific grid item with grid-item:nth-child(n) and set negative margins to it.
For example, with a class of picture-1 it may look like this in the CSS file:
.picture-1:nth-child(3) {
margin-bottom: -50px;
}
I have a work around to get your desired result. I just moved all the three rows in a separate grid section. I am not sure if it helps or not but here it is:
body {
margin: 40px;
}
.wrapper1 {
display: grid;
grid-gap: 10px;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
margin-bottom: 10px;
}
.wrapper2 {
display: grid;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
margin-bottom: 10px;
}
.wrapper3 {
display: grid;
grid-template-columns: [col] 100px [col] 100px [col] 100px;
grid-template-rows: [row] auto [row] auto [row] ;
background-color: #fff;
color: #444;
margin-bottom: 10px;
}
.box {
background-color:#444;
color:#fff;
padding:20px;
font-size:150%;
}
.a {
grid-column: col 1 / span 2;
grid-row: row 1 / 3;
}
.b {
grid-column: col 3 / span 1;
grid-row: row ;
}
.c {
grid-column: col 3 / span 1;
grid-row: row 2 ;
}
.d {
grid-column: col 1 / span 1;
grid-row: row 3;
width: 80%;
}
.e {
grid-column: col 2 / span 1;
grid-row: row 3;
width: 80%;
}
.f {
grid-column: col 3 / span 1;
grid-row: row 3;
width: 80%;
}
.g {
grid-column: col 1 / span 1;
grid-row: row 4;
width: 80%;
}
.h {
grid-column: col 2 / span 1;
grid-row: row 4;
width: 80%;
}
.i {
grid-column: col 3 / span 1;
grid-row: row 4;
width: 80%;
}
<div class="wrapper1">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
</div>
<div class="wrapper2">
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
</div>
<div class="wrapper3">
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
</div>

Resources