I have the following markup:
<div class="wrapper">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
</div>
I want the layout to accomplish a layout in which the first two child divs are arranged next to each other as two columns while the 3rd sits on a row of its occupying full width.
The first child column will be a fixed width (30px), while the second should occupy the remaining space.
I have tried this, but it doesn't accomplish what I need:
.wrapper {
display: grid;
grid-template-columns: 20px auto 100%;
border:1px solid white;
}
Maybe something like this
.wrapper {
display: grid;
grid-template-columns: 30px 1fr;
grid-gap: 1rem;
}
.child {
padding: 1rem;
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.three {
grid-column: 1 / -1; /* 👈 It makes this element take all available columns (the whole row)
}
<div class="wrapper">
<div class="child one">One</div>
<div class="child two">Two</div>
<div class="child three">Three</div>
</div>
That's the method I prefer.
First, you fraction in four with grid-template: 1fr 1fr / 1fr 1fr. This is column sizes / row sizes
After that, imagine you have two squares together in the first row (first 1fr 1fr)
Now imagine the three lines (The first line of the left square draws one vertical line, the two squares touching draw a second line, and the 2nd square draws the third one).
|â–¢|â–¢|
So, you say to #red, start in line 1 and finish in line 2 grid-column: 1 / 2, to the #green, start in the two and finish in the 3, and so on.
The result looks like this:
.grid
{
display: grid;
grid-auto-flow: row dense;
/* This is column column / row row */
grid-template: 1fr 1fr / 1fr 1fr;
height: 300px;
}
#red {
background-color: red;
grid-column: 1 / 2;
grid-row: 1 / 2;
}
#green {
background-color: green;
grid-column: 2 / 3;
grid-row: 1 / 2;
}
#blue {
background-color: blue;
grid-column: 1 / 3;
grid-row: 2 / 3;
}
/* To make the first row 30px you can use this instead */
.grid
{
grid-template: 1fr 1fr / 30px 1fr;
}
<div class="grid">
<div id="blue">Blue</div>
<div id="red">Red</div>
<div id="green">Green</div>
</div>
Related
I want the vertical space for the 4 and 5 blocks to be shared exactly 50%.
I currently have the code configured like:
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas:
"side1 main1"
"side2 main1"
"side3 main2";
Is it possible to somehow have the main1/main2 to share the space each as 50%?
If you think of it as a grid with 6 rows then side elements can take 2 rows each height and main elements can take 3 rows each height.
* {
margin: 0;
padding: 0;
}
.grid {
display: grid;
grid-template-areas: "side1 main1" "side1 main1" "side2 main1" "side2 main2" "side3 main2" "side3 main2";
width: 50vmin;
/* added just for demo */
aspect-ratio: 2 / 3;
gap: 1vmin;
}
.grid>div {
background: red;
font-size: 40px;
}
.grid>div:nth-child(1) {
grid-area: side1;
}
.grid :nth-child(2) {
grid-area: side2;
}
.grid :nth-child(3) {
grid-area: side3;
}
.grid :nth-child(4) {
grid-area: main1;
}
.grid :nth-child(5) {
grid-area: main2;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
And as you want the side elements to be squares you can set the overall aspect ratio 2 / 3 and drop the 1fr row and column settings.
I'm trying to achieve the following layout:
As you can see, the cards in the middle column occupy multiple grids, in order to give it that effect.
What I have:
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
". . ."
". . ."
". . .";
}
.grid-item {
border: 1px solid black;
}
.grid-item:nth-child(3) {
grid-column: 2;
grid-row: 2;
}
.grid-item:nth-child(4) {
grid-column: 2;
grid-row: 3;
}
.grid-item:nth-child(5) {
grid-column: 2;
grid-row: 4;
}
.grid-item:nth-child(6) {
grid-column: 3;
grid-row: 1;
}
<div class="grid">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
</div>
However, my approach definitely isn't the most sustainable, nor are my cards rendering in the correct order (cards go from 1, 7, 2, 3 etc ..).
I haven't seen an approach where using CSS grid, a layout like the image has been achieved, so wondering if CSS grid is the best solution here?
To achieve this you mostly have to change the behavior of your grid container.
Adding grid-auto-flow: column; fixes the issue of the elements moving in rows.
Doubling the number of rows means that you can work "by halves" when positioning our elements.
On the grid elements, adding grid-row: span 2 sets them to occupy a whole area in your design
Then all you have to do is tell the first one and second to last one to start on the second row.
If you were going to iterate this over more than 3 columns, it would by every 7th element minus the first one ( .grid-item:nth-child(7n-1)) instead of nth-to-last. In that case, you'd also have to define your grid differently, similar to below.
grid-template-rows: repeat( 6, auto );
grid-auto-columns: 1fr;
You can also remove the grid-area definition.
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: repeat(6, auto);
grid-auto-flow: column;
gap: 0px 0px;
}
.grid-item {
border: 1px solid black;
grid-row: span 2;
}
.grid-item:nth-child(1), .grid-item:nth-last-child(2) {
grid-row: 2 / span 2;
}
<div class="grid">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
</div>
Both divs display correctly alone, but if both img-1 and img-2 divs are both in the container, the second div disappears.
HTML:
<div class="body-background">
<div class="background-img-1"></div>
<div class="background-img-2"></div>
</div>
CSS
.body-background {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: 1fr;
width: 100%;
height: 100%;
}
.background-img-1 {
background: red;
grid-column: 1 / 3;
}
.background-img-2 {
background: blue;
grid-column: 2 / 4;
}
Shouldn't the boxes overlap normally?
Give both background divs a grid-row: 1 property (which becomes grid-row: 1 / 2). I don't think the browser likes having to give it implicitly to two overlapping cells.
.body-background {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: 1fr;
width: 100vw;
height: 100vh;
}
.background-img-1 {
background-color: red;
grid-column: 1 / 3;
grid-row: 1;
}
.background-img-2 {
background-color: blue;
grid-column: 2 / 4;
grid-row: 1;
}
<div class="body-background">
<div class="background-img-1"></div>
<div class="background-img-2"></div>
</div>
This question already has answers here:
Why does Chrome 80 cause this grid-template-rows: auto problem
(2 answers)
Closed 3 years ago.
I have a css grid with 2 columns and 3 rows. The third row content is not always present because of an angular ngif clause. An image is present in the first column that spans the 3 rows. With all that said, I get 2 different results in Chrome (80.0.3987.87, which is the latest stable as I post) and Firefox.
Is there a way to control the rows so that it behaves like in Firefox, i.e. the third row grows when the image height is bigger than the 2 first row heights combined.
.grid {
width:400px;
display:grid;
grid-template-columns: 40px 1fr;
grid-template-rows: minmax(0, auto) minmax(0, auto) minmax(0, 1fr);
}
.image {
width:40px;
height:100px;
grid-column:1;
grid-row:1 / span 3;
background-color: #f00;
}
.text1 {
grid-column:2;
grid-row:1;
}
.text2 {
grid-column:2;
grid-row:2;
}
<div class="grid">
<div class="image"></div>
<div class="text1">Text 1</div>
<div class="text2">Text 2</div>
</div>
Here is the codepen that you can check in both Chrome and Firefox.
And here is an image to show the difference:
As you can see, Chrome increases equally the height of rows 1 and 2 (row 3 stays 0). Firefox increases only the height of row2, i.e. the last visible row with content.
Note that I tried setting grid-template-rows as "minmax(0, auto) minmax(0, auto) 1fr", but then row 3 will have a weird height that makes the grid height bigger than its content.
Update: Ah! Was able to try it on a previous Chrome version (79) and I get the same result as in Firefox this time. So it seems 80 changed it. Can some people here confirm?
You can update your code like below. It seems to work the same in Chrome 80 and firefox. Worth to note that 1fr is equal to minmax(auto, 1fr) which is indeed different from minmax(0,1fr) but still don't know exactly what makes both behave differently.
.grid {
width:400px;
display:grid;
grid-template-columns: 40px 1fr;
grid-template-rows: auto auto 1fr;
}
.image {
width:40px;
height:100px;
grid-column:1;
grid-row:1 / span 3;
background-color: #f00;
}
.text1 {
grid-column:2;
grid-row:1;
}
.text2 {
grid-column:2;
grid-row:2;
}
<div class="grid">
<div class="image"></div>
<div class="text1">Text 1</div>
<div class="text2">Text 2</div>
</div>
The way you have mentioned the grid-template-rows for the container is invalid in chrome. I guess that's the issue
Try this css and see;
<style>
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.image {
height: 100px;
grid-row: 1/4;
background-color: #f00;
}
.text1 {
grid-column: 2;
grid-row: 1;
}
.text2 {
grid-column: 2;
grid-row: 2;
}
</style>
Hope that helps!!
This question already has answers here:
Make a grid item span to the last row / column in implicit grid
(5 answers)
Closed 5 years ago.
I have a CSS grid such as this:
.grid-wrapper
display: grid
margin: 0 auto
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr))
grid-auto-rows: minmax(100px, auto)
grid-gap: 10px
And I want to position a main element in the beginning:
.main-item
grid-column-end: span 2
grid-row-end: span 2
A series of intermediate elements following that one, and in the last possible position of the grid -not following the other elements, but literally on the right bottom corner of the grid-.
Right now I can place it on the last column with
.last item
grid-column-end: -1
But I can't find a way of placing it on the last row -given that the number of rows is not defined-.
Any ideas?
https://codepen.io/rtyx/pen/XVQMJQ
.wrapper {
border: 2px solid #f76707;
background-color: #fff4e6;
}
.wrapper>div {
border: 2px solid #ffa94d;
background-color: #ffd8a8;
color: #d9480f;
}
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
grid-auto-rows: minmax(100px, auto);
grid-gap: 10px;
width: 1000px;
}
.main-item {
grid-column-end: span 2;
grid-row-end: span 2;
}
.last-item {
grid-column-end: -1;
grid-row-end: -1;
}
<div class="wrapper">
<div class="main-item">Main item</div>
<div class="item1">Item 2</div>
<div class="item2">Item 3</div>
<div class="item3">Item 4</div>
<div class="last-item">last-item</div>
</div>
Based on your codepen. In class .last-item set grid-row-end:3
For same layout use this...
.last-item {
grid-column-end: -1;
grid-row-end: 4;
}