【问题标题】:Responsive two column layout reordering the blocks响应式两列布局对块进行重新排序
【发布时间】:2020-04-12 02:32:39
【问题描述】:

在移动布局中,我有六个 div,按重要性顺序依次排列。在桌面上,我想重新排序项目。在下图中,移动布局在左侧,桌面布局在右侧。

这六个项目的高度互不相关。布局应适用于任何高度。

我尝试了不同的解决方案。最容易实现桌面布局的方法是创建两个包装器 div。但这不允许在移动设备上有不同的订单。

我试图让forced horizontal wrapping in flexbox 适应垂直方向。这个answer for column breaks 几乎可以工作,但它需要一个固定的容器高度。

我搜索了有关 girds 的信息,不幸的是,it seems impossible to have more than one element in a grid area

有没有办法在不使用 Javascript 的情况下解决这个问题? (我们目前的解决方案涉及到 Javascript,但是访问者可以注意到 div 的重新排列)。

【问题讨论】:

  • 这对你有什么提示吗?弹性/顺序和列 CSS stackoverflow.com/questions/59398922/… 的混合
  • @G-Cyr 谢谢。我已经看过这样的解决方案。您链接的答案中有两个缺失的部分。 1. 两列不具有相同的宽度(解决方案正负边距) 2. 中断必须在第 3 个 div 之后。我没有找到强迫它的方法。 break-beforebreak-after 似乎不起作用。
  • 不幸的是,这是一个经典的砌体问题。 flexbox 或 css-grid 都没有提供完整的解决方案而不妥协。
  • 当然使用列包装器和显示:内容,但对此的支持并不理想。

标签: css responsive-design flexbox css-grid


【解决方案1】:
  • flex 需要一个高度来换行,(参见上一个使用 javascript 设置所需高度的 sn-p 演示)

  • grid 需要设置跨越来组合元素,

  • columnCSS 看不懂order ...

...这里可能还有float

// set a random min-height on children 
for(let e of document.getElementsByClassName('element')) {
  e.style.minHeight = Math.floor(25 + Math.random() * 72) + 'px';
}
* {
  margin: 0;
  box-sizing: border-box;
}

/* reset breakpoint to your own value */
@media screen and (min-width: 568px) {
  div {
    width: 50%;
  }
  div:nth-child(odd) {
    float: left;
    clear: left;
  }
  div:nth-child(even) {
    overflow: hidden;
  }
}

/* demo purpose */
section {
  counter-reset: div;
}
div:before {
  counter-increment: div;
  content: "Div N°"counter(div);
}
div {
  border: solid;
  display:flex;
  align-items:center;
  justify-content:center;
}
<section>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</section>

即使这样,元素之间也会出现间隙,当跟随非浮动元素时,浮动总是会换行。


masonry 脚本可以是一个选项,也可以是 javascript 来排序 height ,因此可以在 order 之外使用 flex 列。

这是 javascript 的想法:

hl = 0;
hr = 0;
nb = 0;
for (let e of document.getElementsByClassName("element")) {
  nb++;
  h = Math.floor(50 + Math.random() * 50);
  e.style.height = h + "px";
  if (nb % 2 === 0) {
    hr = hr + h;
  } else {
    hl = hl + h;
  }
  if (hl > hr) {
    document.getElementById("test").style.height = hl + "px";
  } else {
    document.getElementById("test").style.height = hr + "px";
  }
}
* {
  margin:0;
  box-sizing:border-box;
}
div {border:solid;box-sizing:border-box;width:25%;background:tomato;}
/* demo purpose */
section {
  counter-reset: div;
  background:gray;
  display:flex;
  flex-direction:column ;
  flex-wrap:wrap;
}
div:nth-child(even) {
  order:2;
  width:75%;
  background:orange
}
div:before {
  display:block;
  counter-increment: div;
  content: "Div N°"counter(div);
}
@media screen and (max-width:568px) {
  section {
    height:auto!important;/* because of js script */
    display:block;
  }
  section div:nth-child(1n) {width:auto;}
}
<section id="test">
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
  <div class="element"></div>
