Layout combining two CSS Grids - html

I'm working on a assignment in which I want to make two groups of css-grids mixed with each other like this:
I'm using the following code
.group1 .item1 {
grid-column: 1 / 4;
}
.group1 .item2 {
grid-column: 1;
}
.group1 .item3 {
grid-column: 2 / 4;
}
.group2 .item4 {
grid-column: 2 / 3;
}
.group2 .item5 {
grid-column: 3 / 4;
}
.group2 .item6 {
grid-column: 2 / 4;
}
.container {
display: grid;
grid-gap: 5px;
max-width: 1200px;
margin: 0 auto 100px auto;
border: 8px dashed #999;
}
<section class="part5 container">
<div class="container group1">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item item3">Item 3</div>
</div>
<div class="container group2">
<div class="item item4">Item 4</div>
<div class="item item5">Item 5</div>
<div class="item item6">Item 6</div>
</div>
</section>
I'm expecting the output to be like the [image] attached WITHOUT CHANGING HTML but I'm unable to get that output, please help me, I shall be very thankful to you for this act of kindness.

You could use display:contents to avoid the subcontainers to come in the way and use display grid and grid-area (grid-row/grid-column) to dispatch your elements.
But this is not yet working everywhere !
Demo of the idea
.part5 {
display: grid;
grid-template-colums: repeat(6, 1fr);
min-height: 100vh
}
.container.group1,
.container.group2 {
display: contents;
}
.item1 {
grid-column: 1/ span 6;
grid-row: 1;
border: solid;
color: tomato;
}
.item2 {
grid-row: 2 /span 3;
grid-column: 1 /span 2;
border: solid;
color: turquoise;
}
.item3 {
grid-row: 2;
grid-column: 3/span 4;
border: solid;
color: green;
}
.item4 {
grid-row: 3;
grid-column: 3 /span 2;
border: solid;
}
.item5 {
grid-row: 3;
grid-column: 5 / span 2;
border: solid;
color: brown;
}
.item6 {
grid-row: 4;
grid-column: 3 / span 4;
border: solid;
color: purple;
}
/* demo*/
* {
margin: 0;
}
[class^=item] {
display: flex;
align-items: center;
justify-content: center;
font-size: calc(2vh + 2vw)
}
<section class="part5 container">
<div class="container group1">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item item3">Item 3</div>
</div>
<div class="container group2">
<div class="item item4">Item 4</div>
<div class="item item5">Item 5</div>
<div class="item item6">Item 6</div>
</div>
</section>
https://css-tricks.com/get-ready-for-display-contents/
—a magical new display value that essentially makes the container disappear, making the child elements children of the element the next level up in the DOM.
from your code, it could be a short code update :
/*update */
.container {
display: contents
}
.part5 {
/* end update */
display: grid;
grid-gap: 5px;
max-width: 1200px;
margin: 0 auto 100px auto;
border: 8px dashed #999;
}
.group1 .item1 {
grid-column: 1 / 4;
}
.group1 .item2 {
grid-column: 1;
grid-row: 2/5;
}
.group1 .item3 {
grid-column: 2 / 4;
}
.group2 .item4 {
grid-column: 2 / 3;
}
.group2 .item5 {
grid-column: 3 / 4;
}
.group2 .item6 {
grid-column: 2 / 4;
}
.container {
display: contents
}
.part5 {
display: grid;
grid-gap: 5px;
max-width: 1200px;
margin: 0 auto 100px auto;
border: 8px dashed #999;
}
/*demo*/
div {
box-shadow: 0 0 0 2px lightgray;
<section class="part5 container">
<div class="container group1">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item item3">Item 3</div>
</div>
<div class="container group2">
<div class="item item4">Item 4</div>
<div class="item item5">Item 5</div>
<div class="item item6">Item 6</div>
</div>
</section>
The rough way is to set both groups on the same grid overlapping them :
.container {
display: grid;
width: 100%;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 1fr);
}
.group1 {
grid-row: 1 / span 4;
grid-column: 1 / span 6;
}
.group2 {
grid-template-rows: repeat(2, 1fr);
grid-column: 3 /span 4;
grid-row: 3 /span 3;
}
.item1 {
grid-column: 1 / span 6;
color: tomato;
}
.item2 {
grid-column: 1 / span 2;
grid-row: 2 / span 4;
color: turquoise;
}
.item3 {
grid-column: 3 / span 4;
color: green;
}
.item4 {
grid-column: 1 /span 3;
grid-row: 1;
}
.item5 {
grid-column: 4/span 3;
color: brown;
}
.item6 {
grid-column: 1/ span 6;
color: purple;
}
/* demo*/
[class^=item] {
border: solid;
display: flex;
align-items: center;
justify-content: center;
font-size: calc(2vh + 2vw);
background: lightgray;
min-height:20vh
}
<section class="part5 container">
<div class="container group1">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item item3">Item 3</div>
</div>
<div class="container group2">
<div class="item item4">Item 4</div>
<div class="item item5">Item 5</div>
<div class="item item6">Item 6</div>
</div>
</section

