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.
Related
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>
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>
As you can see, when I change the grid-gap, only the width of 1, 3 and 4 are updated.
The width of 2 is not updated at all.
I want it to update the width of 1 and the width of 2, 3 and 4.
The demo of MDN shows that it's possible to resize all items accordingly.
https://developer.mozilla.org/en-US/docs/Web/CSS/gap
Here's my code
.container {
display: grid;
width: 500px;
height: 100px;
gap: 20px; /* Try to change this, width of 2 isn't updated */
grid-template-columns: 2fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
transition: gap 0.3s linear;
}
.child {
background-color: gray;
text-align: center;
font-size: 50px;
color: white;
line-height: 70px
}
.child-1 {
grid-row-start: 1;
grid-row-end: 3;
}
.child-2 {
grid-column-start: 2;
grid-column-end: 4;
}
<div class="container">
<div class="child child-1">1</div>
<div class="child child-2">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
It's because the width of (2) include a gap so its width is 2fr + gap. changing the gap will also change the fr and the width will remain constant.
in this case 1fr = (500px - 2*gap)/4 so 2fr + gap = (500px - 2*gap)/2 + gap = 250px
Change the code and use a different structure where the width of (2) isn't constant:
.container {
display: grid;
width: 500px;
height: 100px;
grid-gap: 20px;
grid-template-columns: 4fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
animation: change 1s linear infinite alternate;
}
.child {
background-color: gray;
text-align: center;
font-size: 50px;
color: white;
line-height: 70px;
grid-column:span 2;
}
.child-1 {
grid-row-start: 1;
grid-row-end: 3;
grid-column:span 1;
}
.child-2 {
grid-column-start: 2;
grid-column-end: 6;
}
#keyframes change {
to {
grid-gap:1px;
}
}
<div class="container">
<div class="child child-1">1</div>
<div class="child child-2">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
In this case 1fr = (500px - 4*gap )/8 and the width of (2) is 4fr + 3*gap = (500px - 4*gap)/2 + 3*gap = 250px + gap But now the (3) and (4) will be constant because 2fr + gap=(500px - 4*gap)/4 + gap = 125px
Another structure where all will update:
.container {
display: grid;
width: 500px;
height: 100px;
grid-gap: 30px;
grid-template-columns: 6fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
animation: change 1s linear infinite alternate;
}
.child {
background-color: gray;
text-align: center;
font-size: 50px;
color: white;
line-height: 70px;
grid-column:span 3;
}
.child-1 {
grid-row-start: 1;
grid-row-end: 3;
grid-column:span 1;
}
.child-2 {
grid-column-start: 2;
grid-column-end: 8;
}
#keyframes change {
to {
grid-gap:1px;
}
}
<div class="container">
<div class="child child-1">1</div>
<div class="child child-2">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
The (2) will have a width equal to 250px + 2*gap. (3) and (4) will have a width equal to 125px + 0.5*gap
Another configuration:
.container {
display: grid;
width: 500px;
height: 100px;
grid-gap: 30px;
grid-template-columns: 2fr 4fr 2fr 1fr 1fr 2fr;
grid-template-rows: 1fr 1fr;
animation: change 1s linear infinite alternate;
}
.child {
background-color: gray;
text-align: center;
font-size: 50px;
color: white;
line-height: 70px;
grid-column:span 2;
}
.child-1 {
grid-row-start: 1;
grid-row-end: 3;
}
.child-2 {
grid-column-start: 3;
grid-column-end: 7;
}
#keyframes change {
to {
grid-gap:1px;
}
}
<div class="container">
<div class="child child-1">1</div>
<div class="child child-2">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
Basically the trick is to avoid having a constant width for your elements.
Problem:
It's not easy to see it from outside but if you can Examine the Grid Layout in Firefox developer tools you can see the difference.
You can notice that the width of the two columns of 2 is changing yet the parent remains constant because it is spanning them both and breaking it would make the grid asymmetrical.
Solution:
You can use this Grid Generator and create some changes to the code for the following setup:
Now 1 spans two fractions of the layout, 2 spans four fractions while 3 and 4 spans two fractions each. In this way, the whole structure is symmetrical.
.container {
display: grid;
width: 500px;
height: 100px;
grid-gap: 20px; /* Try to change this, width of 2 isn't updated */
grid-template-columns: 4fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
transition: grid-gap 1s ease-in-out;
}
.container:hover {
grid-gap: 0px;
}
.child {
background-color: gray;
text-align: center;
font-size: 50px;
color: white;
line-height: 70px;
}
.child-1 {
grid-area: 1 / 1 / 3 / 2;
}
.child-2 {
grid-area: 1 / 2 / 2 / 6;
}
.child-3 {
grid-area: 2 / 2 / 3 / 4;
}
.child-4 {
grid-area: 2 / 4 / 3 / 6;
}
<div class="container">
<div class="child child-1">1</div>
<div class="child child-2">2</div>
<div class="child child-3">3</div>
<div class="child child-4">4</div>
</div>
I have been having some trouble getting CSS Grid to work properly with my React App. When I use grid-template-columns: 1fr 3fr 1fr;, one of the 1fr columns is much smaller than the other (so the space on the right is much smaller than the space created on the left in comparison to the middle column). Is there any particular reason why this would be? Here is the rest of my CSS:
#main-body {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-auto-rows: 100px;
background-color: white;
}
#main-header {
color: white;
background-color: darkcyan;
grid-column-start: 2;
grid-row-start: 1;
text-align: center;
display: inline;
}
#quote-render-block {
text-align: center;
background-color: orange;
grid-column: 2;
grid-row-start: 2;
}
There may be another child react component apart from the main-body or some styling for the parent component that is creating the issue. You can view a codepen of your code here: https://codepen.io/sakettawde/pen/yxvoxM
HTML:
<div class="main-body">
<div class="main-header">
</div>
<div class="quote-render-block">
</div>
</div>
CSS:
.main-body {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-auto-rows: 100px;
background-color: white;
}
.main-header {
color: white;
background-color: darkcyan;
grid-column-start: 2;
grid-row-start: 1;
text-align: center;
display: inline;
}
.quote-render-block {
text-align: center;
background-color: orange;
grid-column: 2;
grid-row-start: 2;
}
It is possible that a parent element has a "padding-right" CSS attribute that is shifting the contents of the screen.
I'm wondering how css grids can make use of max-widths. In the old way, you'd use a container with wrapper class that'd set the margins.
With CSS grids, depending on how you create them, you no longer need to use containers and sometimes you have no where to add one.
I want the header to be full width, but I want the nav within it to have a max width of 80% of the screen's resolution and margin auto it, this code is similar to the way one would have done it with a wrapping container. The question is, how do I do the same with aside and main as they are not inside of a parent to set a max width with?
body {
display: grid;
grid-template-areas:
"header header"
"aside main";
grid-template-columns: 275px 1fr;
grid-template-rows: 1fr 1fr;
}
header {
grid-area: header;
border: solid 1px black;
}
header > nav {
max-width: 80%;
margin: auto;
border: solid 1px blue;
}
aside {
grid-area: aside;
}
main {
grid-area: main;
}
HTML
<html>
<body>
<header>
<nav>nav</nav>
</header>
<aside>aside</aside>
<main>main</main>
</body>
</html>
If I have to wrap them inside of a container, how will that affect the grid? If I set the max width on the html or body tag then how would I get a header that stretches the full width of the browser?
https://jsfiddle.net/6zd3o088/6/
Think of this as a FOUR column grid of
grid-template-columns: 10% 275px 1fr 10%;
Then assign your elements per the revised grid-areas
grid-template-areas:
"header header header header"
". aside main .";
body {
display: grid;
grid-template-areas: "header header header header" ". aside main .";
grid-template-columns: 10% 275px 1fr 10%;
grid-template-rows: 1fr 1fr;
margin: 0;
padding: 0;
background: lightgrey;
}
header {
grid-area: header;
background:rebeccapurple;
}
header>nav {
max-width: 80%;
margin: auto;
background: lightblue;
}
aside {
grid-area: aside;
background: lightgreen;
}
main {
grid-area: main;
background: pink;
}
<header>
<nav>nav</nav>
</header>
<aside>aside</aside>
<main>main</main>
To use a max-width with the nav respecting the value we have to take the nav out of the header so it becomes a grid-item. Then we can align it on the grid over the header.
Using minmax for inner columns we can achieve the desired result
body {
display: grid;
grid-template-columns: 1fr minmax(auto, 100px) minmax(auto, 300px) 1fr;
grid-template-rows: 1fr 1fr;
margin: 0;
padding: 0;
background: lightgrey;
}
header {
grid-column: 1/-1;
grid-row: 1;
background: rebeccapurple;
}
nav {
grid-column: 2 / 4;
grid-row: 1;
background: lightblue;
}
aside {
grid-column: 2;
background: lightgreen;
}
main {
grid-column: 3;
background: pink;
}
<header></header>
<nav>nav</nav>
<aside>aside</aside>
<main>main</main>
Demo'd here using smaller column width for reference only. Amend the max figures as desired.
Codepen