How to put items in a grid, in which items will be touching container borders, and have specific gap between each items?
https://i.stack.imgur.com/simVM.png
It's a trivial but important problem to me. I make research and there is some methods(I don't like any of them and want find better solution)
1. Bootstrap method
DEMO: https://codepen.io/olegburakov/pen/MQORVX
.container{
overflow: hidden;
&__inner{
display: flex;
flex-wrap: wrap;
margin-left: -10px;
margin-right: -10px;
}
&__item{
padding: 10px;
width: 100%;
min-height: 100px;
@media screen and (min-width: 480px){
width: 50%;
}
@media screen and (min-width: 768px){
width: 33.33%;
}
@media screen and (min-width: 1024px){
width: 25%;
}
&-inner{
background: olive;
height: 100%;
}
}
}
I don't like this solution because of:
1) Negative margins in container to press items to it borders and make items touching it.
2)Need to add wrapper to container with overflow: hidden to hide horizontal scrollbar or padding-left and padding-right equal or bigger than negative margin of container.
3) Additional blocks in HTML: container-wrapper and item-inner
2. Nth-child method
More difficult than bootstrap method, and bad for media queries.
3. Grid layout method
DEMO: https://codepen.io/olegburakov/pen/xYPeoK
.container{
display: grid;
grid-template-columns: 1fr;
grid-gap: 20px;
@media screen and (min-width: 480px){
grid-template-columns: 1fr 1fr;
}
@media screen and (min-width: 768px){
grid-template-columns: 1fr 1fr 1fr;
}
@media screen and (min-width: 1024px){
grid-template-columns: 1fr 1fr 1fr 1fr;
}
&__item{
width: 100%;
min-height: 100px;
background: olive;
}
}
My favourite. Just 4 lines of code! But I'm not sure about it compatibility (for example in my not updated Edge15 demo looks like this https://i.stack.imgur.com/P5kPM.png). I think it's need some time before we can fully use grid layout.
4. Fluid width method
DEMO: https://codepen.io/olegburakov/pen/jYWyeW
I write a mixin that calculates width of items. So you not need extra HTML or padding/margin properties. BUT it don't work when last row has more then one item and less then full row. I tried to fix this with :before :after but it didn't work.
.container{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background: tomato;
&__item{
@include fluid-width-item(100%, 15px, 15px);
border: 1px solid #000;
min-height: 100px;
background-color: olive;
}
&__item{
@media screen and (min-width: 480px){
@include fluid-width-item(50%, 15px, 15px);
}
@media screen and (min-width: 768px){
@include fluid-width-item(33.33%, 15px, 15px);
}
@media screen and (min-width: 1024px){
@include fluid-width-item(20%, 15px, 5px);
}
}
}
So maybe I miss more interesting method without extra html/css and with good compatibility? Currently I use bootstrap method.