【问题标题】:Creating a flexbox grid with gutters and fixed widths创建一个带有间距和固定宽度的 flexbox 网格
【发布时间】:2019-06-18 23:46:37
【问题描述】:

我需要创建一个有 3 行的网格,每行有 2 列

  • 第一行列应为 40% - 60%
  • 第二行两列都应该是 50%
  • 第三行第一列应为 60%,第二列应为 40%。

列之间应该有一个10px 间隔,对于小于992px 的屏幕尺寸,所有列都应该是100%,同时仍然有一个10px“间隔”。

除最后一列外,每 100% 列的下方应为 10 像素间距)。我正在努力研究如何以最好的方式做到这一点。

HTML:

<div class="flexrow">
   <div class="col-1"></div>
   <div class="col-2"></div>
   <div class="col-3"></div>
   <div class="col-4"></div>
   <div class="col-5"></div>
   <div class="col-6"></div>
</div>

CSS:

.flexrow{
   display: flex;
   align-items:stretch;
   flex-wrap: wrap;
}

我尝试了边距,但无法使其正常工作。

【问题讨论】:

  • 使用边距出了什么问题?它可能有助于显示您尝试了什么以及您卡在哪里。
  • 它在最底部创建了一个边距。我也不明白设置列宽的最佳方法是什么。

标签: css flexbox


【解决方案1】:

Flexbox 使用 justify-content 的值 space-between 使这变得非常容易:

