【问题标题】:Two-column layout with ability to reorder items without JavaScript两列布局,无需 JavaScript 即可重新排序项目
【发布时间】:2018-08-04 17:30:34
【问题描述】:

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

2列布局的条件:

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

1列布局的条件:

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

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

要模拟媒体查询行为,请从主容器中删除“单列”类。

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

【问题讨论】:

  • 是的。这是可能的。你试过自己编码吗?如果是这样,请发布您的代码。否则,您的问题可能会被关闭,因为 Stack Overflow 不是免费的代码编写服务。
  • 您真的希望 a3 在单列布局中显示在 a2 上方吗?还是你的插图有错误?
  • @TylerH 更重要的是能够将 b* 项目放在 a* 项目之间的任何位置。更改 a* 位置不太重要,但它会很好。
  • @ITMan 我有点困惑,你想要改变位置是什么?听起来您希望它动态更改(否则您只需编写代码以将其准确定位为您想要的位置),但我看不出您在哪里指定在一种情况下,B2 是给定的顺序,然后在另一种情况下,B2 的顺序不同(例如)。
  • @TylerH 我想为特定分辨率(移动)设置/更改项目顺序。对于“deskop”,我有 2 列布局 - 让我们假设项目顺序来自 html 元素顺序。但是当我更改为“移动”时,我有 1 列布局,并且项目的显示顺序应该与 html 标记不同。

标签: css flexbox media-queries css-grid


【解决方案1】:

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

【讨论】:

  • 乍一看,这似乎是正确的解决方案。我必须详细检查此布局行为。感谢您的帮助。
  • 用那个伪元素真是个聪明的把戏!据我了解,如果没有其他选择,我也可以使用 javascript 计算伪高度/边距?
  • 确实,您需要在运行时或事先计算的是容器高度。伪元素的高度只需要大于此值,即可强制换行。
【解决方案2】:

2列布局的条件:

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

这正是 CSS Columns 所做的。

1列布局的条件:

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

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


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

这样您就可以避免固定高度并获得动态/灵活尺寸的项目。

Updated fiddle

堆栈sn-p

* {
  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 的版本,它会生成屏幕截图显示的布局:

【讨论】:

  • 哇,更新解决方案真是太好了。这正是我所要求的!
猜你喜欢
  • 2016-12-20
  • 1970-01-01
  • 2020-04-12
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2010-11-05
相关资源
最近更新 更多