fr units cannot be the minimin value of minmax() (css) - 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>

Related

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));
}
}

Nested grids result in rows automatically filling the largest size

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;
}

CSS fr / fractional units minimum too large

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>

Css grid minmax wrap

I have the following grid with 3 items:
<div class="grid">
<p> </p>
<p> </p>
<button> </button>
</div>
.grid {
display: grid;
justify-content: flex-start;
align-items: flex-end;
grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr) minmax(100px, 1fr);
grid-gap: 2rem;
}
I want the paragraphs to be at least 200px as from css minmax and the button to be at least 100px and wrap as a decrease the browser window width.
but this doesnt happen.
The elements stay in one row.
Thank you
Close enough to what you wanted (without media queries and convoluted rules not worth the trouble):
HTML:
<div class="container">
<p>Lorem ipsum</p>
<p>Delor sit</p>
<button>Amet</button>
</div>
CSS:
// See the container's items:
.container > * { background: lightblue; }
A) Use grid; don't know if possible to set different minmax() while preserving repeat(auto-fit, ..) behavior:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 2rem;
}
B) Use flexbox; the margins hack mimicks grid's gutters until CSS implements flexbox gutters natively:
.container {
display: flex;
flex-wrap: wrap;
margin-right: -2rem;
}
.container > * { margin-right: 2rem; }
p { flex: 1 1 200px; }
button { flex: 1 1 100px; }

Resources