.container{
display: grid;
grid-template-columns: repeat(6,auto);
grid-gap: 5px;
grid-template-areas:
'item1 item1 item1 item1 item1 item1'
'item2 item2 item3 item3 item3 item3'
'item2 item2 item3 item3 item3 item3'
'item2 item2 item4 item4 item5 item5'
'item2 item2 item4 item4 item5 item5'
'item2 item2 item6 item6 item6 item6'
;
}
.box{
border: 2px solid black;
background-color: lightblue;
padding: 10px;
border-radius: 12px;
text-align: center;
}
#item1{
grid-area: item1;
}
#item2{
grid-area: item2;
}
#item3{
grid-area: item3;
}
#item4{
grid-area: item4;
}
#item5{
grid-area: item5;
}
#item6{
grid-area: item6;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="box" id="item1">item-1</div>
<div class="box" id="item2">item-2</div>
<div class="box" id="item3">item-3</div>
<div class="box" id="item4">item-4</div>
<div class="box" id="item5">item-5</div>
<div class="box" id="item6">item-6</div>
</div>
</body>
</html>

display: subgrid
A clean and efficient way to solve this problem would be to use display: subgrid, which is a CSS Grid feature designed specifically for these sorts of layouts. Subgrids allow nested grid containers to recognize the grid lines of the primary grid container.
Unfortunately, this feature is not available yet. More details here:
Positioning content of grid items in primary container (subgrid feature)
grid-template-areas
Another clean and efficient way to solve the problem would be to make the primary container (.part5.container) a grid container, then arrange both child containers in the shape that you need using grid-template-areas.
Unfortunately, this feature is also not available yet. More details here:
grid-template-areas with ASCII art is not working
A possible solution
So here's a solution using CSS Grids and (to compensate for the missing features listed above) a little bit of absolute positioning. No changes to the HTML.
.part5.container {
display: grid;
border: 8px dashed #999;
height: 100vh;
grid-template-rows: auto auto;
grid-template-columns: 35% 1fr;
grid-template-areas: " group1 group1 "
" . group2 ";
}
.container.group1 {
grid-area: group1;
display: grid;
grid-template-rows: 50px 1fr;
grid-template-columns: 35% 1fr;
grid-gap: 5px;
position: relative;
}
.item1 {
grid-column: 1 / -1;
}
.item2 {
position: absolute;
top: 55px; /* top row height plus gap */
width: 35%; /* first column width */
height: calc(100vh - 71px); /* minus height of top row (50px) plus borders (16px)) */
}
.item3 {
grid-column: 2;
}
.container.group2 {
grid-area: group2;
display: grid;
grid-template-rows: 1fr 50px;
grid-template-columns: 1fr 1fr;
grid-gap: 5px;
margin: 5px 0 0 5px;
}
.item6 {
grid-column: 1 / -1;
}
.item {
background-color: lightgreen;
display: flex;
align-items: center;
justify-content: center;
}
body {
margin: 0;
}
* {
box-sizing: border-box;
}
<section class="part5 container">
<div class="container group1">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item item3">Item 3</div>
</div>
<div class="container group2">
<div class="item item4">Item 4</div>
<div class="item item5">Item 5</div>
<div class="item item6">Item 6</div>
</div>
</section>

