两列布局,无需 JavaScript 即可重新排序项目

Two-column layout with ability to reorder items without JavaScript

有没有办法通过媒体查询将 2 列布局转换为 1 列布局?

2 列布局的条件:

  1. 项目应该在列中一个接一个地流动
  2. 列中的项目将具有不同的高度
  3. 项目位置(顺序)可以由html标记元素位置
  4. 强加

1 列布局的条件:

  1. 项目应该一个接一个地流动
  2. 列中的项目将具有不同的高度
  3. 项目位置 (!) 不能由 html 标记强加(应该是 控制 css)

我一直在考虑为列使用两个单独的容器 - 但是当布局变为 1 列时,该构造阻止了我在列之间重新排序(混合)元素。我似乎应该将所有元素放在一个容器中 - 然后对于 1 列布局 flex 可以用于重新排序,但是在这种情况下如何实现 2 列布局?

要模拟媒体查询行为,请从主容器中删除 class "one-column"。

<div id="container" class="one-column"> -> <div id="container" class="">

在这个概念中,主要问题是列中的项目(2 列布局)不是直接一个接一个地流动(右列中的项目之间存在间隙)。

这是我到目前为止所取得的成就:

* {
  box-sizing: border-box;
}
div {
  width: 100%;
  height: 100px;
  float: left;
}
#container.one-column {
  display: flex;
  flex-direction: column;
  height: auto;
}
#container {
  display: block;
}
.col1 {
  width: 60%;
  background-color: red;
  height:300px;
  float: left;
}
.col2 {
  width: 40%;
  background-color: blue;
  border: 1px solid white;
  float: right;
}
.one-column > div {
  width: 100%;
}
<div id="container" class="one-column">
  <div class="col1" style="order:2;">
    ONE
  </div>
  <div class="col2" style="order:1;">
    TWO
  </div>
  <div class="col1" style="order:4;">
    THREE
  </div>  
  <div class="col2" style="order:3;">
    FOUR
  </div>
</div>

JSFiddle:https://jsfiddle.net/3b6htt1d/40/

你的 2 列布局也应该使用 flex。

唯一真正的问题是在您希望的位置强制换行。

最好的方法是为容器设置一个确定的高度。在这种情况下,可以使用伪元素来强制换行:

* {
  box-sizing: border-box;
}
div {
  width: 100%;
  height: 100px;
  border: 1px solid white;
}
.container {
  display: flex;
  flex-direction: column;
  height: auto;
  margin-top: 5px;
}
.col1 {
  width: 60%;
  background-color: red;
  height:300px;
}
.col2 {
  width: 40%;
  background-color: blue;
}
.one-column > div {
  width: 100%;
}
.two-column {
    flex-wrap: wrap;
    max-height: 800px;
}
.two-column:after {
    content: "";
    width: 10px;
    height: 10px;
    background-color: yellow;
    order: 2;
    margin-top: 1000px;
}
.two-column .col1 {
    order: 1;
}
.two-column .col2 {
    order: 3;
}
<div class="container two-column">
  <div class="col1">
    ONE
  </div>
  <div class="col2">
    TWO
  </div>
  <div class="col1">
    THREE
  </div>  
  <div class="col2">
    FOUR
  </div>
</div>
<div class="container one-column">
  <div class="col1">
    ONE
  </div>
  <div class="col2">
    TWO
  </div>
  <div class="col1">
    THREE
  </div>  
  <div class="col2">
    FOUR
  </div>
</div>

Conditions for 2 column layout:

  1. items should flow one after another within columns
  2. items within columns will have different heights
  3. item position (order) can be imposed by html markup element position

这正是 CSS 列所做的。

Conditions for 1 column layout:

  1. items should flow one after another
  2. items within columns will have different heights
  3. item position (!) cannot be imposed by html markup (should be controlled over css)

这正是 Flexbox 和 column 方向可以做的事情。


因此,如果将两者结合起来,对于 2 列,它们将如左图示例所示从上到下流动,对于 1 列,您可以使用 order 控制它们的位置。

有了这个,您可以避免固定高度并获得 dynamic/flexible 尺寸的物品。

Updated fiddle

堆栈片段

* {
  box-sizing: border-box;
}
div {
  width: 100%;
  height: 100px;
}
#container.one-column {
  display: flex;
  flex-direction: column;
  height: auto;
}
.col1 {
  width: 60%;
  background-color: red;
  height:300px;
}
.col2 {
  width: 40%;
  background-color: blue;
  border: 1px solid white;
}
.one-column > div {
  width: 100%;
}

@media (min-width: 500px) {
  #container.one-column {
    display: block;
    columns: 2;
  }
  #container.one-column > div {
    -webkit-column-break-inside: avoid;
    page-break-inside: avoid;
    break-inside: avoid;
  }
  .zcol1 ~ .col1 {
    background-color: yellow;
    height:100px;
  }
}
<div id="container" class="one-column">
  <div class="col1" style="order:2;">
    ONE
  </div>
  <div class="col2" style="order:1;">
    TWO
  </div>
  <div class="col1" style="order:4;">
    THREE
  </div>  
  <div class="col2" style="order:3;">
    FOUR
  </div>
</div>


这是我的另一个答案,这可能是另一种选择,将 Flexbox 与 float 结合起来。


根据评论更新

这是一个结合了 Flexbox 和 float 的版本,它会生成您的屏幕截图显示的布局: