How to make a responsive css grid with margins using auto-fit? - html

I don't NEED to use auto-fit. I just want the code to work.
I want a left margin of 89px, a right margin of 89px, and two items in the middle. So I originally had something like this:
.container3 {
grid-template-columns: repeat(1, 89px 1fr 1fr 89px);
}
The above works, but is not responsive. I need these to break into separate rows when the screen goes smaller. This is the best I can come up with and it doesn't work...
.container3 {
height: 800px;
/* background-color: pink; */
display: grid;
grid-template-columns: repeat(
auto-fit,
89px minmax(300px, 1fr) minmax(300px, 1fr) 89px
);

If you want them to break into separate rows, you can make use of grid breakpoints.Bootstrap Grid options
You can try something like this:
<div class="container3">
<div class="row">
<div class="col-12 col-md-4">First row in xs screen / left column in medium and higher devices</div>
<div class="col-12 col-md-4">Second row in xs screen / middle column in medium and higher devices</div>
<div class="col-12 col-md-4">Last row in xs screen / Right column in medium and higher devices</div>
</div>
</div>

Related

dynamic grid, taking size from child element

I want to create an dynamic grid class. For my React application.
I want the grid columns 20% bigger then the item thats inside.
I have this solution below. My Problem is, that i have a hover effect on the items. And the hover effect adds a margin to the item. That forces the grid to resize. Is there any solution to make the grid 20% bigger then its elements but at the same time ignoring margin?
.grid-dynamic {
display: grid;
grid-template-columns: repeat(auto-fill, 20%);
grid-auto-rows: 120%;
place-items: center;
}
<div classname="grid-dynamic">
<div classname="item"></div>
<div classname="item"></div>
<div classname="item"></div>
<div classname="item"></div>
...
</div>

Two equal width columns (where the width is set by the longest one) and a third one fills the remaining space

I want to make a layout like this, using CSS Grid if possible but open to other possibilities:
Basically, I want to have a container .grid that contains 3 elements (input, btn1, btn2). Firstly, btn1 and btn2 width should be the same and is determine by whichever element needs more space (i.e longer content). After that, the remaining element (input) should take all what is left. I came up with this snippet but for sure it cannot work.
.grid {
display: grid;
grid-template-columns: auto 1fr 1fr;
}
<div class="grid">
<input />
<button>Foo</button>
<button>Bar Bar Bar</button>
</div>
What is a good way to achieve this using CSS only?
Use a nested grid container for the buttons.
.grid {
display: grid;
grid-template-columns: 1fr auto; /* see note 1 */
}
.button-container {
display: grid;
grid-template-columns: 1fr 1fr; /* see note 2 */
}
<div class="grid">
<input />
<div class="button-container">
<button>Foo</button>
<button>Bar Bar Bar</button>
</div>
</div>
<br>
<div class="grid">
<input />
<div class="button-container">
<button>Foo</button>
<button>Bar Bar Bar Bar Bar Bar</button>
</div>
</div>
<br>
<div class="grid">
<input />
<div class="button-container">
<button>Foo</button>
<button>Bar Bar Bar Bar Bar Bar Bar Bar Bar</button>
</div>
</div>
Notes:
1fr on the first column consumes all available horizontal space, pinning the second column to the right as much as possible.
1fr 1fr on the nested columns causes the horizontal space in the sub-container to be equally divided, regardless of content width.
Here is a hack (yes a hack!) that relies on the fact that you know the container width.
In the below, I will consider a full-page container (width defined using 100vw)
.grid {
display: grid;
margin:50px 5px;
grid-template-columns:1fr auto;
}
/* they will overlap so the longest one will define the size of auto*/
button {
grid-column:2;
grid-row:1;
}
/* we translate the first one to disable the overlap*/
button:first-of-type {
transform:translateX(-100%);
}
input {
/* 100vw - 10px = width of the grid container
100% is the width of the 1fr
((100vw - 10px) - 100%) will be the width of the buttons
*/
width:calc(100% - ((100vw - 10px) - 100%));
box-sizing:border-box;
}
body {
margin:0;
}
<div class="grid">
<input >
<button>Foo</button>
<button>Bar Bar Bar</button>
</div>

Setting one column equal width and for the rest using repeat(auto-fit, minmax()) in grid-template-columns

I'm using grid in my nav element that contains 7 nested elements. I want the first one to be at least 2x larger than the others. I tried to use this:
grid-template-columns: 2fr repeat(auto-fit, minmax(100px, 1fr));
But it doesn't work, in the console it shows that is invalid property value, why? How can I do this in another way?
Something like that ?
Also, maybe this could help : CSS Grid with variable number of “auto” rows, but one row should take “1fr”
.container{
display:grid;
grid-template-columns: 2fr repeat(6, minmax(auto,1fr));
}
.el:first-child{
background-color:red;
}
.el{
border:solid 1px black;
}
<div class="container">
<div class="el">Element</div>
<div class="el">Element</div>
<div class="el">Element</div>
<div class="el">Element</div>
<div class="el">Element</div>
<div class="el">Element</div>
<div class="el">Element</div>
</div>

css grid max-width when number of items doesnt fill the page [duplicate]

I'm working with CSS grids to achieve a card grid layout.
But I don't quite know how to tweak the minmax() statement to handle use cases where there aren't enough items to fill a row but still need them to look like cards!
If I replace the max 1fr value with a static 100px or I use a fractional 0.25fr it upsets the scaling at smaller media sizes.
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-column-gap: 17px;
grid-row-gap: 25.5px;
padding-bottom: 25.5px;
}
.card {
background-color: #000;
height: 100px;
}
<div class="wrapper">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
And then if there are only a couple items
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-column-gap: 17px;
grid-row-gap: 25.5px;
padding-bottom: 25.5px;
}
.card {
background-color: #000;
height: 100px;
}
<div class="wrapper">
<div class="card"></div>
<div class="card"></div>
</div>
The key is to use auto-fill instead of auto-fit.
When the repeat() function is set to auto-fit or auto-fill, the grid container creates as many grid tracks (columns/rows) as possible without overflowing the container.
Note that as the grid container is being rendered, the presence of grid items is irrelevant. The container just lays out the columns and rows as instructed, creating grid cells. It doesn't care if the cells are occupied or unoccupied.
With auto-fit, when there are not enough grid items to fill the number of tracks created, those empty tracks are collapsed.
Taking your code as an example, when there aren't enough grid items to fill all the columns in the row, those empty columns are collapsed. The space that was used by the empty columns becomes free space, which is then evenly distributed among existing items. By absorbing the free space, the items grow to fill the entire row.
With auto-fill, everything is the same as auto-fit, except empty tracks are not collapsed. They are preserved. Basically, the grid layout remains fixed, with or without items.
That's the only difference between auto-fill and auto-fit.
Here's an illustration of three grid items with auto-fill:
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
Here's an illustration of three grid items with auto-fit:
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
spec reference: https://www.w3.org/TR/css3-grid-layout/#auto-repeat
In Short,
Auto-fit: Fit entire length of container.
Auto-fill: Doesn't fit entire length of the contaier.
When using minmax() function, the auto-fit keyword will expand the grid items to fill the available space. While auto-fill will keep the available space reserved without altering the grid items width.

