我正在尝试使用css网格布局创建砌体布局。网格中的所有项目都具有可变高度。我不知道会有什么东西。所以我不能为每个项目定义grid-row
。是否可以在列中的上一个结尾之后立即启动每个新项目?
我正在尝试的代码:
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, 330px);
align-items: flex-start;
grid-column-gap: 10px;
grid-row-gap: 50px;
}
.item {
background: black;
border-radius: 5px;
}
<div class="wrapper">
<div class="item" style="height:50px"></div>
<div class="item" style="height:100px"></div>
<div class="item" style="height:30px"></div>
<div class="item" style="height:90px"></div>
<div class="item" style="height:80px"></div>
<div class="item" style="height:50px"></div>
<div class="item" style="height:70px"></div>
<div class="item" style="height:40px"></div>
</div>
答案 0 :(得分:1)
在您的问题中,您将分别设置每个项目的高度。如果您愿意这样做,那么可以通过网格轻松实现砌体布局。
而不是为每个项目集l = [1, 2, 3, 4, 5]
def generator(l, batch_size=2):
while 1:
for i in range(0, len(l), batch_size):
batch = l[i:(i + batch_size)]
if len(batch) < batch_size:
batch.extend(l[0: batch_size - len(batch)])
yield batch
>> gen = generator(l, batch_size=2)
>> next(gen) # [1, 2]
>> next(gen) # [3, 4]
>> next(gen) # [5, 1]
>> next(gen) # [1, 2] << want [2, 3] instead
设置高度,以便每个项目跨越一定数量的行。
grid-row-end
项目的高度将取决于您为网格设置的 <div class="item" style="grid-row-end: span 5"></div>
和grid-auto-rows
的值。
我在这里制作了一个Codepen:https://codepen.io/andybarefoot/pen/NaprOB
如果您不想为每个项目单独设置grid-row-gap
值,则可以使用一些JavaScript动态执行此操作。我在每个项目中放置了另一个“容器”div,并测量此容器的高度以计算项目需要跨越多少行。我在页面加载时执行此操作,并在加载任何图像时再次为每个项目执行此操作(因为内容的高度将更改)。如果将此方法与响应式布局结合使用,则还应重新计算页面调整大小,因为列的宽度可能已更改,这将影响内容的高度。
以下是响应列调整大小的完整示例:https://codepen.io/andybarefoot/pen/QMeZda
如果你有宽度可变的物品,你仍然可以达到类似的效果,但是网格的包装不是很完美,可以改变物品顺序以优化包装。
我在Media上写了一篇关于这种方法的博客,如果感兴趣的话:使用CSS Grid的砌体样式布局
答案 1 :(得分:0)
这是仅使用CSS创建Masonry布局的一种方法。
*,
*:before,
*:after {
box-sizing: border-box !important;
}
article {
-moz-column-width: 13em;
-webkit-column-width: 13em;
-moz-column-gap: 1em;
-webkit-column-gap: 1em;
}
section {
display: inline-block;
margin: 0.25rem;
padding: 1rem;
width: 100%;
background: #efefef;
}
p {
margin: 1rem 0;
}
body {
line-height: 1.25;
}
<article>
<section>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error aliquid reprehenderit expedita odio beatae est.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis quaerat suscipit ad.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nihil alias amet dolores fuga totam sequi a cupiditate ipsa voluptas id facilis nobis.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem ut debitis dolorum earum expedita eveniet voluptatem quibusdam facere eos numquam commodi ad iusto laboriosam rerum aliquam.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat architecto quis tenetur fugiat veniam iste molestiae fuga labore!</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit accusamus tempore at porro officia rerum est impedit ea ipsa tenetur. Labore libero hic error sunt laborum expedita.</p>
</section>
<section>
<p>Lorem ipsum dolor sit.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima asperiores eveniet vero velit eligendi aliquid in.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus dolorem maxime minima animi cum.</p>
</section>
</article>
注意:我没有制作代码,我发现它做了一些小改编, 可以找到原始代码here。
请注意,正如Zen所指出的那样:
[...]项目布局从上到下,从左到右, 而人们通常期望的是(文化假设可以理解) 从左到右,从上到下布局。这是基于CSS3列的常见建议的showstopper。
答案 2 :(得分:0)
您可以动态设置span
的{{1}}值(使用一些JS,就像下面示例中基于Codepen experiment的那个)并使用grid-row-end
dense
的关键字:
grid-auto-placement
const gridStyles = getComputedStyle(document.querySelector('.wrapper',null));
const rowHeight = parseInt(gridStyles.getPropertyValue('--grid-row-height'));
const gap = parseInt(gridStyles.getPropertyValue('--grid-gutter'));;
let makeGrid = function() {
let items = document.querySelectorAll('.item');
for (let i=0, item; item = items[i]; i++) {
// take an item away from grid to measure it
item.classList.add('is-being-measured');
let height = item.offsetHeight;
// calcylate the row span
let rowSpan = Math.ceil((height + gap)/(rowHeight + gap));
// set the span value for grid-row-end
item.style.gridRowEnd = 'span '+rowSpan;
// return the item into the grid
item.classList.remove('is-being-measured');
}
}
window.addEventListener('load', makeGrid);
window.addEventListener('resize', () => {
clearTimeout(makeGrid.resizeTimer);
makeGrid.resizeTimer = setTimeout(makeGrid, 50);
});
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, 330px);
--grid-gutter: 10px;
grid-gap: var(--grid-gutter);
--grid-row-height: 10px;
grid-auto-rows: var(--grid-row-height);
grid-auto-flow: row dense;
position: relative;
}
.item {
background: black;
color: white;
border-radius: 5px;
}
.item.is-being-measured {
/* temporary styles for measuring grid items */
position: absolute;
width: 330px;
top: 0;
left: 0;
}
.item > * { margin-left: 20px; }
答案 3 :(得分:-1)
您可以使用column
完成此操作。
.wrapper {
column-gap: 10px;
column-count: 4;
}
.item {
display: inline-block;
background: #000;
width: 100%;
border-radius: 3px;
}
您似乎尝试使用flex
和grid
的组合,这可能会令人感到困惑。据我所知,flex是相对于页面上其他项目的,其中设置列会影响属于这些列的项目。