Page overflowing with gird repeat auto-fit - html

I have a grid with an auto-fit. It's working fine, but on smaller (< 350) screens, it's overflowing. How can fixe this? Basically have 350 as long as it's possible and shrink otherwise.
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 1rem;
}
.item {
background-color: crimson;
height: 200px;
border-radius: 2rem;
}
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

You can nest another property inside minmax(), e.g. min():
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 350px), 1fr));
gap: 1rem;
}
.item {
background-color: crimson;
height: 200px;
border-radius: 2rem;
}
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

This should achieve what you're looking for:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(350px, 100%), 1fr));
gap: 1rem;
}
Your minimum width was not responsive, so I've fixed that by adding a value of 100% inside the minmax using min().

Related

Centering in CSS grid with a fixed width column

Im trying to make a simple CSS centered grid layout.
I know that when I use justify-items: center, the items inside a grid container are supposed to align horizontally, but when I specify a column width in pixels like this grid-template-columns: repeat(3, 100px) the whole grid return to normal. So is there any way to make the grid items centered but in same time specify the column width in pixels?
Here are my example:
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
.container {
background-color: #aa96da;
display: grid;
justify-items: center;
grid-gap: 20px;
grid-template-rows: repeat(3, 1fr);
/*Only if I change this 100px to '1fr' the justify-items will work */
grid-template-columns: repeat(3, 100px);
}
.item {
width: 100px;
height: 100px;
background-color: green;
}
Change the justify-items to justify-content and it should work.
.container {
background-color: #aa96da;
display: grid;
/* justify-items: center; */
justify-content: center;
grid-gap: 20px;
grid-template-rows: repeat(3, 1fr);
/*Only if I change this 100px to '1fr' the justify-items will work */
grid-template-columns: repeat(3, 100px);
}
.item {
width: 100px;
height: 100px;
background-color: green;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Short answer: You want justify-content not justify-items
.container {
background-color: #aa96da;
display: grid;
justify-content: center; /* -items to -content */
grid-gap: 20px;
grid-template-rows: repeat(3, 1fr);
/*Only if I change this 100px to '1fr' the justify-items will work */
grid-template-columns: repeat(3, 100px);
}
.item {
width: 100px;
height: 100px;
background-color: green;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Long answer:
There's a difference between the grid item and the space it lives in.
When you define a grid, you're only defining rows/columns of the grid called tracks, Not actually defining where each element goes etc.
The DOM elements only follow the flow of the grid and are placed accordingly, which we can alter using properties like grid-column grid-row
You can look at it like this:
As you can see there's The Grid container, The Grid, The Columns, The Rows and then The Grid items.
The Grid items lives in the intersection between the two called The Grid Area (this what makes css grid better than flexbox in some ways)
And justify-items aligns the grid items within that area.
So grid-template-columns: repeat(3, 1fr); This means 3 columns their width is the width of the grid split evenly between them.
Demo
Don't look at the code just the preview
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
[grid] {
height: 300px;
display: flex;
border: 2px solid;
padding: 10px;
flex-wrap: wrap;
}
[column] {
flex: 1 0 calc(100% / 3);
border: 2px solid;
display: flex;
flex-direction:column;
align-items:center;
}
[column]>div {
width: 100px;
flex:1;
background-color: green;
}
<div grid>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
</div>
As you can see the grid columns are wider than the grid items 100px which means there space to center stuff, So justify-items: center; will center them inside.
That's why it looks like the grid is centered, But it's actually not reasons why changing to grid-template-columns: repeat(3, 100px); breaks it.
In the case of grid-template-columns: repeat(3, 100px);
Demo
Don't look at the code just the preview
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
[ctr] {
border: 2px solid;
padding: 10px;
}
[grid] {
height: 300px;
width: 340px;
display: flex;
padding: 10px;
flex-wrap: wrap;
}
[column] {
flex: 0 0 100px;
border: 2px solid;
display: flex;
flex-direction: column;
align-items: center;
}
[column]>div {
width: 100px;
flex: 1;
background-color: green;
}
<div ctr>
<div grid>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
<div column>
<div>Grid Item</div>
</div>
</div>
</div>
As you can see the columns width equal the grid item's so they all fit snugly within the columns and the grid is still empty.
You can try adding the flex property on top of those grid elements and then center it with justify-content:center;
index.html:
<div class="centering_items">
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
style.css
.centering_items {
display: flex;
justify-content: center;
}
.container {
background-color: #aa96da;
display: grid;
grid-gap: 20px;
grid-template-rows: repeat(3, 1fr);
/*Only if I change this 100px to '1fr' the justify-items will work */
grid-template-columns: repeat(3, 100px);
}
.item {
width: 100px;
height: 100px;
background-color: green;
}

How to repeat a grid-template-areas?

I have problem with grid. I want create some like this:
I want this schema repeat a few times.
But my code is not flexie.
.grid {
margin: 0 auto;
display: grid;
grid-template-columns: 32% 32% 32%;
grid-column-gap: 20px;
grid-row-gap: 20px;
grid-template-areas: "a b c"
"d e f"
"g g g"
"h i j"
"k l m"
"o o o";
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
.item5 {
grid-area: e;
}
.item6 {
grid-area: f;
}
.item7 {
grid-area: g;
}
.item {
background: red;
border: 4px solid black;
height: 20px;
width: 100%;
}
<div class="grid">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
<div class="item item5"></div>
<div class="item item6"></div>
<div class="item item7"></div>
</div>
how to improve the grid?
I want to repeat the scheme 3 3 1. If I have about 100 elements this solution will be unbearable
You can simplify like below. No need for grid-template-areas or grid-template-columns
.grid {
margin: 0 auto;
display: grid;
grid-gap: 20px;
}
.grid > .item:nth-child(7n) {
/* this will create 3 columns layout and force each 7th element to span all of them */
grid-column:span 3;
}
.item {
background: red;
border: 4px solid black;
height: 20px;
}
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

How can I make a two-column layout have equal height columns with one scrollable? [duplicate]

This question already has answers here:
One flex/grid item sets the size limit for siblings
(6 answers)
How can you set the height of an outer div to always be equal to a particular inner div?
(2 answers)
Closed 3 years ago.
I want to display two areas in two columns using CSS Grid. However height of left column must be the same as height in right column.
If left column is higher than right column the content in left column should be scrollable.
What I want to achieve:
I cannot to this without hardcoding heights in pixels. Is is possible to do that by CSS only? Or I need to use JavaScript to recalculate left column height?
I attached jsFiddle to take a look.
https://jsfiddle.net/rafalcypcer/2teonuhy/17/
Thanks,
Rafal
.gridwrapper {
display: grid;
grid-template-columns: 0.5fr 1.5fr;
grid-auto-rows: 200px;
grid-gap: 10px;
grid-template-rows: auto;
}
.column {
background: green;
}
.dynamic-content {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
background: pink;
margin: 20px;
}
.list {
overflow-y: auto;
margin: 20px;
height: 100%;
}
.item {
height: 50px;
background: yellow;
border: 2px solid black;
}
<div class="gridwrapper">
<div class="column">
<div class="list">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
<div class="column">
<div class="dynamic-content">Some dynamic content with random height</div>
</div>
</div>
Since the width is known you can consider position:absolute for the content so it doesn't affect the height and simply stretch it using top:0;bottom:0;
.gridwrapper {
display: grid;
grid-template-columns: 0.5fr 1.5fr;
grid-auto-rows: 200px;
grid-gap: 10px;
grid-template-rows: auto;
}
.column {
background: green;
position:relative;
}
.dynamic-content {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
background: pink;
margin: 20px;
}
.list {
position:absolute;
overflow-y: auto;
margin: 20px;
top:0;
bottom:0;
left:0;
right:0;
}
.item {
height: 50px;
background: yellow;
border: 2px solid black;
}
<div class="gridwrapper">
<div class="column">
<div class="list">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
<div class="column">
<div class="dynamic-content">Some dynamic content with random height</div>
</div>
</div>

margins and flex-wrap in a flexbox

I have a problem with flex-wrap property of a flexbox.
Here is my code:
.container {
display: flex;
flex-wrap: wrap;
}
.item {
width: 50%;
margin: 0 10px;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
</div>
What I want to do is to let some space margin between items but without wrapping them. I want them horizontally two by two and every item with width of 50% margin included to prevent flex-wrap.
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 1 0 34%; /* fg, fs, fb */
margin: 10px;
height: 50px;
background-color: gray;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
With flex-grow: 1 defined in the flex shorthand, there's no need for flex-basis (width) to be 50%, which results in one item per row due to the margins.
Since flex-grow will consume free space on the row, flex-basis only needs to be large enough to enforce a wrap.
In this case, with flex-basis: 34%, there's plenty of space for the margins, but not enough space for a third item on each line.
You can use calc for this, so for example you can set flex-basis: calc(50% - margin x 2).
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex-basis: calc(50% - 20px);
margin: 10px;
background: lightblue;
height: 50px;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
You may use calc to exclude margin from the width:
.container {
display: flex;
flex-wrap: wrap;
}
.item {
width: calc(50% - 20px);
margin: 5px 10px;
height:20px;
background:red;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

How can I arrange elements inside a wrapper like the example below?

I need to arrange following elements as This sample Image with CSS Flexbox.
.wrapper {
width: 60%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.element {
width: 200px;
height: 200px;
background: green;
margin-bottom: 20px;
}
<div class="wrapper">
<div class="element large"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element large"></div>
</div>
I have tried few styles but couldn't get successful. Is there any way to fix this with css flex?
In case you change your mind, the Grid solution:
.grid {
width: 60%;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(4, 100px); /* "width" */
grid-template-rows: repeat(4, 100px); /* "height" */
grid-gap: 10px; /* gap between items */
justify-content: center; /* horizontally centered */
}
.item {
background: green;
}
.larger {
grid-column: 1 / span 2; /* starts at the 1st column & spans two */
grid-row: 1 / span 2; /* starts at the 1st row & spans two */
/* can also omit the 1's since it's the first child */
}
.larger2 {
grid-column: 3 / span 2;
grid-row: 3 / span 2;
}
<div class="grid">
<div class="item larger"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item larger2"></div>
</div>