css grid fit rows heights - css

I want to remove the worthless margin between rows, so I want every div takes the content height without giving margin to his side div, I tried everything but nothing works.
.grids {
width: 90%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(min-content, max-content);
margin: auto;
grid-gap: 32px;
}
.grid {
position: relative;
width: 95%;
height: max-content;
margin: 10px;
padding: 20px;
background: black;
border-radius: 10px;
}
<div class="grids">
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
</div>

Edit: To make a masonry layout I have wrapped grid items in div tag
so you can nest as many tags as you want.
grid items overflow the content because of the width and height properties.
you're using a grid gap for both rows and columns.
So I guess this might help you out.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
grid-template-rows: masonry;
grid-gap: 10px;
}
.grid-item {
padding: 20px;
background: red;
border-radius: 10px;
margin-bottom: 24px;
}
<div class="grid">
<div>
<div class="grid-item">
<h1>Hello world</h1>
</div>
<div class="grid-item">
<h1>Hello world</h1>
</div>
</div>
<div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
<div>
<div class="grid-item">
<h1>Hello
<br>
friend
</h1>
</div>
<div class="grid-item"></div>
</div>
</div>
Also, I renamed the classes for naming purposes only.
MDN docs grid-row: row-gap
MDN docs masonry layout: masonry layout

You can try to set grid-gap: 32px to grid-gap: 0 32px, it will remove the margin between grid rows;

Related

Separate line text in CSS grid

I want to make a grid in footer where the text is above the grid but also staying in the grid. Position: absolute don't work because it effects both grid and text, and i want to move them independently of each other.
How it looks:
https://i.imgur.com/norbzp1.png
How i want it to be:
https://i.imgur.com/1fYoQIF.png
Code:
<div class="footer">Footer
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
</div>
And css:
.footer{
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: 50px;
grid-gap: 10px;
}
.icon{
display: flex;
background: rgb(160, 84, 84);
}
You can achieve this by wrapping the grid and the footer with a container.
.footer-header {
text-align: center;
padding:20px;
}
.footer-grid {
grid-column: span 3 / auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: 50px;
grid-gap: 10px;
}
.icon{
display: flex;
background: rgb(160, 84, 84);
}
<div class="footer">
<div class="footer-header">
Footer
</div>
<div class="footer-grid">
<div class="icon">1</div>
<div class="icon">2</div>
<div class="icon">3</div>
<div class="icon">4</div>
<div class="icon">5</div>
<div class="icon">6</div>
</div>
</div>
Also you can use grid-template-areas, for example
.footer{
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas: "footer-head footer-head footer-head";
grid-auto-rows: 50px;
grid-gap: 10px;
}
.icon{
display: flex;
background: rgb(160, 84, 84);
}
.footer-head {
text-align: center;
grid-area: footer-head;
}
<div class="footer">
<div class="footer-head">Footer</div>
<div id="icon1" class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
</div>

Responsive centering of divs

