我有一个Wordpress循环的帖子。这会输出某种后列表。为方便起见,我们可以将其视为ordered-list
:
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
每个列表项都有一个独特的,不同的高度。当给定某个设备宽度时,我希望它们并排显示,而没有&#34;行像行为&#34;。因此,每列应将下一个帖子放在其下方,如下图所示(较短项目下方没有不必要的空格):
使用float
,flex-box
和css-grid
或display: inline-block
对我不起作用。
虽然我很想避免在我的DOM中使用相同内容的两个循环,因为它对于屏幕阅读器来说是一种不良行为等。
如果没有大量的javascript,我有没有看到解决方案?互联网上充满了float: left;
个例子,搜索&#34;两列&#34;,&#34;灵活列&#34;我找不到任何有用的东西。
答案 0 :(得分:3)
您可以使用display: flex
和 flex-direction: column;
。通过向父容器添加高度(或最大高度),可以使元素自动转到下一列。然后,您可以更改某个元素的order
属性,将它们推入第二行。
此解决方案不是非常通用,因为它取决于内容,但它可能会让您知道如何做到这一点。
$('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;
重要提示(由@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代码片段,它实现了以下功能:
整个概念仍然基于使用order: x
属性将项目推向左侧或右侧的想法。
可以使用 CODEPEN DEMO 。
注意:浏览器支持等于flex-box的浏览器支持。
"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;