.flexrow {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

这样可以确保在尺寸正确时物品会粘在容器的外边缘。

通过将弹性项目的宽度设置为小于总宽度的 100% 来创建装订线。这里我们需要 2 列,因此您可以将项目的宽度设置为 50% 减去足以弥补装订线宽度:

.flexcol {
  width: calc(50% - 5px); // 50% minus 5px for each column, with 2 columns that's a 10px gutter space between the two columns.
  margin-bottom: 10px; //space between the rows, remove if you dont want that.
}

现在要设置第一行和第三行,只需相应地更改宽度即可:

.col-1,
.col-6 {
  width: calc(40% - 5px); // here's the 40% ones
}

.col-2,
.col-5 {
  width: calc(60% - 5px); // and the 60% ones
}

对于 992px 的 100% 变化,只需添加一个媒体查询并更新必要的值:

@media (max-width: 992px) {
  .flexcol {
    width: 100%; // 100% width, no margin or anything to deal with because of the space-between layout approach
  }
  .col-5 {
    margin-bottom: 10px; // add this so the 5th and 6th items have space between them when 100% wide
  }
}

.flexrow {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  background: #efefef;
}

.flexcol {
  width: calc(50% - 5px);
  margin-bottom: 10px;
  
  /* just for visibility */
  border: 1px solid red;
  padding: 20px;
  background: #fff;
  box-sizing: border-box;
}

.col-1,
.col-6 {
  width: calc(40% - 5px);
}

.col-2,
.col-5 {
  width: calc(60% - 5px);
}

.col-5,
.col-6 {
  margin-bottom: 0;
}

@media (max-width: 992px) {
  .flexcol {
    width: 100%;
  }
  .col-5 {
    margin-bottom: 10px;
  }
}
<div class="flexrow">
  <div class="flexcol col-1">THING 1</div>
  <div class="flexcol col-2">THING 2</div>
  <div class="flexcol col-3">THING 3</div>
  <div class="flexcol col-4">THING 4</div>
  <div class="flexcol col-5">THING 5</div>
  <div class="flexcol col-6">THING 6</div>
</div>

【讨论】:

  • 是的,这确实有效。您的解决方案和上面的网格都实现了相同的效果。现在我不确定什么对浏览器兼容性更好。
  • Flexbox 支持:caniuse.com/#search=flex。网格支持:caniuse.com/#search=grid。很接近了,flexbox 有更好的支持。
【解决方案2】:

由于各种原因,这项工作比 Flexbox 更适合 CSS Grid。

首先,让排水沟在 Grid 中工作很简单。您可以使用 grid-gap 属性,该属性在 flexbox 中尚不可用。

其次,您请求的“列”并不是真正的列。一列从上到下具有相同的宽度。您要求masonry layout,它允许内容项跨越多个列和行。

同样,使用 CSS Grid 完成这项任务要容易得多。

这是一种可能适合您的解决方案(包括媒体查询):

jsFiddle demo

.grid-container {
  display: grid;
  grid-auto-columns: 1fr;
  width: 500px;
  grid-auto-rows: 50px;
  grid-gap: 10px;
}

.col-1 {
  grid-column: 1 / span 4;
  grid-row: 1;
}

.col-2 {
  grid-column: 5 / span 6;
  grid-row: 1;
}

.col-3 {
  grid-column: 1 / span 5;
  grid-row: 2;
}

.col-4 {
  grid-column: 6 / span 5;
  grid-row: 2;
}

.col-5 {
  grid-column: 1 / span 6;
  grid-row: 3;
}

.col-6 {
  grid-column: 7 / span 4;
  grid-row: 3;
}

@media ( max-width: 992px ) {
  .grid-container>div {
    grid-column: 1;
    grid-row: auto;
  }
}

/* non-essential demo styles */

.grid-container {
  border: 1px solid black;
  background-color: lightgray;
}
.grid-container > div {
  font-size: 1.3em;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}
.grid-container > div:nth-child(odd) {
  background-color: green;
}
.grid-container > div:nth-child(even) {
  background-color: orangered;
}
<div class="grid-container">
  <div class="col-1">40%</div>
  <div class="col-2">60%</div>
  <div class="col-3">50%</div>
  <div class="col-4">50%</div>
  <div class="col-5">60%</div>
  <div class="col-6">40%</div>
</div>

在上面的布局中,您创建的每一列的宽度为1fr。这意味着每一列都会平均分配容器中的可用空间。

您现在可以跨列创建具有所需宽度的网格区域。

例如,如果您希望“列”的宽度为 60%,请告诉网格项跨越六列 (span 6)。

1fr 的另一个好处是,它会在所有固定宽度(例如排水沟)都被计入行长之后应用。这意味着您不需要对十列进行任何计算以适应。

【讨论】:

  • Flexbox 实际上处理得非常优雅,刚刚发布了我的 flexbox 答案。
  • 是的,你让它与 flexbox 一起工作。但我不会称其为优雅,因为减小项目的大小以创建排水沟是一种黑客行为。使用gap 属性的好处是可以自然地创建排水沟。希望这个功能很快可以用于 flexbox。 @BugsArePeopleToo
  • @Michael_B 谢谢,我读过关于 Grid 的文章,但似乎浏览器支持不是 100%?例如,它不适用于 IE。
  • 但是,当我需要其他大小的列,例如宽度为 33.333% 或任何其他小数时,它是如何工作的?
  • 使用 CSS Grid 更改列长度实际上非常简单。这就是该模块的设计目的。 jsfiddle.net/0oyap8fm
【解决方案3】:

我只会使用 flexbox (https://yoksel.github.io/flex-cheatsheet/) 和一些边距来做到这一点,因为我认为没有“完美”或首选的方式来做到这一点。

确保您也在全屏中检查 sn-p 以查看列的百分比分离。

/*




I need to create a grid that has 3 rows, each row has 2 columns.

    First row columns should be 40% - 60%
    Second row both columns should be 50%
    Third row first column should be 60%, second column 40%.

The columns should have a 10px gutter in between the columns, and for screen sizes smaller then 992px all columns should be 100% while still having a 10px "gutter".

(Underneath every 100% column except the last one should be 10px gutter). I am struggling on how to do this the best way.

*/
.row {
  display: flex;
  flex-flow: row nowrap;
  background-color: white;
  height: 100px;
}

.item1 {
  flex-basis: 40%;
  margin-right: 5px;
  background-color: red;
}

.item2 {
  flex-basis: 60%;
  margin-left: 5px;
  background-color: yellow;
}

.item3 {
  margin-right: 5px;
  flex-basis: 50%;
  background-color: blue;
}

.item4 {
  margin-left: 5px;
  flex-basis: 50%;
  background-color: pink;
}

.item5 {
  margin-right: 5px;
  flex-basis: 60%;
  background-color: grey;
}

.item6 {
  margin-left: 5px;
  flex-basis: 40%;
  background-color: brown;
}

@media(max-width: 992px) {
  .row {
    display: flex;
    flex-flow: row wrap;
    background-color: white;
    height: 100px;
  }
  .item1 {
    flex-basis: 100%;
    margin-right: 0px;
    background-color: red;
        margin-bottom: 10px;
  }
  .item2 {
    flex-basis: 100%;
    margin-left: 0px;
    background-color: yellow;
        margin-bottom: 10px;
  }
  .item3 {
    margin-right: 0px;
    flex-basis: 100%;
    background-color: blue;
        margin-bottom: 10px;
  }
  .item4 {
    margin-left: 0px;
    flex-basis: 100%;
    background-color: pink;
        margin-bottom: 10px;
  }
  .item5 {
    margin-right: 0px;
    flex-basis: 100%;
    background-color: grey;
        margin-bottom: 10px;
  }
  .item6 {
    margin-left: 0px;
    flex-basis: 100%;
    background-color: brown;
  }
}
<div class="row">
  <div class="item1"></div>
  <div class="item2"></div>
</div>
<div class="row">
  <div class="item3"></div>
  <div class="item4"></div>
</div>
<div class="row">
  <div class="item5"></div>
  <div class="item6"></div>
</div>

【讨论】:

    猜你喜欢
    • 2016-04-13
    • 2020-11-16
    • 2018-10-22
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2017-10-27
    • 1970-01-01
    相关资源
    最近更新 更多