Using minmax() functions in CSS grid - css

I have a grid with 2 columns x 2 rows. All of them are set in minmax() size. Can I ask why the element with class show doesn't take the full size of the grid even though I set all other elements (hide class) in the grid to width 0 and height 0. Doesn't minmax() work properly?
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--seemoresz: 100px;
}
#outer {
display: grid;
grid-template-columns: minmax(calc(700px - var(--seemoresz)), 700px) minmax(0px, var(--seemoresz));
grid-template-rows: minmax(0px, var(--seemoresz)) minmax(calc(700px - var(--seemoresz)), 700px);
width: 700px;
height: 700px;
overflow: hidden;
background-color: aqua;
}
.hide {
width: 0;
height: 0;
}
<div id="outer">
<div class="hide">
hide this
</div>
<div class="hide">
hide this
</div>
<div class="show">
show this
</div>
<div class="hide">
hide this
</div>
</div>

The minmax() function is working fine. So is the calc() function.
The problem is a misunderstanding about the minimum height and widths that are set.
Even though you set the grid items to zero width and height:
.hide {
width: 0;
height: 0;
}
...the grid columns have their own width and height:
#outer {
display: grid;
grid-template-columns: minmax(calc(700px - var(--seemoresz)), 700px) minmax(0px, var(--seemoresz));
grid-template-rows: minmax(0px, var(--seemoresz)) minmax(calc(700px - var(--seemoresz)), 700px);
}
The columns and rows aren't shrinking to zero, which prevents .show from expanding across the entire container.
Consider using auto instead of minmax() in grid-template-*. That will enable the column / row to track the size of the grid item.
Also consider the solutions in these posts:
How to make a column span full width when a second column is not there? (CSS Grid)
Is it possible to hide columns with empty content via the grid-template-columns definition?
minmax() defaulting to max

Related

grid-template-columns that bleed to the edge but are clamped in size

I'm wondering if it's possible to create a grid with a variable and unknown amount of cells such that:
The size of each cell is between MINIMUM and MAXIMUM size (lets say 200px and 500px) AND
The cells always expand all the way to edge of the container
https://codesandbox.io/s/grid-auto-fit-jqp7w
If you do
gridTemplateColumns: `repeat(auto-fit, minmax(200px, 1fr))`,
the cells will always fill up to the edge of the container correctly, but if you only have one cell, it can potentially be very large.
If you do
gridTemplateColumns: `repeat(auto-fit, minmax(200px, 500px))`,
the grid cells will wrap rather than decrease their size to fit
I don't know a way to achieve what you want using fixed width in minmax, like 200px and 500px. But a close option is to use auto-fill. It keeps responsiveness but does not allow a single child to take the full width of its parent when the screen is large.
* {
box-sizing: border-box;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 5px;
margin: 5px;
}
.cell {
background-color: grey;
padding: 1rem;
}
.single {
background-color: green;
}
<div class="grid">
<div class="single cell">single cell</div>
</div>
<div class="grid">
<div class="cell">cell</div>
<div class="cell">cell</div>
<div class="cell">cell</div>
</div>

How to make images in a CSS Grid lay next to each other and jump to another row when lacking space

