Why does grid-gap cause an overflow without percent? - css

Why do I have an overflow on the X axis in the following snippet?
The overflow is generated once I apply grid-gap: 35px on my .box grid container.
.container {
width: 500px;
border: 1px solid #000;
margin: 0 auto;
}
.box {
display: grid;
grid-template-columns: repeat(16, 1fr);
background: #00f;
gap: 35px;
}
.item {
height: 50px;
background: #0f0;
text-align: center;
line-height: 40px;
vertical-align: middle;
}
.span4 {
grid-column: span 4;
}
<div class="container">
<div class="box">
<div class="item span4">A</div>
<div class="item span4">B</div>
<div class="item span4">C</div>
<div class="item span4">D</div>
<div>
</div>

This is because a Grid item(i.e. .container) cannot be smaller than it's contents(all .item combined). Let's consider your case here.
container width = 500px
grid-template-columns is repeating 16 times with gap of 35px each. If we do the math here that would be 560px(16*35) which will be greater than your container width(500px).
To fix this either you increase the container width to 560px or make in percentages i.e. 100%
.container {
width: 100%; /*560px*/
border: 1px solid #000;
margin: 0 auto;
}
.box {
display: grid;
grid-template-columns: repeat(16, 1fr);
background: #00f;
gap: 35px;
}
.item {
height: 50px;
background: #0f0;
text-align: center;
line-height: 40px;
vertical-align: middle;
}
.span4 {
grid-column: span 4;
}
<div class="container">
<div class="box">
<div class="item span4">A</div>
<div class="item span4">B</div>
<div class="item span4">C</div>
<div class="item span4">D</div>
<div>
</div>

Since you have 4 div elements of class="item", in .box you can reduce the number of columns to 4
grid-template-columns: repeat(4, 1fr);
where each .item element spans 1 column.
grid-column: span 1;
This fixes the overflow problem.
As to why this happens:
For a certain column width, the column gap is supposed to take up a percentage of the column. If the column gap is smaller than the column width, then the column gap is by default included in the column. If the column gap is larger than the column width, then the column cannot hold the column gap and has no choice but to overflow. Since the column width which is 500/16 = 31.25 is smaller than the column gap 35, it overflows.
Note: this only seems to happen when an element is spamming more than one column. If an element is spanning one column and the the column gap is greater than column width, then it is constrained at the given column width. Hope this helped :)
Hope this helped :)

Related

3 siblings - Need 1 to grow responsively while the other 2 stay at min-content

Going to do my best to explain the constraints.
There's 3 containers .content .left and .bottom and a resize handler to control available space.
I need .container to 'grow' as the space grows to take up the available space.
.left should stay at it's min-content width and 100% height and is already (great).
.bottom should stay at it's min-content height and 100% width and isn't currently (not great).
Cannot change the structure of the HTML because it's outside my control in real world.
Messed around for awhile with different combinations of align-items: stretch and grow but can't seem to do it when the direction is a row, but can't change it to a column without changing structure of HTML.
.container {
display: flex;
flex-wrap: wrap;
height: 20rem;
width: 20rem;
overflow: hidden;
resize: both;
border: 1px solid blue;
}
.left {
border: 1px solid red;
}
.content {
border: 1px solid pink;
flex: 1;
}
.bottom {
border: 1px solid grey;
flex-basis: 100%;
}
<div class="container">
<div class="left">left min content</div>
<div class="content">should resize vertically and horizontally</div>
<div class="bottom"/>bottom should be min content</div>
</div>
in this scenario we can utilize display: grid; properties and achieve the required behavior without changing the HTML structure, by doing something like this.
.container {
display: grid;
grid-template-columns: max-content auto;
grid-template-rows: auto max-content;
height: 40rem;
width: 20rem;
overflow: hidden;
resize: both;
border: 1px solid blue;
}
.left {
border: 1px solid red;
}
.content {
border: 1px solid pink;
}
.bottom {
border: 1px solid grey;
grid-column: span 2;
}
<div class="container">
<div class="left">left min content</div>
<div class="content">should resize vertically and horizontally</div>
<div class="bottom">bottom should be min content</div>
</div>
I have simply defined 2 rows and columns, grid-template-columns: max-content auto; and grid-template-rows: auto max-content;.
then letting the 1st column take all the available height using max-content, and the 2nd column, which is the bottom one, stays auto and takes up the remaining space.
then using grid-column: span 2; on the bottom div. which expands it to the size of 2 rows which in our case is 100% of the width (as we only have 2 rows).
I hope this will resolve your issue.

neither FLEX nor GRID can't do what's needed