Related

How to place grid items at the end of the container

I have a grid container and I want my items to be placed at bottom.
I have this Actual
I want something like this
Expected
.container {
display: grid;
grid-template-columns: repeat(14, 1fr);
grid-template-rows: repeat(6, 1fr);
grid-gap: 8px;
width: 200px;
background: blue;
}
.item {
background-color: red;
color: white;
}
.item-1 {
grid-column: span 5;
grid-row: span 6;
}
.item-2 {
grid-column: span 4;
grid-row: span 5;
}
.item-3 {
grid-column: span 3;
grid-row: span 4;
}
<div class="container">
<div class="item item-1">Item 1</div>
<div class="item item-2">Item 2</div>
<div class="item item-3">Item 3</div>
</div>
PS: I've already tried place-items: end; and align-items: end;
You can use the two value start / end syntax for grid-column and grid-row to establish the start and end of your items.
For example grid-row: 2 / span 3; would start at the 2nd grid line and span an additional 3 more down to the 5th grid line.
.container {
display: grid;
grid-template-columns: repeat(14, 1fr);
grid-template-rows: repeat(6, 1fr);
grid-gap: 8px;
width: 200px;
background: blue;
}
.item {
background-color: red;
color: white;
}
.item-1 {
grid-column: span 5;
grid-row: span 6;
}
.item-2 {
grid-column: 6 / span 4;
grid-row: 2 / span 5;
}
.item-3 {
grid-column: 10 / span 3;
grid-row: 3 / span 4;
}
<div class="container">
<div class="item item-1">Item 1</div>
<div class="item item-2">Item 2</div>
<div class="item item-3">Item 3</div>
</div>
Note: In response to the edit about align-items, this only works when the layout isn't being defined by spanning multiple rows.

How to make the cell of a grid as long as as entire grid