</section>

【讨论】:

  • 天哪,在看到这些 hacks 后,我开始欣赏更多的 flexbox 和网格,我可以想象过去的日子非常艰难。
  • 这是目前为止最好的解决方案,但演示显示它是平日。
  • @LorenzMeyer 这里是带有 flex 列的 javascript 想法,并为了在实际中绘制列 codepen.io/gc-nomade/pen/WNbprXj,您将需要检索奇数/偶数子项的偏移高度来确定要设置的高度值,并且可能处理孩子之间的边距。
  • @Wilson 用一点 js 来检索包装所需的高度,我认为 flex 是最合适的。如果您好奇,我添加了一个 sn-p,或者在这里使用 codepen:codepen.io/gc-nomade/pen/WNbprXj ;)
【解决方案2】:

结果

我使用 CSS Grids 来解决这个问题。

HTML

<div class="list">
  <div class="item one">1</div>
  <div class="item two">2</div>
  <div class="item three">3</div>
  <div class="item four">4</div>
  <div class="item five">5</div>
  <div class="item six">6</div>
</div>

CSS

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Verdana';
    color: #fff;
}


.list {
  background: gold;
  display: grid;
  grid-gap: 10px;
  text-align: center;

  grid-template-columns: repeat(1, 1fr);
  grid-auto-rows: minmax(70px, auto);
  grid-template-areas: 
        "one"
        "two"
        "three"
        "three"
        "four"
        "five"
        "six";

}

.item {
  background: gray
}

.one {
    grid-area: one;
}

.two {
    grid-area: two;
}

.three {
    grid-area: three;
}

.four {
    grid-area: four;
}

.five {
    grid-area: five;
}

.six {
    grid-area: six;
}


@media screen and (min-width: 650px) {
    .list {
      grid-template-columns: repeat(2, 1fr);
      grid-template-areas: 
        "one   two"
        "one   two"
        "one   four"
        "three four"
        "three six"
        "three six"
        "three six"
        "five  six"
        "five  .";
    }
}

【讨论】:

  • grid-template-areas 需要调整为 div 的高度。所以这不是一个可行的解决方案。
【解决方案3】:

@Paulie_D 的评论和 @G-Cyr 的回答启发了我这个解决方案:

必须对齐的六个divs 分组为两个中间&lt;div&gt;,代表桌面布局中的两列。它们是容器的孙子,而不是子。

在移动设备上,我们忽略 divs 和 display: contents; 列,并使用 flexbox 的 order: n; 重新排序孙子。在桌面上,我们使用display: inline-block; 显示两列,并以源顺序保留孙子。

for(let e of document.getElementsByClassName('item')) {
  e.style.minHeight = Math.floor(25 + Math.random() * 72) + 'px';
}
.container {
  display: flex;
  flex-direction: column;
}
.item {
  margin-bottom: 0.5em;
  text-align: center;
  background:#ddd;
  padding: 1em;
}
.left, .right{
  display: contents;
}
.item1, .item2{
  order: 1;
}
.item3, .item4{
  order: 2;
}
.item5, .item6{
  order: 3;
}

@media (min-width: 40em){
  .left, .right{
    display: inline-block;
    vertical-align: top;
  }
  .container{
    display: block;
  }
  .left{
    width: calc(67% - 0.5em);
    margin-right: 0.5em;
  }
  .right{
    width: 33%;
  }
}
<div class="container">
  <div class="left">
    <div class="item item1">1</div>
    <div class="item item3">3</div>
    <div class="item item5">5</div>
  </div><div class="right">
    <div class="item item2">2</div>
    <div class="item item4">4</div>
    <div class="item item6">6</div>
  </div>
</div>

【讨论】:

    猜你喜欢
    • 2018-11-02
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 2016-04-22
    • 2015-09-27
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    相关资源
    最近更新 更多