How to keep same image heights in fluid CSS grids?

I'm quite new to css grids. I need to code a 2 columns component, with fluid equal height images inside. I could do it with flexbox, but this time I need a css grid, and it must be responsive.
That said, this component has 2 images, 1 per column. The original img files have equal heights (340x300, 708x300). I need to show them about 30% and 70% width, minus gap. I tried to use both 'auto' and fr units, also combined, but no luck.
On the last/large breakpoint, it's all fine:
The problem comes when on smaller breakpoints: I can't keep the 2 images the same exact height (make them scale with same height):
Here's some code, one of the versions. But any variation of this code (different unit combinations) give some kind of problems, and none of them makes me having equal height images:
.images-block-box{
display: grid;
grid-gap: 16px;
grid-template-columns: auto auto;
//grid-template-columns: 1fr auto;
//grid-template-columns: 1fr 2fr;
//grid-template-columns: 33.333% 66.666%;
}
Ah, and obviously, the images are fluid (max-width:100%; height: auto).
How to solve?
The original img files have equal heights (340x300, 708x300).
You can exploit the fact that fractional units work in proportions of the items. So use grid-template-columns: 340fr 708fr if the images file are not going to change. See demo below:
.images-block-box{
display: grid;
grid-gap: 16px;
grid-template-columns: 340fr 708fr;
}
img {
max-width: 100%;
height: auto;
display: block;
}
<div class="images-block-box">
<img src="https://via.placeholder.com/340x300"/>
<img src="https://via.placeholder.com/708x300"/>
</div>
This is my answer. The trick is using img{object-fit: cover;}
.wrap{
width:100vw;
display:grid;
grid-template-columns:3fr 7fr;
grid-gap:1em;
}
.a img{width:100%;height:100%;object-fit: cover;}
<div class="wrap">
<div class="a">
<img src="http://via.placeholder.com/340x300" />
</div>
<div class="a">
<img src="http://via.placeholder.com/708x300" />
</div>
</div>