I'm trying to position images the way shown in the picture using CSS Grid and I can't find a right solution.
Right now I'm simply changing the grid flow to column, but the grid elements don't jump to another row when they meet the end of the container - they resize it and stay in the same, first row.
I tried to use grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)) - it solves this jump to another line issue, but it gives all the elements a fixed width whereas some images are not that wide. It creates empty holes between images which I'd like to avoid.
Any ideas on how to accomplish it?
wrong solution 1
Code from the image above:
container {
display: grid;
grid-gap: 1rem;
grid-auto-flow: column;
}
photo { // all container's elements have this class
height: 10rem;
width: auto;
}
wrong solution 2
Code from the image above:
container {
display: grid;
grid-gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
photo {
height: 10rem;
max-width: 100%;
}
You see, this is tusk for flex, not for grid. Using grid means columns with same width on each row. No need here at all.
html {
font-size: 10px;
}
.conteiner {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.photo {
height: 10rem;
margin: 0 1rem 1rem 0;
}
.photo img {
width: auto;
height: 100%;
}
<div class="conteiner">
<div class="photo"><img src="https://via.placeholder.com/500x200"></div>
<div class="photo"><img src="https://via.placeholder.com/300x200"></div>
<div class="photo"><img src="https://via.placeholder.com/200x200"></div>
<div class="photo"><img src="https://via.placeholder.com/400x200"></div>
<div class="photo"><img src="https://via.placeholder.com/500x200"></div>
<div class="photo"><img src="https://via.placeholder.com/300x200"></div>
<div class="photo"><img src="https://via.placeholder.com/200x200"></div>
</div>
Although I'm using Justified gallery jQuery plugin, if I wand all images in each row to fill all the width.

Center The Leftover Item From The Last Row In GRID (1fr 1fr)

This is something that I've been struggling with for a while, but I can't seem to find a way to do it.
If you have an odd number of items in grid and you want 2 items per row (1fr 1fr), you end up with a single item in the last row that is left-centered.
I just want to make it centered so it looks nicer.
Here's a picture too.
You can try something like this jsfiddle:
/* visibility properties */
body {
width: 60%;
margin: 5% auto;
}
div {
margin: 3%;
width: 100px;
height: 100px;
background-color: black;
justify-self: center;
}
div:nth-of-type(2n) {
background-color: red;
}
/* actual code: */
section {
display: grid;
grid-template-columns: 1fr 1fr;
}
#last-div {
grid-column: 1 / span 2;
}
<section>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div id="last-div">
</div>
</section>
Get more info on CSS Grid: complete-guide-grid
You could try something like this since I faced a similar issue in one of my earlier projects.
grid-template-columns : repeat(auto-fit, minmax(<minSize>, 1fr));
Set minSize to whatever minimum width you want an element to occupy.

CSS grid with fixed-width larger than content

I have a simple CSS grid, with one cell - an <img>. The grid has a fixed width of 100px and uses grid-auto-columns: 100%; to scale the image down to fit inside:
.grid {
display: grid;
width: 100px;
grid-auto-columns: 100%;
background-color: #844;
}
.grid > * {
grid-column: 1;
grid-row: 1;
}
<div class='grid'>
<img src='https://i.imgur.com/HAwaW3D.png' />
</div>
But for some reason, the grid's height remains as if the image was rendered at its original size, leaving this empty space after the cell:
And I cannot for the life of me find a way to avoid it.
Any ideas on how to make the grid's height match its contents in this scenario?
note: I'm testing in Firefox 56.2.5

Grid-like container with adaptive width

I would like to have container, that satisfies following conditions:
it has 2 rows and unlimited amount of columns
all items inside it are one-word text elements, that have their width
all items inside it are equal width, defined by the widest element (longest word)
I was thinking about using a flexbox. Since all of the items have known height (because they are one line of text), I can define wrappable container like this:
display: flex;
flex-flow: column wrap;
height: 100px;
All items inside the same column are equal in width. But I want all of the items have the same width. Should I use grid? If yes, how?
You can try CSS grid like below:
.grid {
display: inline-grid;
grid-template-rows: 1fr 1fr; /*two equal rows*/
grid-auto-columns: 1fr; /*all columns will be equal*/
grid-auto-flow: column;
}
span {
outline: 1px solid;
padding: 5px
}
<div class="grid">
<span>some_text</span>
<span>text_long</span>
<span>text</span>
<span>a</span>
<span>text</span>
<span>some_text</span>
<span>some_looong_text</span>
<span>some_text</span>
</div>
If you want all the items to have the same width, you need to define their width within their class.
.container{
display: flex
height: 100px
}
.container__item{
width: 20px
height: 100%:
}
Change the width to your pleasure.

Resources