如何创建两列而不阻止水平行

时间:2017-11-23 13:50:46

标签: javascript html css rows

我有一个Wordpress循环的帖子。这会输出某种后列表。为方便起见,我们可以将其视为ordered-list

<ol>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ol>

每个列表项都有一个独特的,不同的高度。当给定某个设备宽度时,我希望它们并排显示,而没有&#34;行像行为&#34;。因此,每列应将下一个帖子放在其下方,如下图所示(较短项目下方没有不必要的空格):

enter image description here

使用floatflex-boxcss-griddisplay: inline-block对我不起作用。

虽然我很想避免在我的DOM中使用相同内容的两个循环,因为它对于屏幕阅读器来说是一种不良行为等。

如果没有大量的javascript,我有没有看到解决方案?互联网上充满了float: left;个例子,搜索&#34;两列&#34;,&#34;灵活列&#34;我找不到任何有用的东西。

3 个答案:

答案 0 :(得分:3)

您可以使用display: flex flex-direction: column; 。通过向父容器添加高度(或最大高度),可以使元素自动转到下一列。然后,您可以更改某个元素的order属性,将它们推入第二行。

此解决方案不是非常通用,因为它取决于内容,但它可能会让您知道如何做到这一点。

&#13;
&#13;
$('li').each(function() {
  $(this).css('height',Math.floor((Math.random() * 50) + 30)+"px");
})
&#13;
ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  max-height: 100vh;
  margin:0;
  padding:0;
}

li {
  box-sizing: border-box;
  text-align:center;
  padding: 10px;
  background: red;
  max-width: 50%;
  margin: 5px;
}
li:nth-child(2n) {
  background:green;
  order:1;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ol>
&#13;
&#13;
&#13;

重要提示(由@Marian Rick添加):

  • 此方法仅在左列大于右列时才有效
  • 您需要设置固定高度,不允许动态内容

使用javascript片段可以解决这两个问题,使解决方案保持动态。

答案 1 :(得分:1)

我有另一个奇特的答案。它使用flex-direction:coulmn和page-break-before来强制第二列中的每秒推文。这样您就不会限制完整列表的高度。 请在单独的选项卡中检查jsfiddle以检查我如何使用断点从正常列表切换到两个coulmns。

同时检查它是否在所有目标浏览器中运行:https://caniuse.com/#search=page-break-before

<section>
  <article>1</article>
  <article>2</article>
  <article>3</article>
  <article>4</article>
  <article>5</article>
  <article>6</article>
  <article>7</article>
</section>
for(int i=0; i<10; i++)
{
    vector <int> v;
    for(int j=0; j<1000000; j++) v.push_back(j);
}

答案 2 :(得分:1)

基于great idea of @TemaniAfif,我编写了一个小的,经过严格测试的jQuery代码片段,它实现了以下功能:

  • 每个项目将尽可能靠近顶部放置,关于其在容器内的位置
  • 在调整浏览器大小时,每个项目都会更新其位置
  • 它的极少和快速的javascript,而CSS完成大部分工作

整个概念仍然基于使用order: x属性将项目推向左侧或右侧的想法。

可以使用 CODEPEN DEMO

注意:浏览器支持等于flex-box的浏览器支持。

&#13;
&#13;
"use strict";

// DEMO STYLE - Should be removed
// calculate random heights for each item
$("li").each(function() {
  $(this).css("height", Math.floor(Math.random() * 300 + 2) + "px");
});


///////////////////////
// Calculate columns
//
// 1. loop through each item.
// 2. first get the height of item
// 3. than check which column is shorter
// 4. if left column is shorter or equal, keep item on the left side
// 5. if right column is shorter, push this item to the right side
// 6. check which side will be higher
// 7. if left column is higher, assign height of column to parent container
// 8. if right column is higher, create a margin-bottom equal of the column offset and assign it to the left column
// calculation is finished. test it.

// finally add the height of the bigger column to the div
// if its the left column, assign the height of the right
var container = $("ol");
var items = container.find("li");
var breakPoint = 768; // if equal or bigger, the calculation will be fired

var calcPositions = function calcPositions() {

  // quit function if its a mobile device
  if ($(window).width() < breakPoint) return;

  // reset margin of left column item
  container.find("li.push-left").last().css("margin-bottom", "15px");

  var leftColumnHeight = 0;
  var rightColumnHeight = 0;

  // 1. loop through each item
  items.each(function(i, e) {
  
    // 2. get height of item
    var height = $(this).outerHeight(true);

    // 3. check which column is shorter
    if (leftColumnHeight <= rightColumnHeight) {
    
      // 4. if left column is shorter or equal, keep item on the left side
      leftColumnHeight += height;
      $(this).removeClass("push-right").addClass("push-left");
      return; // skip rest and continue with next item
    }

    // 5. if right column is shorter, push this item to the right side
    // using .push-right { order: 5 } inside css
    rightColumnHeight += height;
    $(this).removeClass("push-left").addClass("push-right");
  });

  // 6. check which side will be higher
  if (leftColumnHeight >= rightColumnHeight) {
  
    // 7. if left column is higher, assign height of column to parent container
    container.height(leftColumnHeight);
    return; // end of function
  }

  // 8. if right column is higher, create a margin-bottom equal of the column offset and assign it to the left column
  // otherwhise the second object can be displayed at the bottom of the left column

  // get offset of columns
  var columnOffset = rightColumnHeight - leftColumnHeight;

  // assign offset to last element of left sidebar
  container.find("li.push-left").last().css("margin-bottom", columnOffset + "px");

  // assign height to container
  container.height(rightColumnHeight);
};

// calculate initially
calcPositions();

// calculate on resize
$(window).resize(function() {
  calcPositions();
});
&#13;
/* functional classes needed for this grid */


/* keep this breakpoint in sync with "breakPoint" inside the javascript */

@media (min-width: 768px) {
  ol {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
  }
  
  li {
    max-width: 50%;
  }
  
  li.push-right {
    order: 1;
    margin-right: 0;
  }
}


/* demo styles that can be removed */

* {
  box-sizing: border-box;
}

ol {
  padding: 0;
  max-width: 800px;
  width: 90%;
  margin: 0 auto;
}

li {
  background: red;
  margin-bottom: 15px;
}

@media (min-width: 768px) {
  li {
    max-width: 49%;
    margin-right: 2%;
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Breakpoint is set to >=768px for two columns:</p>

<ol>
  <li>Lorem.</li>
  <li>Asperiores!</li>
  <li>Illum!</li>
  <li>Perspiciatis!</li>
  <li>Eius.</li>
  <li>Est.</li>
  <li>Quisquam.</li>
  <li>Eaque!</li>
  <li>Vero?</li>
  <li>Iste?</li>
  <li>Provident?</li>
  <li>Ipsum.</li>
</ol>
&#13;
&#13;
&#13;