Nested CSS grid layout different behavior in Chrome and Firefox - html

I'm trying to use CSS grid layout to simulate some responsive behavior, specifically with:
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
My example https://codepen.io/elgs/pen/goNxeL works well in Chrome, however, it doesn't seem to work in Firefox. You will find it when you resize the browser horizontally.
Another example https://codepen.io/elgs/pen/YYoxOq works well in both Chrome and Firefox.
html,body {
height: 100%;
width: 100%;
margin: 0 auto;
padding: 0;
}
body {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
}
.header {
grid-column: 1/2;
grid-row: 1/2;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer {
grid-column: 1/2;
grid-row: 3/4;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.footer .copyright {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
font-size: 12px;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.content {
grid-column: 1/2;
grid-row: 2/3;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 0;
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
max-width: 1000px;
}
.placeholder {
height: 100px;
position: relative;
border: 1px solid red;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>
I'm wondering whether I have done anything wrong or it's the browser's bug.
Firefox version: 58.0 (64-bit)
Chrome version: Version 64.0.3282.119 (Official Build) (64-bit)

This appears to be a bug in Firefox. But I'm not sure.
Here's what is clear:
The fact that you have nested grid containers matters.
Your second demo, which works in both Chrome and Firefox, has only one grid container.
The first demo, which only works in Chrome, has nested grid containers. If you eliminate that nesting, and use only one grid container, the layout works in both browsers.
So, as a possible cross-browser solution, minimize the nesting of grid containers.
In this revised demo, I've commented out display: grid on the body and .content elements. The only grid container left is on .main, the parent of the red boxes:
revised demo
html,
body {
height: 100%;
width: 100%;
margin: 0 auto;
padding: 0;
}
body {
/* display: grid; */
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
}
.header {
grid-column: 1/2;
grid-row: 1/2;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer {
grid-column: 1/2;
grid-row: 3/4;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.footer .copyright {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
font-size: 12px;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.content {
grid-column: 1/2;
grid-row: 2/3;
/* display: grid; */
grid-template-columns: 1fr;
grid-template-rows: 0;
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
max-width: 1000px;
}
.placeholder {
height: 100px;
position: relative;
border: 1px solid red;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>
In Firefox, a fixed value on max-width prevents the box from shrinking to accommodate smaller screen sizes.
Firefox has a problem shrinking the .main container with a pixel value on the max-width. Chrome does not.
A typical solution that comes to mind is to override the min-width: auto default setting on grid items. This prevents items from shrinking past the size of their content or their defined width.
However, that solution, described here: Prevent content from expanding grid items ... doesn't work in this case.
(Probably because there is no content in and no defined widths on the grid items. The only widths defined are on the grid columns, set on the grid container. So the solution, which applies only to grid items, probably doesn't even apply.)
As a possible workaround, if you must keep the nested containers, then instead of using a fixed value with max-width, use a percentage value. That may work for you.
revised codepen
body {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
height: 100vh;
margin: 0;
}
.header {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.content {
display: grid;
grid-template-columns: 1fr;
/* grid-template-rows: 0; */
align-content: start; /* new */
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 100px; /* new */
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
/* max-width: 1000px; */
max-width: 75%; /* new */
}
.placeholder {
border: 1px solid red;
}
.footer {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title,
.footer .copyright {
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer .copyright {
font-size: 12px;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>

Related

Need assist with CSS grid layout of cards

I have this grid over here:
and i want the first big card to take the whole height of the wrapper and remain the same width, while the bottom two cards go to the right, somehow like this:
here's my css/html code where item-1 is the bigger card on the top-left:
.cards-wrapper {
background-color: #43cbff;
width: 1240px;
height: 380px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-gap: 20px;
#media (min-width: 30em) {
grid-template-columns: 1fr 1fr;
}
#media (min-width: 60em) {
grid-template-columns: repeat(4, 1fr);
}
}
.cards {
display: flex;
flex-direction: column;
min-height: 100%;
position: relative;
top: 0;
background-color: aquamarine;
border: 1px solid lightgrey;
border-radius: 8px;
}
.item-1 {
#media (min-width: 60em) {
grid-column: 1 / span 2;
h1 {
font-size: 24px;
}
}
}
You can keep the grid layout and use grid-template-areas to make that first item take up the full height whilst retaining its existing width.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
gap: 8px 8px;
grid-auto-flow: row;
grid-template-areas:
"one one two three"
"one one four five";
}
.container * {
background: orange;
}
.one { grid-area: one; }
.two { grid-area: two; }
.three { grid-area: three; }
.four { grid-area: four; }
.five { grid-area: five; }
<div class="container">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
<div class="four">4</div>
<div class="five">5</div>
</div>
Flex version
I dont know you entire structure and your requirement. But by using only flexbox you can archive this also quite easy.:
.cards-wrapper {
background: gray;
}
.flex {
display: flex;
gap:5px;
}
.left, .right {
width: 50%;
}
.right {
flex-wrap: wrap;
justify-content: center;
}
.right > div {
width: 49,2%;
background-color: lightgreen;
height:100px;
}
.big {
background-color: green;
width: 100%;
}
<div class="cards-wrapper flex">
<div class="left flex">
<div class="big">BIG</div>
</div>
<div class="right flex">
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
</div>

grid layout with resize horizontal not resizing columns [duplicate]

This question already has an answer here:
resize column across multiple rows using html grid layout
(1 answer)
Closed 1 year ago.
I've got a grid layout and I'm using resize: horizontal on one. It lets me resize the box but it doesn't resize the other columns as I would expect it to.
html,
body,
.main {
height: 100%;
margin: 0;
}
.main {
display: grid;
grid-template-columns: minmax(100px, 200px) 1fr;
grid-template-rows: 50px 1fr;
gap: 2px 2px;
grid-auto-flow: row;
grid-template-areas: "header-box header-box" "left-box main-box";
}
.header-box {
background-color: lightblue;
grid-area: header-box;
overflow: hidden;
}
.left-box {
background-color: lightgreen;
grid-area: left-box;
resize: horizontal;
overflow: auto;
}
.main-box {
background-color: lightpink;
grid-area: main-box;
overflow: auto;
}
<div class="main">
<div class="header-box">header box</div>
<div class="left-box">left box</div>
<div class="main-box">main box</div>
</div>
minmax(100px, 200px) is as good as 200px if you want shrinking behavior change to minmax(100px, 1fr)
If you want the grid to responsed to the content rather than the available width of it's own parent change to display: inline-grid;
html,
body,
.main {
height: 100%;
margin: 0;
}
.main {
display:inline-grid;
grid-template-columns: minmax(100px, 1fr) 1fr;
grid-template-rows: 50px 1fr;
gap: 2px 2px;
grid-auto-flow: row;
grid-template-areas: "header-box header-box" "left-box main-box";
}
.header-box {
background-color: lightblue;
grid-area: header-box;
overflow: hidden;
}
.left-box {
background-color: lightgreen;
grid-area: left-box;
resize: horizontal;
overflow: auto;
}
.main-box {
background-color: lightpink;
grid-area: main-box;
overflow: auto;
}
<div class="main">
<div class="header-box">header box</div>
<div class="left-box">left box</div>
<div class="main-box">main box</div>
</div>

How to make a child span the grid from the first to the last gap?

I have a parent grid of 12 columns and a gap of 24px between each column. I want to render a child grid that will start from end of column 1 or start from first gap and end to the last gap, How can I achieve this?
Here's an example of what I want:
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
column-gap: 24px;
}
.grid div {
grid-column: ???;
}
<div class="grid">
<div></div>
</div>
make the element to span from the second column to before the last column then use negative margin:
.grid {
border: 1px solid;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 24px;
}
.grid div {
height: 100px;
background: red;
grid-column: 2 / -2;
margin: 0 -24px;
}
<div class="grid">
<div></div>
</div>
You can also do it like below:
.grid {
border: 1px solid;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 24px;
}
.grid div {
height: 100px;
background: red;
grid-column: 2 / -2;
width: calc(100% + 48px);
justify-self: center;
}
<div class="grid">
<div></div>
</div>

How can I make the content of a grid element not affect its size?

Basically i just want the four boxes in the snippet below to be the same size while still having the text centered inside the first box. Right now the text 'qwe' affects the size of the first box. Also it has to be using display: grid, like it is now.
.asd {
width: 100px;
height: 100px;
border: 1px solid black;
display: grid;
grid-template-columns: repeat(4 1fr);
grid-template-rows: repeat(4 1fr);
}
.asd > div {
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
}
.box1 {
grid-column: 1/2;
grid-row: 1/2;
}
.box4 {
grid-column: 2/3;
grid-row: 2/3;
}
<div class="asd">
<div class="box1">qwe</div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
</div>
Your css is invalid grid-template-columns: repeat(4 1fr);grid-template-rows: repeat(4 1fr);
use
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
If the text grow out of the box use overflow: hidden;
.asd {
width: 100px;
height: 100px;
border: 1px solid black;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
.asd > div {
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
<div class="asd">
<div class="box1">qwe qwe qwe</div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
</div>
Add height and width to 50px of each div as the asd is 100px
.asd {
width: 100px;
height: 100px;
border: 1px solid black;
display: grid;
grid-template-columns: repeat(4 1fr);
grid-template-rows: repeat(4 1fr);
}
.asd > div {
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
width:50px;
height:50px;
}
.box1 {
grid-column: 1/2;
grid-row: 1/2;
}
.box4 {
grid-column: 2/3;
grid-row: 2/3;
}
<div class="asd">
<div class="box1">aqs</div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
</div>
You should use minmax() so it won't use the minimum content size as minimum width for that column.
.mygrid
{
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
}
Also you may want to tell the browser to break the text lines in the middle of a word (if it fails to find a good spot to wrap). This is especially useful in case you have long links in your text:
.mygrid__item
{
word-break: break-word;
}

CSS Grid not working in ie11 despite prefixes

I have the following simple layout example using CSS grid
.container {
width: 100%;
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr auto 1fr;
grid-template-columns: 1fr auto 1fr;
}
.item1 {
text-align:center;
background:red;
color:white;
padding:20px
}
.item2 {
text-align:center;
background:green;
color:white;
padding:20px
}
.item3 {
text-align:center;
background:blue;
color:white;
padding:20px
}
<div class="container">
<div class="item1">
Item 1
</div>
<div class="item2">
Item 2
</div>
<div class="item3">
Item 3
</div>
</div>
I have prefixed with ie specific prefixes but the grid is not working correctly in ie11. Am I missing a prefix?
Anyone any ideas why?
IE does not have auto-flow of grid elements. You need to assign a specific grid position to each grid element, otherwise each non-placed element ends up stacked in 1,1.
.container {
width: 100%;
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr auto 1fr;
grid-template-columns: 1fr auto 1fr;
}
.item1 {
text-align: center;
background: red;
color: white;
padding: 20px;
-ms-grid-column: 1;
}
.item2 {
text-align: center;
background: green;
color: white;
padding: 20px;
-ms-grid-column: 2;
}
.item3 {
text-align: center;
background: blue;
color: white;
padding: 20px;
-ms-grid-column: 3;
}
<div class="container">
<div class="item1">
Item 1
</div>
<div class="item2">
Item 2
</div>
<div class="item3">
Item 3
</div>
</div>