I'm trying to create 3 divs each containing 1 <p>-tag and distribute all 3 on the same row with an equal width using CSS grid.
Most sources say that I should use grid-template-columns to achieve this. Some say to go for 1fr 1fr 1fr, some say repeat(3, 1fr), and yet more say repeat(3, auto).
The result is the same. The 3 divs end up on the same line, but their widths change depending on the width of their content. Is there a way to force all 3 divs to have the same width and simply use the next line if the content is too wide?
The snippet should show the situation I'm in.
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.content {
margin: 2em;
}
<div class="grid-container">
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
</div>
Your grid is fine - the content is the problem here.
You can try word-break or overflow as a workaround:
word-break solution:
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
border: 2px dotted green;
}
.content {
margin: 2em;
border: 2px solid red;
}
.content p {
word-break: break-word;
}
<div class="grid-container">
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
</div>
overflow solution:
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
border: 2px dotted green;
}
.content {
margin: 2em;
border: 2px solid red;
overflow: auto;
}
<div class="grid-container">
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
</div>
EDIT: Apparently, word-break: break-word; does not work in Firefox - thanks, #Yaakov Ainspan. Another reminder that you should test your code in multiple browsers. word-break: break-all; can be used instead.
#fen1x's answer was close, but not quite. I experimented with this a bit, and found that word-break: break-all worked, while break-word did not. (The overflow solution sort of works, but isn't what the OP asked for).
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
max-width: 100%;
}
.content {
margin: 2em;
word-break: break-all;
}
<div class="grid-container">
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
<div class="content">
<p>TESTESTTESTTESTTESTTESTTESTTESTTESTTESTTES</p>
</div>
</div>
Additionally, this solution does not need to be applied to individual elements inside the grid item, but can be applied directly to the item.
Try:
grid-template-columns: repeat(3, minmax(0, 1fr));
Related
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>
I'm trying to build a grid with 2 rows inside a flex column. The flex container has a minimum height to fill the window. The first line of the grid should fill the available space, so I was thinking of the fr unit. A simplified version may look like that:
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.grid {
flex-grow: 1;
background-color: red;
padding: 1rem;
grid-gap: 1rem;
display: grid;
grid-template-rows: 1fr auto;
}
.grid > * {
background-color: white;
}
<div class="container">
<h1>some title</h1>
<div class="grid">
<div>line 1</div>
<div>line 2</div>
</div>
</div>
This works perfectly fine with firefox:
But not with chrome:
What am I missing?
The grid container is interpreting the min-height: 100vh on the flex parent differently in Chrome and Firefox.
As you noted, in Firefox everything works as you expect. But in Chrome, the min-height is effectively ignored (even though flex-grow: 1 works on the same element).
If you switch to height: 100vh you'll see the 1fr work in Chrome, as well.
I would have to research more to tell you if this is a bug or not.
Consider nesting the grid inside another grid, as opposed to flex, container.
.container {
display: grid;
min-height: 100vh;
grid-template-rows: min-content 1fr;
}
.grid {
background-color: red;
padding: 1rem;
grid-gap: 1rem;
display: grid;
grid-template-rows: 1fr auto;
}
.grid>* {
background-color: white;
}
<div class="container">
<h1>some title</h1>
<div class="grid">
<div>line 1</div>
<div>line 2</div>
</div>
</div>
jsFiddle demo
When doing something like grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); I would like my content to not spill out of the grid cell if it is too big or long. Here is an example codepen I created that illustrates the problem. I added some long text with no line breaks to the 3rd grid item. As you can see you the text goes off the edge. I would like the 3rd grid item to expand to fit the text. I am okay if the entire 3rd column has to expand as well, I would just like it to fit the text.
Here is one more slightly modified example codepen#2 with just 2 grid item and the same problem. When those 2 items are still on the same row I would like it to behave as if I had declared grid-template-columns: 1fr 1fr; but then still having the 2nd item wrap to a second row when small enough.
Is there a way to accomplish this?
please check the below css code :
.container {
display: block;
}
.item {
background: #ffc600;
display: grid;
min-width: 100px;
min-height: 100px;
margin: 5px;
float: left;
justify-items: center;
align-content: center;
}
you just have to do make grid-template-columns: repeat(auto-fit, minmax(100px, auto)); max property to auto, it will expand according to content.
.container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(100px, auto));
grid-auto-rows: 100px;
}
.item {
background: #ffc600;
display: grid;
justify-items: center;
align-content: center;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">Three...Long TextSpilling</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
</div>
guys. I'm trying to understand CSS Grid and found a behaviour I thought would be simple but turned out to be a little complicated.
I need to follow a 12-column layout a have a row with 2 elements but I need these elements to fill 100% of the width if it is the single element.
I tried to use auto-fit and it almost did the job but I couldn't find a way to explicitly set 12 columns this way.
Here's a snippet of my code:
<div class="autofit">
<div class="content"></div>
<div class="banner"></div>
</div>
.autofit {
display:grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-gap: 20px;
text-align: center;
}
.autofit .content{
grid-column: 1/9;
}
.autofit .banner {
grid-column: 10/-1;
}
This way the grid works as expected but if I delete the .banner element the .content doesn't stretch to fill the available space ):
Use :only-child to define and extra rule:
.autofit {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-gap: 20px;
text-align: center;
margin:5px;
}
.autofit > *{
height:20px;
}
.autofit .content {
grid-column: 1/9;
background:red;
}
.autofit .banner {
grid-column: 10/-1;
background:blue;
}
.autofit > :only-child{
grid-column: 1/-1;
}
<div class="autofit">
<div class="content"></div>
<div class="banner"></div>
</div>
<div class="autofit">
<div class="content"></div>
</div>
<div class="autofit">
<div class="banner"></div>
</div>
You try this.
.grid-container {
display: grid;
}
.grid-container--fit {
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
.grid-container div{background:#ff0000;}
<div class="autofit grid-container grid-container--fit">
<div class="content">test</div>
<div class="banner">test</div>
</div>
Auto fit
<div class="autofit grid-container grid-container--fit">
<div class="content">test</div>
</div>
Problem:
Right now both of the grid elements below are min: 250px, max: 1fr in size. They wrap on screen size <250px
I'm trying to achieve the following:
the first element to be min: 250px, max: 2fr
the second element to be min: 250px, max: 1fr
but also maintain wrapping to 1fr each on screen size <250px (the way they wrap now basically)
Code:
Codepen: https://codepen.io/anon/pen/dEBQgm?editors=1100
<div class="container">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
...
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 16px;
}
.child {
background: #aaa;
height: 32px
}
I tried this but I lost the wrapping:
grid-template-columns: minmax(250px, 2fr) minmax(250px, 1fr);
You can try flexbox for this:
.container {
display: flex;
flex-wrap: wrap;
margin:-8px; /*Pay attention to this! You may need overflow:hidden on a parent container*/
}
.child {
background: #aaa;
height: 32px;
min-width: 250px;
flex-basis: 0%;
margin: 8px;
}
.container> :first-child {
flex-grow: 2;
}
.container> :last-child {
flex-grow: 1;
}
.container-grid {
display: grid;
grid-template-columns: minmax(250px, 2fr) minmax(250px, 1fr);
grid-gap:16px;
}
.container-grid > .child {
margin:0;
}
flexbox with wrapping
<div class="container">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>
grid without wrapping:
<div class="container-grid">
<div class="child">Child 1</div>
<div class="child">Child 2</div>
</div>