Nested grids result in rows automatically filling the largest size - css

I have a grid that works great:
.grid {
display: grid;
height: 100vh;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
padding: 10px;
}
.card {
border: 2px solid #000;
}
<div class="grid">
<div class="card">Lots and lots and lots of text...</div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
In this example, I have the page divided into 4, with all divs the same size. As the text gets longer in the first card, it expands, pushing the other cards down (making them smaller) before ultimately pushing them off the page, increasing the height of the div.
https://codepen.io/EightArmsHQ/pen/641b47d9bbc7a13880a53b0da04bd3bb
If I wrap this another div
.wrap {
height: 100vh;
display: grid;
grid-template-rows: 20vh 1fr;
}
.grid {
display: grid;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
padding: 10px;
}
.card {
border: 2px solid #000;
}
<div class="wrap">
<div class="controls">
<h1>Text here.</h1>
</div>
<div class="grid">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
Then the .grid rows all match each others height. Which is cool, but not what I want in this scenario. How can I make them behave similarly to the previous example?
Incorrect behaviour:
https://codepen.io/EightArmsHQ/pen/5637d435b48628aa5f31d5b996bbc6bf

The 1fr in grid-template-rows: 20vh 1fr; makes the second grid take up the rest of the available space after your controls div. That space then gets equally divided in four quarters by the CSS settings of your second grid:
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
Simply remove the grid-template-rows style from your second grid so the grid row height is set to auto.
.wrap{
height: 100vh;
display: grid;
grid-template-rows: 20vh 1fr;
}
.grid{
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
padding: 10px;
}
.card{
border: 2px solid #000;
}

Related

grid-template-columns from end of text

I have grid that looks like this:
with the css:
display: grid;
float: left;
gap: 18px;
grid-template-columns: repeat(2, 1fr);
margin-top: 10px;
Is there a way to shorten the distance between Text1 and the start of Text2 long bla...?
(using the grid css and not matgin: -12px for example)
It seems like the distance between them is the width of Text2 long bla... (which is the longest element here)?
thank you!
Using repeat(2, 1fr) will divide the container into 2 equal parts. So if you want to lower the distance between them, you should change your containers width.
.firstContainer {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 300px;
border: 1px solid red;
}
.secondContainer {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 200px;
border: 1px solid green;
}
<section class="firstContainer">
<span>Hello</span>
<span>, World!</span>
</section>
<section class="secondContainer">
<span>Hello</span>
<span>, World!</span>
</section>

fr units cannot be the minimin value of minmax() (css)

When I tried putting 1fr in the first slot of minmax()and the browser dev tools tells me that it is not valid.
The moment I take away the 1fr, it works.
Code that did not work:
.grid {
grid-template-rows: minmax(1fr, auto); /* this did not work */
}
Is there any work arounds to this?
1fr cannot be your minimum because 1fr takes
1 fraction of the leftover space in the grid container
Here is the doc
You can do something like this
.grid {
display: grid;
grid-template-columns: repeat( auto-fit, minmax(100px, 1fr));
grid-gap: 10px;
}
.bloc {
display: flex;
justify-content: center;
align-items: center;
background-color: teal;
color: white;
}
<div class="grid">
<div class="bloc">1</div>
<div class="bloc">2</div>
<div class="bloc">3</div>
<div class="bloc">4</div>
<div class="bloc">5</div>
<div class="bloc">6</div>
<div class="bloc">7</div>
<div class="bloc">8</div>
<div class="bloc">9</div>
</div>

Justifying column(s) in CSS Grid defined with repeat()

I have a multiple column CSS Grid defined with repeat(6, 1fr) but with only one or two columns defined. It seems justifying center or space-between does not work in this case, probably because the grid already knows it has 6 equal width columns so there is nothing to justify?
.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 3em;
grid-gap: 1rem;
/*justify-items: center; horizontally centers column content */
/*align-items: center; vertically centers column content */
}
.grid > div {
background-color: yellow;
}
.grid > div:first-child {
background-color: orange;
}
<div class="grid">
<div>content1</div>
<div>content2</div>
</div>
If you will have only one row you can do the following otherwise use flexbox:
.grid {
display: grid;
grid-auto-columns: calc((100% - 5rem)/6);
grid-auto-flow: column;
grid-template-rows: 3em;
grid-gap: 1rem;
justify-content: center;
border: 1px solid;
}
.grid>div {
background-color: yellow;
}
.grid>div:first-child {
background-color: orange;
}
<div class="grid">
<div>content1</div>
<div>content2</div>
</div>
<div class="grid">
<div>content1</div>
<div>content2</div>
<div>content3</div>
</div>
<div class="grid" style="justify-content: space-between;">
<div>content1</div>
<div>content2</div>
</div>
<div class="grid" style="justify-content: space-between;">
<div>content1</div>
<div>content2</div>
<div>content3</div>
</div>