I'm trying to solve a simple task but the solutions seem not be that simple.
Basically, I want many blocks with the same size to be aligned in center but I nee 1 block that is twice bigger than the others.
If I use FLEX - there are blank spaces around the big block.
If I use GRID - I can't align the blocks in the center.
Please help!
#all {
width: 100%;
border: 1px solid #ff0000;
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, 150px);
grid-template-rows: repeat(auto-fill, 150px);
}
#all div {
width: 150px; height: 150px;
border: 1px solid #ff0000;
}
#all .big {
width: 310px; height: 312px;
grid-column: 2/ 4;
grid-row: 2 / 4;
}
<html>
<head>
<style>
</style>
</head>
<body>
<div id=all>
<div></div>
<div></div>
<div class=big></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</body>
</html>
I need them to be aligned in the center
Here is an edited answer from W3Schools.
NOTE: there must be enough items to circle the one in the middle.
First, you need to add odd items in the grid.
Then, add odd columns to align them properly as you want.
Last, use grid-area to start any of the items from the 2nd row and column. then end it at the other corner according to the number of items in the grid.
and the good thing about this is that it's responsive and you can select any item to put it in the middle.
here is the code.
.grid-container {
display: grid;
grid-template-columns: auto auto auto ; /* odd column */
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.grid-container > div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
.item5 {
grid-area: 2 / 2 / 4 / 3; /* start and end the selected item */
display: flex;
justify-content: center;
align-items: center;
}
<h1>The grid-column Property</h1>
<p>Use the <em>grid-column</em> property to specify where to place an item.</p>
<div class="grid-container">
<!-- add odd items in the grid -->
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
<div class="item5">5</div>
<div class="item6">6</div>
<div class="item7">7</div>
<div class="item8">8</div>
<div class="item9">9</div>
<div class="item10">10</div>
<div class="item11">11</div>
</div>

CSS Grid 3 columns first and second same size middle fixed size [duplicate]

This question already has an answer here:
How can I have a fixed-width centered column with in a 3-column layout?
(1 answer)
Closed 1 year ago.
I would like to create a grid with 3 columns, I want middle column to have fixed width but be always in center of the grid, meaning that first and last column fills the void but have same size.
this is what I got so far:
.grid {
width: 100%;
height: 100%;
display: grid;
gap: 5;
background-color: lightBlue;
grid-template-columns: auto 50px auto;
}
.grid-item {
border: 1px solid black;
overflow: hidden;
}
<div class="grid">
<div class="grid-item">A</div>
<div class="grid-item">B</div>
<div class="grid-item">CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC</div>
</div>
.grid {
width: 100%;
height: 100%;
display: grid;
background-color: lightBlue;
grid-template-columns: 1fr 50px 1fr;
}
.grid-item {
border: 1px solid black;
overflow: hidden;
}
<div class="grid">
<div class="grid-item">A</div>
<div class="grid-item">B</div>
<div class="grid-item">CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC</div>
</div>

A first element should take a free space and next elements should have fixed size

I want to set for fist element '1fr' and any other elements should have fixed size
I'm tried this and it works.
grid-template-columns: 500px repeat(auto-fill, 50px);
This, what I'm trying to do.
.container {
display: grid;
grid-template-columns: 1fr repeat(auto-fill, 50px);
> div {
border: 1px solid red;
}
}
A first element should have a 1fr (any available space)
enter image description here
I think flexbox would be more appropriate here.
.container {
display: flex;
height: 98vh;
margin: 1vh 1vw;
}
.item {
border: 1px solid red;
flex: 0 0 50px;
margin: .5em;
}
.wide {
flex: 1
}
<div class="container">
<div class="item wide">Auto Remaining Width</div>
<div class="item">50px</div>
<div class="item">50px</div>
<div class="item">50px</div>
</div>

Setting different lengths for grid gaps in CSS Grid

I'm creating a layout using CSS Grids, and I want to have different space between each row.
I can create the layout fine by just using margin on each element, but this kind of obscures the simplicity of the code. Is there any grid tricks I can do achieve this, grid-row-gap only seems to take one value, which it uses for all rows.
What I'm trying to achieve is a layout like this:
https://jsfiddle.net/8swzgk0b/1/
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: auto auto auto;
width 100%;
margin: 20px;
grid-column-gap: 40px;
/* grid-row-gap: 40px 60px; */
}
div {
background: #838383;
height: 80px;
}
.wide {
grid-column: 1 / span 3;
margin-bottom: 5px;
}
.row-2 {
background: green;
margin-bottom: 10px;
}
.row-3 {
background: blue;
margin-bottom: 30px;
}
.row-4 {
background: red;
margin-bottom: 20px;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
Is there any grid trick I can do to achieve this, grid-row-gap only seems to take one value, which it uses for all rows.
With the grid-row-gap, grid-column-gap and grid-gap properties, you cannot apply different widths to different gaps. Like you noted, only one value can be used for each axis: One for row gaps and another for column gaps (spec).
You could use margins (or padding) to show extra space, but this doesn't actually change the width of the gap. It only expands the row.
In the example below (based on your code), grid-row-gap is set to 20px. Grid items have the margin-bottom variations you set. Notice how the grip-row-gap size never changes. All changes occur inside the row.
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: auto auto auto;
grid-column-gap: 40px;
grid-row-gap: 20px;
}
div {
background: #838383;
height: 80px;
}
.wide {
grid-column: 1 / span 3;
margin-bottom: 5px;
}
.row-2 {
background: green;
margin-bottom: 10px;
}
.row-3 {
background: blue;
margin-bottom: 30px;
}
.row-4 {
background: red;
margin-bottom: 20px;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
If you want to apply different size gaps between rows, then consider using actual rows for the job:
Now the gaps between rows have their own unique heights.
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: 80px 5px 80px 10px 80px 30px 80px 20px; /* adjusted */
grid-column-gap: 40px;
}
.wide {
grid-column: 1 / span 3;
background: #838383;
}
.row-2 {
grid-row-start: 3;
background: green;
}
.row-3 {
grid-row-start: 5;
background: blue;
}
.row-4 {
grid-row-start: 7;
background: red;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
you can't set different values for the column or row gaps, however, you can use css custom properties such as margin or display or you can create extra rows and columns and assign different values to them using them as gaps.

Resources