Flexbox平铺布局具有一致的边距和对齐

mon*_*ers 4 html css layout flexbox

我们如何实现以下布局:

在此输入图像描述

满足以下条件:

  1. 每行的切片高度应与行中的最高元素相等

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

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

  4. 瓷砖的排序是未知的

  5. 没有网格框架

  6. 仅限现代浏览器

以下标记:

<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>
Run Code Online (Sandbox Code Playgroud)

Mic*_*l_B 6

从问题来看:

  1. 无网格框架

这个问题是在 2015 年发布的,当时 CSS 网格布局的浏览器支持很弱。

自2017年起,所有主流浏览器都支持网格布局

因此,假设发布此要求是出于浏览器兼容性的目的,我将忽略它并提供当今浏览器可以轻松支持的最佳(基于网格)解决方案。

body {
  margin: 0;
}

.tile-wrapper {}

.tile-container {
  display: grid;
  grid-template-rows: auto auto auto;
  grid-template-columns: repeat(6, 1fr);
  grid-gap: 30px;
}

.sixth {
  grid-column: span 1;
}

.third {
  grid-column: span 2;
}

.two-thirds {
  grid-column: span 4;
}

/* demo only */
.tile {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: lightgray;
  border: 1px solid gray;
}
Run Code Online (Sandbox Code Playgroud)
<div class="tile-wrapper">
  <div class="tile-container">
    <div class="tile third">1/3</div>
    <div class="tile third">1/3<br>
    text<br>text<br>text</div>
    <div class="tile third">1/3</div>
    <div class="tile two-thirds">2/3</div>
    <div class="tile third">1/3<br>
    text<br>text<br>text<br>
    text<br>text<br>text<br>
    text<br>text<br>text</div>
    <div class="tile sixth">1/6<br>
    text<br>text<br>text<br>
    text<br>text</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>
Run Code Online (Sandbox Code Playgroud)

从问题来看:

具备以下条件:

  1. 每行的图块的高度应等于该行中最高元素的高度。查看

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

  3. 瓷砖可以具有不同的宽度比(3乘以三分之一或三分之一+三分之二等)。查看

  4. 瓷砖的顺序未知。好的

  5. 没有网格框架。不适用(参见上面的注释)

  6. 仅限现代浏览器。查看


mon*_*ers 5

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

平铺布局的常见问题是在多行的不同尺寸的贴片之间保持一致的间距和对齐.假设我们想要一个30px分隔所有图块的边距,我们可以简单地设置margin-right: 30px所有图块,然后使用第n个类型选择器来删除margin-right行中最后一个图块.

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

巧妙的解决方法是将最右边的tile的边距压缩到父容器的宽度.我们可以通过将最外面的div的宽度设置为所需的宽度(在这种情况下为90%)overflow: hidden,然后将内部容器的宽度设置为100%加上平铺边距的宽度; width: calc(100% + 30px).这样,无论哪个瓷砖位于该行的最右侧位置,瓷砖将与其容器的边缘齐平.

为了保证瓷砖则总是适合根据需要,我们设置了柔性基础是比例的行宽的,我们希望他们占据减去瓦保证金;.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);
}
Run Code Online (Sandbox Code Playgroud)

这是一个小提琴

注意:这仅适用于现代浏览器(Chrome,Safari,FF,IE11 +).IE11中还存在一个已知的错误,它要求您使用long-hand flex-basisstyle属性将其设置为calc()值.