How to make 2 css grid columns into 1 for mobile without media query?

As title says + I need to keep itemX and itemY in one cell on each device. Is media query the only solution? If there is more of a native css grid way I would love to learn it.
See fiddle:
https://jsfiddle.net/forusak/ctg3auh0/
.container {
display: grid;
grid-template: repeat(10, auto) / repeat(auto-fit, minmax(250px, 1fr));
column-gap: 30px;
color: white;
}
.container>* {
background-color: #b90011;
border: 1px solid black;
padding: 5%;
height: 20px;
}
.item1 {
grid-row: 1 / 10;
height: auto;
}
/* comment out part bellow to see mobile responsivity which is missing here */
.itemX,
.itemY {
grid-area: 3 / 2 / 3 / 2;
width: 40%;
}
.itemY {
margin-left: auto;
}
<div class="container">
<div class="item1"> </div>
<div class="item"> </div>
<div class="item"> </div>
<div class="itemX"> itemX </div>
<div class="itemY"> itemY </div>
<div class="item"> </div>
<div class="item"> </div>
</div>
Checkout the below code. At screen-width < 464px itemX and itemY will reassemble vertically.
body {
padding: 1rem;
}
.res-grid-1 {
--min-size: 25rem;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--min-size), 1fr));
grid-gap: 1rem;
}
.res-grid-1 > div {
padding: 5rem 1rem;
text-align: center;
font-size: 2rem;
background: #557571;
color: #ffffff;
}
.res-grid-2 {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
grid-gap: 1rem;
}
<div class="res-grid-1">
<div>Item 1</div>
<div class="res-grid-2">
<div>Item X</div>
<div>Item Y</div>
</div>
</div>
However there is a small bug, between screen-width 1280px and 1328px itemX and itemY are reassembling horizontally(which should be vertically). This is due to nesting of grid;it is possible to achieve responsive CSS grid without media-queries but here you're trying achieve the same for a nested grid without media-queries.
If you wish to use media-queries, you can fix this bug by making following changes to CSS:
In class res-grid-2 replace line:
grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
with:
grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
and add:
#media only screen and (max-width: 576px) {
.res-grid-2 {
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
}

How to specify different size for each grid element and maintain wrapping?

Problem:
Right now both of the grid elements below are min: 250px, max: 1fr in size. They wrap on screen size <250px
I'm trying to achieve the following:
the first element to be min: 250px, max: 2fr
the second element to be min: 250px, max: 1fr
but also maintain wrapping to 1fr each on screen size <250px (the way they wrap now basically)
Code:
Codepen: https://codepen.io/anon/pen/dEBQgm?editors=1100
<div class="container">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
...
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 16px;
}
.child {
background: #aaa;
height: 32px
}
I tried this but I lost the wrapping:
grid-template-columns: minmax(250px, 2fr) minmax(250px, 1fr);
You can try flexbox for this:
.container {
display: flex;
flex-wrap: wrap;
margin:-8px; /*Pay attention to this! You may need overflow:hidden on a parent container*/
}
.child {
background: #aaa;
height: 32px;
min-width: 250px;
flex-basis: 0%;
margin: 8px;
}
.container> :first-child {
flex-grow: 2;
}
.container> :last-child {
flex-grow: 1;
}
.container-grid {
display: grid;
grid-template-columns: minmax(250px, 2fr) minmax(250px, 1fr);
grid-gap:16px;
}
.container-grid > .child {
margin:0;
}
flexbox with wrapping
<div class="container">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
grid without wrapping:
<div class="container-grid">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>

Resources