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!!
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>
I'm sure this has been answered before but I can't seem to get it working. I'm trying to horizontally center grid items with a display:grid parent. I've got a 12 column grid (76px column / 56px gap at full screen), with various column width child elements (for this example I'll just use span 8 1000px).
.main-container{
max-width:1528px;
margin: 0 auto;
}
.parent{
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-column-gap: 56px;
justify-items: center;
}
.grid-8{
grid-column: span 8;
background: red;
opacity: 0.6;
width: 100%;
}
<div class="main-container">
<div class="parent">
<div class="grid-8">8</div>
</div>
</div>
Also once the child element is centred is it possible for it to keep its width (1000px) until the .main-container starts to touch either side? once the browser starts to get pulled smaller (horizontally). Sorry, this is a little tricky for me to explain what I mean. The .main-container if the browser window is pulled in so this is at say 1200px wide the span 8 column will no longer be 1000px wide it will have shrunk (I'm guessing because it is relative to the main container size). But ideally, I'd like it to stay 1000px until the .main-container hits it and then the span 8 can start reducing in width.
Thanks
You can't align items in grid automatically with justify/align props.
You can try using grid-column-end: -N; syntax for each child nodes, but it's not best way to do that.
Much better to use flex - in this case you can align child nodes as you wish.
Anyway, if you want to continue working with grid, you can do something like this (like an option):
.main-container {
max-width: 1528px;
margin: 0 auto;
}
.parent {
--columns-amount: 12;
display: grid;
/*grid-template-columns: repeat(12, minmax(0, 1fr));*/
grid-template-columns: repeat(var(--columns-amount), 1fr);
grid-column-gap: 56px;
/*justify-items: center;*/
}
.grid-8 {
/* edit --column-size to see changes */
--column-size: 8;
grid-column: calc((var(--columns-amount) - var(--column-size)) / 2 + 1) / span var(--column-size);
background: red;
opacity: 0.6;
/*width: 100%;*/
}
/* flex */
.parent--flex {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.parent--flex>.grid-8 {
flex: 0 0 auto;
width: 66.66667%;
}
<div class="main-container">
<div class="parent">
<div class="grid-8">Grid</div>
</div>
</div>
<hr />
<div class="main-container">
<div class="parent--flex">
<div class="grid-8">Flex</div>
</div>
</div>
I have a jsfiddle.
What I have:
What I want:
Problem:
The hopefully relevant section is:
grid-template-columns: repeat(auto-fit, 1fr);
where both elements in my section have width: max-content;.
This (and the expanded but technically identical form of repeat(auto-fit, minmax(auto, 1fr));) do not do what I expect - it creates picture 1, I expect it to look like picture 2. It looks like the minimum width for these elements is too large, so instead of being on one row, it puts them in columns.
I made picture 2 by changing the code to repeat(auto-fit, minmax(200px, 1fr));. This is not a great solution as I want the minimum element size to be based on the grid elements' widths, not some arbitrary value.
I do want to have the elements able to be on different rows (for instance, if the browser is very narrow), so CSS grid seems useful for this task. I'm obviously just misunderstanding some key aspect.
Question
What value can I use in my grid-template-columns to make my elements work the way I expect with CSS grid? Is there a way to do it with repeat(auto-fit, X); or do I have to specify the number?
Answer
As stated below, you cannot use repeat(auto-fit with fr as it does not specify an absolute minimum or maximum, which the spec says is invalid.
Michael_B gave the answer (in his jdfiddle example comment) of using
display: flex;
flex-wrap: wrap;
which does exactly what I expected repeat(auto-fit, 1fr); to do.
This rule won't work.
grid-template-columns: repeat(auto-fit, 1fr)
The problem is explained here: minmax fails (invalid property value)
This rule won't work:
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))
The problem is explained here: minmax() defaulting to max
You can use min-content
.page-container {
display: grid;
grid-gap: 0.5rem;
grid-template-columns: 20% 80%;
grid-template-rows: auto auto 20rem;
grid-template-areas: "header header" "sidebar content" "footer footer";
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 25px;
padding: 50px;
}
.header {
grid-area: header;
display: grid;
grid-template-columns: repeat(2, min-content);
grid-gap: 10px;
}
.header>* {
background-color: lightgreen;
}
.header a:link {
color: inherit;
text-decoration: none;
}
.header a:hover {
/* https://html.spec.whatwg.org/multipage/rendering.html#phrasing-content-3 */
text-decoration: underline;
}
.header h1,
h2 {
margin: 0;
width: max-content;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.footer {
grid-area: footer;
}
<div class="page-container">
<section class="box header">
<h1><a href="https://jeremy.richards.dev">
Jeremy.Richards.dev
</a></h1>
<h2>
and this on the
</h2>
</section>
<div class="box sidebar">
Sidebar
</div>
<div class="box content">
Content
</div>
<div class="box footer">
<h2 style="font-size: 2rem;">
Something
</h2>
<h3 style="font-size: 1.5rem;">
My name underneath
</h3>
<p>
Linkedin/github/SO
</p>
</div>
</div>
I am trying to get CSS Grid blocks to stack on top of each other when viewed on small screens. I know I can write media queries to change two columns to one. But I thought Grid could handle this without them?
I thought I could achieve this with auto-fit on columns. However, I think I may of misunderstood how this works?
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
grid-template-rows: 1fr 1fr;
grid-template-areas: "leftCol rightTop" "leftCol rightBottom";
height: 100vh;
}
.leftCol {
grid-area: leftCol;
background-color: pink;
width: 100%;
height: 100;
}
.rightBottom {
grid-area: rightBottom;
background-color: yellow;
width: 100%;
height: 100;
}
.rightTop {
grid-area: rightTop;
background-color: blue;
width: 100%;
height: 100;
}
<div class="grid-container">
<div class="leftCol"></div>
<div class="rightBottom"></div>
<div class="rightTop"></div>
</div>
When the screen is below 400px, the right hand column just disappears. I was expecting them to stack on top of each other.
For example:
CodePen Example
I am trying to get CSS Grid blocks to stack on top of each other when viewed on small screens. I know I can write media queries to change two columns to one. But I thought Grid could handle this without them? I thought I could achieve this with auto-fit on columns.
You can.
Here you go:
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
grid-auto-rows: 50%;
height: 100vh;
}
.leftCol { background-color: pink; }
.rightBottom { background-color: yellow; }
.rightTop { background-color: blue; }
body { margin: 0; }
<div class="grid-container">
<div class="leftCol"></div>
<div class="rightBottom"></div>
<div class="rightTop"></div>
</div>
revised codepen
Here's the problem with your original code:
The repeat() function allows you to render a pattern of tracks in the grid container.
With auto-fit or auto-fill, the repeat() function will render as many tracks as possible without overflowing the container.
By itself, your code works as you expect, as illustrated above.
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr))
With this rule, the grid items stack into a single column on smaller screens.
However, when you introduce explicit columns and rows, this interferes with the ability of repeat() and auto-fit to do their job.
grid-template-areas: "leftCol rightTop" "leftCol rightBottom"
This rule tells grid items where they need to be, stunting repeat().
grid-template-rows: 1fr 1fr
This rule creates a two-row limit in the container, pushing the third item off-screen.
In a nutshell, don't add rules that interfere with repeat() / auto-fit. If you need a more sophisticated layout, then use media queries.
try using
css:
.grid-container div {
display: inline-block;
float: left;
}
seems like an easy task which Im trying to get done since hours. I cant get my grid elements vertical aligned properly. Please take a look at the fiddle to get the idea. Maybe someone could help me with this issue.
HTML
<section class="top">
<div></div>
<div></div>
</section>
<section class="bottom">
<div></div>
<div></div>
<div></div>
</section>
CSS
section {
display: grid;
grid-template-rows:auto;
margin: 40px 0 0 0
}
section.top {
grid-template-columns:2fr 1fr;
grid-column-gap: 50px;
}
section.bottom {
grid-template-columns:1fr 1fr 1fr;
grid-column-gap: 50px;
}
section div {
background:lightblue;
height:400px
}
https://jsfiddle.net/ecj1wrae/
Well, with some thinking and calculation this one here does the trick
CSS
section.top {
grid-template-columns:calc(66% + 2vw) 34%;
grid-column-gap: 2vw;
}
section.bottom {
grid-template-columns:33% 33% 34%;
grid-column-gap: 2vw;
}
https://jsfiddle.net/ecj1wrae/3/
I know this is an old question... But I had a similar problem and I thought I'd share my solution for anyone else that needs some help.
This comment helped push me in the right direction
But you're dividing space using fr units, which applies only free
space in the container. And the bottom section has 50px less free
space than the top. So they cannot be aligned in this manner
As the layout needs to consider the gaps between the columns I found it better to frame the problem as it needs to take up 2 columns of a 3 column layout instead of thinking it needs to take up 2fr of a 3fr layout.
Helpfully grid allows us to specify how many columns an element can span grid-column: span 2;
Using the html in the question we can use a span on the first div in the top section:
section {
display: grid;
margin: 40px 0 0 0;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-column-gap: 50px;
}
section.top div:first-child {
grid-column: span 2;
}
If you would like to do it with only 1 parent element, this may be a solution:
.wrapper {
display: grid;
grid-template-columns: auto auto auto auto;
grid-row-gap: 50px;
grid-column-gap: 10px;
grid-template-areas:
'item1 item1 item1 item1 item2'
'item3 item3 item4 item4 item5';
}
.wrapper > div {
background: red;
height: 400px;
}
.item1 {
grid-area: item1;
}
.item2 {
grid-area: item2;
}
.item3 {
grid-area: item3;
}
.item4 {
grid-area: item4;
}
.item5 {
grid-area: item5;
}
<div class="wrapper">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
<div class="item4"></div>
<div class="item5"></div>
</div>
A really simple solution is change the grid-column-gap by margin (if having space on the sides is not a problem):
HTML
<section class="top">
<div></div>
<div></div>
</section>
<section class="bottom">
<div></div>
<div></div>
<div></div>
</section>
CSS
section {
display: grid;
grid-template-rows:auto;
margin: 4px 0 0 0
}
section.top {
grid-template-columns:2fr 1fr;
}
section.bottom {
grid-template-columns:1fr 1fr 1fr;
}
section div {
background:lightblue;
height:400px;
margin: 5px;
}
https://codepen.io/fillsanches/pen/oNEpKWN