Code:
.wrapper {
display: grid;
position: relative;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 25vh;
width: 100%;
}
.prova {
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
width: 100%;
background-color: none;
overflow: auto;
position: fixed;
}
<div class="wrapper">
<div class="prova">1</div>
<div class="prova">2</div>
<div class="prova">3</div>
<div class="prova">4</div>
<div class="prova">5</div>
<div class="prova">6</div>
<div class="prova">7</div>
<div class="prova">8</div>
<div class="prova">9</div>
<div class="prova">10</div>
<div class="prova">11</div>
<div class="prova">12</div>
</div>
As you can see here, in the last row of the grid there are 4 cells but I'd like them to become just one long cell, or to add another cell below them as bis as I just said!
you can use grid-column: span 4; on your last child to make it span all columns:
.wrapper {
display: grid;
position: relative;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 25vh;
width: 100%;
}
.prova {
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
.wrapper div:last-child {
grid-column: span 4;
}
<div class="wrapper">
<div class="prova">1</div>
<div class="prova">2</div>
<div class="prova">3</div>
<div class="prova">4</div>
<div class="prova">5</div>
<div class="prova">6</div>
<div class="prova">7</div>
<div class="prova">8</div>
<div class="prova">9</div>
<div class="prova">10</div>
<div class="prova">11</div>
<div class="prova">12</div>
<div class="prova">13</div>
</div>

Grid format HTML CSS

I'm trying to create a section on my html where I can show some grids. Can you help me with this please? I'm attaching a pic where I'm showing what I want to do. Yellow color is how it is right now, and blue is the final result.
.wrapper {
display: grid;
grid-gap: 20px;
justify-content: center;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: 1 / 3;
grid-row: 1;
}
.b {
grid-column: 3;
grid-row: 1 / 3;
}
.c {
grid-column: 1;
grid-row: 2;
}
.d {
grid-column: 2;
grid-row: 2;
}
<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>

How do I move three of my grid cells to the top of the grid?

I am learning to work with "grid" and have hit a roadblock. I want to move the last three cells to the top of the grid so that I can put headers before the content but don't know how to do that. Any help is appreciated.
HTML:
<div class="gridWrapper">
<div class="gridBox heading1">Heading</div>
<div class="gridBox heading2">Heading</div>
<div class="gridBox heading3">Heading</div>
<div class="gridBox a">A</div>
<div class="gridBox b">B</div>
<div class="gridBox c">C</div>
<div class="gridBox d">D</div>
<div class="gridBox e">E</div>
<div class="gridBox f">F</div>
</div>
CSS:
.gridWrapper {
color: white;
display: grid;
grid-gap: 15px;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-rows: 500px 500px 100px;
background-color: transparent;
padding-left: 50px;
padding-right: 50px;
padding-top: 100px;
justify-content: center;
}
.gridBox {
background-color: white;
color: black;
margin: 0px;
border-radius: 5px;
padding: 20px;
font-size: 100%;
}
.a {
grid-area: 1 / 2 / 2 / 3;
}
.b {
grid-area: 2 / 2 / 3 / 3;
}
.c {
grid-area: 2 / 3 / 3 / 4;
}
.d {
grid-area: 1 / 1 / 1 / 2;
}
.e {
grid-area: 2 / 1 / 3 / 2;
}
.f {
grid-area: 1 / 3 / 2 / 4;
}

Is this possible with CSS Grid?

I want the "Next" button of this section to go full width when the other div has been taken away. I need the middle div to stay as part of the same container as I will be putting this in the middle in a media query for tablet / desktop.
<div class="container">
<div class="item item--1">Page 1 of 20</div>
<div class="item item--2">Previous</div>
<div class="item item--3">Next</div>
</div>
<div class="container" style="margin-top: 40px;">
<div class="item item--1">Middle</div>
<div class="item item--2">Next</div>
</div>
.container {
display: grid;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.item {
background: yellow;
border: 1px solid grey;
text-align: center;
}
.item--1 {
text-align: center;
grid-row: 1;
grid-column: 1 / span 2;
}
.item--2 {
grid-row: 2;
grid-column: 1fr;
}
.item--3 {
grid-row: 2;
grid-column: 1fr;
}
https://codepen.io/chrismorrison/pen/xjjwxQ?editors=1100
You can do this by retaining the class on the "Next" div (there seems little reason to change it) and the targeting it differently when it follows the "Previous" div using the adjacent selector. +
.container {
display: grid;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.item {
background: yellow;
border: 1px solid grey;
text-align: center;
}
.item--1 {
text-align: center;
grid-row: 1;
grid-column: 1 / span 2;
}
.item--2 {
grid-row: 2;
grid-column: 1;
}
.item--3 {
grid-row: 2;
grid-column: 1 / span 2;
}
.item--2 + .item--3 {
grid-column: 2 / span 1;
}
<div class="container">
<div class="item item--1">Page 2 of 20</div>
<div class="item item--2">Previous</div>
<div class="item item--3">Next</div>
</div>
<div class="container" style="margin-top: 40px;">
<div class="item item--1">Page 1 of 20</div>
<div class="item item--3">Next</div>
</div>
Frankly, a better solution would be flexbox like so. This works with both Previous and Next buttons out of the box.
.container {
display: flex;
flex-wrap: wrap;
margin-top: 20px
}
.item {
background: yellow;
border: 1px solid grey;
text-align: center;
}
.item--1 {
text-align: center;
flex: 1 0 100%;
}
.item--2,
.item--3 {
flex: 1;
}
<div class="container">
<div class="item item--1">Page 1 of 20</div>
<div class="item item--3">Next</div>
</div>
<div class="container">
<div class="item item--1">Page 2 of 20</div>
<div class="item item--2">Previous</div>
<div class="item item--3">Next</div>
</div>
<div class="container">
<div class="item item--1">Page 20 of 20</div>
<div class="item item--2">Previous</div>
</div>