Reputation: 761
I tried to create a grid system based on flexbox for learning purposes, but I found some problems after creating things with it: when the total columns occupied 100% of the space, the last column went to the next line (container is flex-flow: row wrap;) but when they were not 100% (eg one column with 30% the other with 65%) they were on the same line ... Then I discovered that it was something related to margins, but still I could not solve it.
My doubts now are: what to use for the width of the columns? flex-basis? width
How do I get this problem with the margins to be resolved? I've seen one in github projects that use something like "gap" but I still do not quite understand how it works ...
I tried adding calc () properties together with "- $ gap" which was 10px but I still could not generate a grid the way it should be.
My previous code was like this:
.row {
display: flex;
}
@for $i from 1 through $grid-cols {
@media (max-width: 768px) {
.col-mob-#{$i} {
width: 100 / ($grid-cols / $i) * 1%;
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-#{$i} {
width: 100 / ($grid-cols / $i) * 1%;
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-#{$i} {
width: 100 / ($grid-cols / $i) * 1%;
}
}
@media (min-width: 1408px) {
.col-fhd-#{$i} {
width: 100 / ($grid-cols / $i) * 1%;
}
}
}
Edit: I managed to leave it a bit the way I wanted it the following way:
$grid-cols: 12;
$gap: 0.75rem !default;
// .row is used as container for divs with columns
.row {
display: flex;
}
@for $i from 1 through $grid-cols {
@media (max-width: 768px) {
.col-mob-#{$i} {
flex-basis: calc((100 / (#{$grid-cols} / #{$i}) * 1%) - #{$gap});
}
}
// ....
Upvotes: 0
Views: 706
Reputation: 272797
You can simply reduce the width using the value of the gap that you add as margin. The trick is to consider the fact that gaps are only inside thus you need to use -1
to correctly calculate the width:
.row {
display: flex;
}
$grid-cols : 8;
$gaps : 10px;
.row > div:not(:last-child) {
margin-right: $gaps;
}
@for $i from 1 through $grid-cols {
@media (max-width: 768px) {
.col-mob-#{$i} {
width: (calc((100% - (#{$grid-cols / $i} - 1)*#{$gaps})/ #{($grid-cols / $i)}));
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-#{$i} {
width: (calc((100% - (#{$grid-cols / $i} - 1)*#{$gaps})/ #{($grid-cols / $i)}));
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-#{$i} {
width: (calc((100% - (#{$grid-cols / $i} - 1)*#{$gaps})/ #{($grid-cols / $i)}));
}
}
@media (min-width: 1408px) {
.col-fhd-#{$i} {
width: (calc((100% - (#{$grid-cols / $i} - 1)*#{$gaps})/ #{($grid-cols / $i)}));
}
}
}
Full code compiled:
.row {
display: flex;
flex-wrap:wrap;
margin:5px;
}
.row > div{
height:50px;
background:red;
}
.row > div:not(:last-child) {
margin-right: 10px;
}
@media (max-width: 768px) {
.col-mob-1 {
width: calc((100% - (8 - 1)*10px)/ 8);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-1 {
width: calc((100% - (8 - 1)*10px)/ 8);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-1 {
width: calc((100% - (8 - 1)*10px)/ 8);
}
}
@media (min-width: 1408px) {
.col-fhd-1 {
width: calc((100% - (8 - 1)*10px)/ 8);
}
}
@media (max-width: 768px) {
.col-mob-2 {
width: calc((100% - (4 - 1)*10px)/ 4);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-2 {
width: calc((100% - (4 - 1)*10px)/ 4);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-2 {
width: calc((100% - (4 - 1)*10px)/ 4);
}
}
@media (min-width: 1408px) {
.col-fhd-2 {
width: calc((100% - (4 - 1)*10px)/ 4);
}
}
@media (max-width: 768px) {
.col-mob-3 {
width: calc((100% - (2.6666666667 - 1)*10px)/ 2.6666666667);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-3 {
width: calc((100% - (2.6666666667 - 1)*10px)/ 2.6666666667);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-3 {
width: calc((100% - (2.6666666667 - 1)*10px)/ 2.6666666667);
}
}
@media (min-width: 1408px) {
.col-fhd-3 {
width: calc((100% - (2.6666666667 - 1)*10px)/ 2.6666666667);
}
}
@media (max-width: 768px) {
.col-mob-4 {
width: calc((100% - (2 - 1)*10px)/ 2);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-4 {
width: calc((100% - (2 - 1)*10px)/ 2);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-4 {
width: calc((100% - (2 - 1)*10px)/ 2);
}
}
@media (min-width: 1408px) {
.col-fhd-4 {
width: calc((100% - (2 - 1)*10px)/ 2);
}
}
@media (max-width: 768px) {
.col-mob-5 {
width: calc((100% - (1.6 - 1)*10px)/ 1.6);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-5 {
width: calc((100% - (1.6 - 1)*10px)/ 1.6);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-5 {
width: calc((100% - (1.6 - 1)*10px)/ 1.6);
}
}
@media (min-width: 1408px) {
.col-fhd-5 {
width: calc((100% - (1.6 - 1)*10px)/ 1.6);
}
}
@media (max-width: 768px) {
.col-mob-6 {
width: calc((100% - (1.3333333333 - 1)*10px)/ 1.3333333333);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-6 {
width: calc((100% - (1.3333333333 - 1)*10px)/ 1.3333333333);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-6 {
width: calc((100% - (1.3333333333 - 1)*10px)/ 1.3333333333);
}
}
@media (min-width: 1408px) {
.col-fhd-6 {
width: calc((100% - (1.3333333333 - 1)*10px)/ 1.3333333333);
}
}
@media (max-width: 768px) {
.col-mob-7 {
width: calc((100% - (1.1428571429 - 1)*10px)/ 1.1428571429);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-7 {
width: calc((100% - (1.1428571429 - 1)*10px)/ 1.1428571429);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-7 {
width: calc((100% - (1.1428571429 - 1)*10px)/ 1.1428571429);
}
}
@media (min-width: 1408px) {
.col-fhd-7 {
width: calc((100% - (1.1428571429 - 1)*10px)/ 1.1428571429);
}
}
@media (max-width: 768px) {
.col-mob-8 {
width: calc((100% - (1 - 1)*10px)/ 1);
}
}
@media (min-width: 769px) and (max-width: 1023px) {
.col-tab-8 {
width: calc((100% - (1 - 1)*10px)/ 1);
}
}
@media (min-width: 1024px) and (max-width: 1407px) {
.col-hd-8 {
width: calc((100% - (1 - 1)*10px)/ 1);
}
}
@media (min-width: 1408px) {
.col-fhd-8 {
width: calc((100% - (1 - 1)*10px)/ 1);
}
}
<div class="row">
<div class="col-mob-3">
</div>
<div class="col-mob-5">
</div>
</div>
<div class="row">
<div class="col-mob-1">
</div>
<div class="col-mob-1">
</div>
<div class="col-mob-1">
</div>
<div class="col-mob-1">
</div>
<div class="col-mob-1">
</div>
<div class="col-mob-1">
</div>
<div class="col-mob-1">
</div>
<div class="col-mob-1">
</div>
</div>
<div class="row">
<div class="col-mob-4">
</div>
<div class="col-mob-4">
</div>
</div>
<div class="row">
<div class="col-mob-2">
</div>
<div class="col-mob-6">
</div>
</div>
Upvotes: 0
Reputation: 3103
FLexbox is linear, while Grid is 2 dimensional. There are loads of ways to approach this. but you need to use flex-wrap: no-wrap
.
I would define a flex row first.
.outerRow {
display: 'flex';
# Do not allow wrap (event though this is default)
flex-wrap: 'no-wrap';
# Fill the full height
align-items: 'stretch';
}
Now your columns. If you want two columns 25% and one column 50%, do like this:
.quarter {
flex-grow: 1;
}
.half {
flex-grow: 2;
}
notice that they are ratios.
then you need to make column classes:
.column {
display: 'flex';
# Make this a flex-column
flex-direction: 'column';
# Do not allow wrap (event though this is default)
flex-wrap: 'no-wrap';
# Fill the full width
align-items: 'stretch';
}
then within those columns you can make linear flex arrangement. You could use quarterColumn or halfColumn classes from above...... or you could edit the class like this:
.column {
display: 'flex';
flex-direction: 'column';
flex-wrap: 'no-wrap';
# Everything floats to flex-start (event though this is default)
justify-content: 'flex-start';
}
populate the columns with block level elements and end up with a pinterest style staggered grid.
<div class="outerRow">
<div class="quarter column">
<div></div>
<div></div>
<div></div>
</div>
<div class="half column">
<div></div>
<div></div>
<div></div>
</div>
<div class="quarter column">
<div></div>
<div></div>
<div></div>
</div>
</div>
or if you want them uniform:
<div class="outerRow">
<div class="quarter column">
<div class="half"></div>
<div class="half"></div>
<div class="half"></div>
</div>
<div class="half column">
<div class="half"></div>
<div class="half"></div>
<div class="half"></div>
</div>
<div class="quarter column">
<div class="half"></div>
<div class="half"></div>
<div class="half"></div>
</div>
</div>
remember the flex-grow values are ratios with each other
read https://css-tricks.com/snippets/css/a-guide-to-flexbox/
:)
Upvotes: 1