How do I go from here
To here
I'm trying to center the inner div's to their parent except for the last row where I'd like to align it left to the row above it.
Here is the jsfiddle for the top image https://jsfiddle.net/L15p2nev
.container {
text-align: center;
background-color: green;
}
.item {
display: inline-block;
width: 300px;
background-color: red;
}
<div class="container">
<div class="item">
item
</div>
<div class="item">
item
</div>
<div class="item">
item
</div>
</div>
Using grid display layout, this can be archived.
You can set grid-template-columns: repeat(auto-fit, 300px) to align items as the image.
.container {
background-color: green;
display: grid;
grid-template-columns: repeat(auto-fit, 300px);
justify-content: center;
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.item {
display: inline-block;
background-color: red;
}
<div class="container">
<div class="item">
item
</div>
<div class="item">
item
</div>
<div class="item">
item
</div>
</div>

Shrink grid items just like flex items in css

Is it possible to shrink grid items just like flex items in css?
Grid items
.container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.child {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
padding: 5px;
border: 3px solid #a07;
}
<div class="container">
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
</div>
jsfiddle
Flex items
.container {
display: flex;
margin-left: -10px;
flex-flow: row wrap;
}
.child {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
padding: 5px;
border: 3px solid #a07;
flex: 200px 1 1;
margin-left: 10px;
margin-bottom: 10px;
}
<div class="container">
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
</div>
jsfiddle
In a nutshell I can have the following positioning of the elements with the flex above:
While I can not achieve the same behaviour by using a grid layout. Flex layout allows items to shrink on small screen, while grid layout does not allow. At the same time I would like to preserve the behavior that the item will move to the next line with another item only when after such a placement each one of them will be no shorter than a specific size (200px in our case).
I am using grid layout because it allows to preserve the invariant that widths of all the children will be the same. With flex layout the last item will be stretched to the whole line if it will be alone on the line.
New solution
An optimized version of the initial solution using min()
.container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(min(200px,100%), 1fr));
}
.child {
display: flex;
align-items: center;
justify-content: center;
padding: 5px;
border: 3px solid #a07;
}
body {
margin:0;
}
<div class="container">
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
</div>
Old solution
One solution is to specify a max-width to the child element relying on the viewport unit since percentage values are relative to the size of the track defined by the minmax() and cannot be used. This solution isn't generic and you need to adjust the value depending on each situation.
In you case for example, we can use 100vw since the container is the only element in the body and is taking the whole width:
.container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.child {
display: flex;
align-items: center;
justify-content: center;
padding: 5px;
border: 3px solid #a07;
max-width:100vw;
box-sizing:border-box; /* Don't forget this !*/
}
body {
margin:0;
}
<div class="container">
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
</div>
In case there is more element or some padding/margin you need to consider them within the max-width calculation:
.container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.child {
display: flex;
align-items: center;
justify-content: center;
padding: 5px;
border: 3px solid #a07;
max-width:calc(100vw - 40px); /*we remove the body margin*/
box-sizing:border-box;
}
body {
margin:0 20px;
}
<div class="container">
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
<div class="child">
text
</div>
</div>
It's like we no more have 2 constraints but 3:
The grid cell has a minimum size of 200px
The grid cell fill the remain space
The element inside the grid cell has a maximum size defined relatively to the screen size. (the shrink constraint we were missing)

Flexbox that wraps around a fixed container

I'm trying to create a form with a variable number of form fields that would expand horizontally. Each field would have a minimum width of 300 px, but would expand to fill the row if there is extra space. If there is not enough space for each field at 300px, then it would wrap to another row. Flexbox would be the perfect solution for this. However, I also want there to be a variable width container for submit & cancel buttons that is fixed on the right side of the first row. (See the attached illustration.)
How can I create this fixed, right-aligned container that Flexbox would flow around? Can this be done with Flexbox alone? Would CSS Grid (or a combination of Flexbox & Grid) be helpful here? Example code would be appreciated.
I think your best solution is to use float and inline-block. then you can adjust sizing considering media query
body>.container {
background-color: #FFFFFF;
margin: auto;
margin-top: 24px;
padding: 0px;
}
.container {
border: solid 1px #F00;
font-size:0;
}
.box {
box-sizing: border-box;
border: 1px solid #000;
text-align: center;
vertical-align: middle;
min-height: 36px;
width: calc(25% - 10px);
min-width: 200px;
display:inline-block;
margin: 5px;
font-size:initial;
}
.box.buttons {
float:right;
}
<link data-require="bootstrap-css#*" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" />
<div class="container">
<div class="box buttons">
<button>Submit</button>
<button>Cancel</button>
</div>
<div class="box a">Box A</div>
<div class="box b">Box B</div>
<div class="box c">Box C</div>
<div class="box e">Box E</div>
<div class="box f">Box F</div>
</div>
After some experimentation, I found that this is possible with CSS Grid. Here is the basic layout:
HTML:
<div class="auto-fit">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C</div>
<div class="D">D</div>
<div class="E">E</div>
<div class="F">F</div>
<div class="G">G</div>
<div class="H">H</div>
<div class="I">I</div>
<div class="J">J</div>
<div class="K">K</div>
<div class="L">L</div>
<div class="M">M</div>
<div class="buttons"><button>Submit</button><button>Cancel</button></div>
</div>
CSS:
div.auto-fit {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
}
div.auto-fit > div {
background-color: #fff;
border-radius: 3px;
padding: 15px;
font-size: 14px;
}
div.buttons {
grid-column: -1/-2;
grid-row: 1/2;
}
Here is a jsfiddle that shows it in action: https://jsfiddle.net/lobo78/5ufqdm4y/22/

CSS Grid: Is it possible to apply color to grid gaps?

