如何创建基于flexbox的网格系统?

时间:2019-02-08 23:01:06

标签: css css3 sass flexbox

出于学习目的,我尝试创建基于flexbox的网格系统,但是在使用它创建东西后发现了一些问题:当总列占据100%的空间时,最后一列转到下一行(容器是flex-flow:行换行;),但是当它们不是100%(例如,一列为30%,另一列为65%)时,它们在同一行上...然后我发现这与边距有关,但仍然我无法解决。

我现在的疑问是:列宽使用什么?弹性基础?宽度

如何解决要解决的边距问题?我已经在github项目中看到一个使用“ gap”之类的东西,但是我仍然不太了解它是如何工作的...

我尝试将calc()属性与10px的“-$ gap”一起添加,但是我仍然无法以应有的方式生成网格。

我以前的代码是这样的:

.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%;
        }
    }
}

编辑:我设法通过以下方式保留了它所需的方式:

$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});
        }
    }
    // ....

2 个答案:

答案 0 :(得分:1)

FLexbox是线性的,而Grid是二维的。有很多方法可以解决此问题。但您需要使用flex-wrap: no-wrap

我先定义一个弹性行。

.outerRow {
    display: 'flex';
    # Do not allow wrap (event though this is default)
    flex-wrap: 'no-wrap';
    # Fill the full height
    align-items: 'stretch';
}

现在您的专栏。如果您希望两列为25%,一列为50%,请执行以下操作:

.quarter {
    flex-grow: 1;
}
.half {
    flex-grow: 2;
}

注意它们是比率。

然后您需要创建列类:

.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';
}

然后在这些列中可以进行线性弹性排列。您可以从上方使用QuarterColumn或halfColumn类……,也可以像这样编辑该类:

.column {
    display: 'flex';
    flex-direction: 'column';
    flex-wrap: 'no-wrap';
    # Everything floats to flex-start (event though this is default)
    justify-content: 'flex-start';
}

使用块级元素填充列,并以pinterest风格的交错网格结束。

<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>

或者如果您希望它们统一:

<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>

记住弹性增长值是彼此的比率

阅读https://css-tricks.com/snippets/css/a-guide-to-flexbox/

:)

答案 1 :(得分:0)

您可以简单地使用添加为边距的间隙值来减小宽度。诀窍是考虑以下事实:间隙仅在内部,因此您需要使用-1来正确计算宽度:

.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)}));
        }
    }
}

已编译完整代码:

.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>