具有一致边距和对齐的Flexbox图块布局

时间:2015-06-20 04:10:06

标签: html css layout flexbox

我们如何实现以下布局:

enter image description here

符合以下条件:

  1. 每行的瓷砖高度应与行中的最高元素相等

  2. 行中的最后一个图块应与父容器齐平(无间隙)

  3. 瓷砖可以是不同的宽度比(3倍三分之一或三分之一+三分之二等)

  4. 瓷砖的排序未知

  5. 没有网格框架

  6. 仅限现代浏览器

  7. 以及以下标记:

    <div class="tile-wrapper">
      <div class="tile-container">
        <div class="tile third">1/3</div>
        <div class="tile third">1/3</div>
        <div class="tile third">1/3</div>
        <div class="tile two-thirds">2/3</div>
        <div class="tile third">1/3</div>
        <div class="tile sixth">1/6</div>
        <div class="tile sixth">1/6</div>
        <div class="tile third">1/3</div>
        <div class="tile sixth">1/6</div>
        <div class="tile sixth">1/6</div>
      </div>
    </div>
    

2 个答案:

答案 0 :(得分:5)

这是一种越来越常见的布局,使用flexbox和一些聪明的容器标记可以相对容易地实现。

平铺布局的一个常见问题是在多行中保持不同大小的切片之间的一致间距和对齐。假设我们希望30px边距分隔所有切片,我们只需在所有切片上设置margin-right: 30px,然后使用第n个类型选择器移除最后一个切片的margin-right排。

但是,当瓷砖的相对尺寸和顺序未知时,这是不可能的。例如,三分之一区块旁边的三分之二区块将不符合将最后一个区块的边距移除为由三个三分之一区块组成的行所需的相同的第n个类型选择器规则。 / p>

巧妙地解决这个问题的方法是将 absord 最右边的瓷砖边距改为父容器的宽度。我们可以通过使用overflow: hidden将最外层div的宽度设置为所需宽度(在本例中为90%),然后将内部容器的宽度设置为100% plus 瓷砖边缘的宽度; width: calc(100% + 30px)。这样,无论哪个瓷砖位于该行的最右侧位置,瓷砖将与其容器的边缘齐平。

为确保瓷砖始终符合要求,我们将其flex-basis设置为我们希望它们占据减去的行宽的比例瓷砖边距; .third { flex: 0 0 calc(33.33% - 30px); /* for a 1/3 tile */}

像这样:

* {
  box-sizing: border-box;
}
.tile-wrapper {
  display: block;
  position: relative;
  width: 90%;
  margin: 0 auto;
  overflow: hidden;
}
.tile-container {
  display: flex;
  position: relative;
  width: calc(100% + 30px);
  flex-wrap: wrap;
}
.tile {
  display: inline-block;
  margin-right: 30px;
  margin-bottom: 30px;
  min-height: 200px;
  line-height: 199px;
  text-align: center;
  border: 1px solid black;
}
.two-thirds {
  flex: 0 0 calc(66.66% - 30px);
}
.third {
  flex: 0 0 calc(33.33% - 30px);
}
.sixth {
  flex: 0 0 calc(16.66% - 30px);
}

Here's a Fiddle

注意:这仅适用于现代浏览器(Chrome,Safari,FF,IE11 +)。 IE11中还存在一个已知错误,要求您使用长手flex-basis样式属性将其设置为calc()值。

答案 1 :(得分:0)

你可以试试这个:

  • 为每个项目设置flex-basis: 0和所需的flex-grow因素。
  • 强行换行将伪元素放在正确的位置。
  • 为所有弹性项设置一些余量。
  • 为flex包装器设置相同金额的负边距。

.tile-wrapper {
  border: 1px solid #000;
}
.tile-container {
  display: flex; /* Magic begins */
  flex-wrap: wrap; /* Multiline */
  margin: -5px; /* Neutralize margins at the edges */
}
.tile {
  min-height: 50px; /* Just an example */
  margin: 5px;
  border: 1px solid #979797;
  background: #d8d8d8;
}
.sixth{ flex: 1; } /* 1/6 * 6 */
.third{ flex: 2; } /* 1/3 * 6 */
.two-thirds{ flex: 4; } /* 2/3 * 6 */
.tile-container::before, .tile-container::after {
  content: ''; /* Enable the pseudo-element */
  order: 1; /* Place it at the appropiate place */
  width: 100%; /* Force line break */
}
.tile-container > :nth-child(n+4) { order: 1; }
.tile-container > :nth-child(n+6) { order: 2; }
<div class="tile-wrapper">
  <div class="tile-container">
    <div class="tile third">1/3</div>
    <div class="tile third">1/3</div>
    <div class="tile third">1/3</div>
    <div class="tile two-thirds">2/3</div>
    <div class="tile third">1/3</div>
    <div class="tile sixth">1/6</div>
    <div class="tile sixth">1/6</div>
    <div class="tile third">1/3</div>
    <div class="tile sixth">1/6</div>
    <div class="tile sixth">1/6</div>
  </div>
</div>