Is there a way to style more than just the width of the grid gaps within the CSS grid layout module? I can't find anything about it in the documentation, however one would tend to think that it would be possible as grid gaps tend to be colored in many designs. If it is not possible, is there a workaround?
Sadly, there is currently no way in the CSS Grid spec to style grid-gap. I came up with a solution that works well though that involves just html and css: show border grid lines only between elements
Instead to use the solution above I recommend to use border with pseudo-classes because if you have an irregular amount of "table cells" you will end up with an ugly color filled cell at the end of the "table".
If you want to use borders between the "table cells" and you have not always the same amount of cells you can do something like this (this example would also work with flexbox):
.wrapper {
display: grid;
grid-template-columns: repeat(2, auto);
/* with flexbox:
display: flex;
flex-wrap: wrap;
*/
}
/* Add border bottom to all items */
.item {
padding: 10px;
border-bottom: 1px solid black;
/* with flexbox:
width: calc(50% - 21px);
*/
}
/* Remove border bottom from last item & from second last if its odd */
.item:last-child, .item:nth-last-child(2):nth-child(odd) {
border-bottom: none;
}
/* Add right border to every second item */
.item:nth-child(odd) {
border-right: 1px solid black;
}
<div class="wrapper">
<div class="item">BOX 1</div>
<div class="item">BOX 2</div>
<div class="item">BOX 3</div>
<div class="item">BOX 4</div>
<div class="item">BOX 5</div>
</div>
For instance: if one has a 5x5 grid of squares, is the only way to get colored grid lines to fill the grid with 25 elements and apply borders to those same elements?
You could do that, but grid borders do not collapse the same way that table borders can with the border-collapse property, and unlike grid gaps they'll be applied to the perimeter of your grid along with the inner borders, which may not be desired. Plus, if you have a grid-gap declaration, the gaps will separate your grid item borders much like border-collapse: separate does with table borders.
grid-gap is the idiomatic approach for spacing grid items, but it's not ideal since grid gaps are just that: empty space, not physical boxes. To that end, the only way to color these gaps is to apply a background color to the grid container.
I added the border color as a background-color to the grid and added a background color to all grid-items.
.grid {
width: 1000px;
display: grid;
background: #D7D7D7;
grid-template-columns: repeat(5, 1fr);
grid-auto-rows: 200px;
grid-gap: 1px;
}
.grid-item {
background: white;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
</body>
</html>
This works for me.
It's not possible, but simply by setting a border in cascade:
this affects text and divs positions.
.grids {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
background: #222;
height: 326px;
width: 455px;
color: white
}
.grids > div {
border: 4px red solid
}
<div class="grids">
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
</div>
By using outline, the positions is unchanged:
.grids {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
background: #222;
height: 326px;
width: 455px;
color: white
}
.grids > div {
outline: 4px red solid;
}
<div class="grids">
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
<div>f</div>
</div>
There is a workaround way: use pseudo :after or :before in each column to apply background color to grid gap.
.grid-column::after {
position: absolute;
right: -20px; // grid-gap
top: 0;
height: 102px; // grid row height
width: 20px; // grid-gap
display: block;
content: '';
background-color: black !important;
}
If you don't know in advance how many columns will fit in your container, this is how I would do it (works for any number of columns and of any size. Also, this method do not style empty items):
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(80px, auto));
grid-auto-rows: minmax(80px, auto);
border-top: 1px solid #000;
border-left: 1px solid #000;
}
.grid-item {
border-bottom: 1px solid #000;
border-right: 1px solid #000;
}
/* not required */
.grid-item {
display: flex;
align-items: center;
justify-content: center;
background:#f5f5f5;
}
<div class="grid">
<div class="grid-item">Item 1</div>
<div class="grid-item">Item 2</div>
<div class="grid-item">Item 3</div>
<div class="grid-item">Item 4</div>
<div class="grid-item">Item 5</div>
<div class="grid-item">Item 6</div>
<div class="grid-item">Item 7</div>
<div class="grid-item">Item 8</div>
<div class="grid-item">Item 9</div>
<div class="grid-item">Item 10</div>
<div class="grid-item">Item 11</div>
<div>
You can also choose to leave out the grid gaps and use the border on the underlying div like so:
CSS:
.grid {
display: inline-grid;
border: red solid;
width: 200px;
height: 100%;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
.grid div {
border: red solid;
}
and the HTML:
<div className="grid">
<div>text</div>
<div>text</div>
<div>text</div>
<div>text</div>
<div>text</div>
<div>text</div>
<div>text</div>
<div>text</div>
</div>
I believe this achieves what you wanted to achieve:
Setting background-color on grid will color your gaps.
For example:
section {
display: grid;
grid-gap: 15px;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
background-color: red;
}

Resources