我想做的是制作一个具有动态数量的单元格的CSS网格。为了简单起见,我们假设每行始终有四个单元格。我可以指定具有如此动态行数的网格吗?
为了更简单,这里是 Flexbox 实现:
const COLORS = [
'#FE9',
'#9AF',
'#F9A',
"#AFA",
"#FA7"
];
function addItem(container, template) {
let color = COLORS[_.random(COLORS.length - 1)];
let num = _.random(10000);
container.append(Mustache.render(template, { color, num }));
}
$(() => {
const tmpl = $('#item_template').html()
const container = $('#app');
for(let i=0; i<5; i++) { addItem(container, tmpl); }
$('#add_el').click(() => {
addItem(container, tmpl);
})
container.on('click', '.del_el', (e) => {
$(e.target).closest('.item').remove();
});
});
.container {
width: 100%;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
.container .item {
flex: 0 0 calc(25% - 1em);
min-height: 120px;
margin: 0.25em 0.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app" class="container">
</div>
<button id="add_el">Add element</button>
<template id="item_template">
<div class="item" style="background: {{color}}">
<p>{{ num }}</p>
<p>
<button class="del_el">Delete</button>
</p>
</div>
</template>
P.S. 显然,我第一次不够清楚......我想使用最新的 CSS 网格布局重新创建这种效果。
好吧,阅读完MDN参考资料后,我找到了答案!动态行(或列)的关键是
repeat
属性。
const COLORS = [
'#FE9',
'#9AF',
'#F9A',
"#AFA",
"#FA7"
];
function addItem(container, template) {
let color = COLORS[_.random(COLORS.length - 1)];
let num = _.random(10000);
container.append(Mustache.render(template, { color, num }));
}
$(() => {
const tmpl = $('#item_template').html()
const container = $('#app');
for(let i=0; i<5; i++) { addItem(container, tmpl); }
$('#add_el').click(() => {
addItem(container, tmpl);
})
container.on('click', '.del_el', (e) => {
$(e.target).closest('.item').remove();
});
});
.container {
width: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(auto-fill, 120px);
grid-row-gap: .5em;
grid-column-gap: 1em;
}
.container .item {
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app" class="container">
</div>
<button id="add_el">Add element</button>
<template id="item_template">
<div class="item" style="background: {{color}}">
<p>{{ num }}</p>
<p>
<button class="del_el">Delete</button>
</p>
</div>
</template>
grid-auto-rows
。
只需使用下面的代码即可自动生成网格列
.container {
display: grid;
grid-auto-flow: column;
}
对于那些登陆这里寻找一种动态表的方法的人来说,将项目包装到新行,并且仍然跨行对齐,一个很好的解决方案是将
flex
与 flex-wrap
和 flex: 1
一起使用所有元素:
.container {
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.container .item {
flex: 1;
}
TLDR;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))
我要寻找的是如何让浏览器计算适当的列数,同时保持行拉伸。我在 mdn 文档中找到了答案。
重要的是设置列的最小宽度。在我的示例中我使用了200px。
有趣的事实:您可以使用
min(200px, 100%)
代替 200px,当容器空间不足时,它可以让项目缩小得更小。类似于min-width: 100%
。
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.container:has(+input:checked) {
grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
}
.fancy-colors {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
width: 600px;
resize: horizontal;
overflow: auto;
position: relative;
&::after {
position: absolute;
bottom: 0;
right: 10px;
content: "Resize me!";
color: grey;
font-size: 0.8em;
}
> * {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
}
<div class="container fancy-colors">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
</div>
<input type="checkbox">min(200px, 100%)</input>
有这样的事吗?
$(document).ready(function() {
//Prepare Element selectors
var cssElem = $("#Dynam"), rowElem = $("#rows"), columnElem = $("#columns"), appElem = $("#app");
var noItems = $(".item").length,defaultColumns = 4;
//Init default state
cssElem.html(".container .item {flex: 0 0 calc(" + (100 / defaultColumns) + "% - 1em);}");
columnElem.val(defaultColumns);
rowElem.val(Math.ceil(noItems / columnElem.val()));
//Add listeners to change
appElem.on("DOMSubtreeModified", function() {
noItems = $(".item").length;
rowElem.val(Math.ceil(noItems / columnElem.val()));
});
columnElem.on("change", function() {
rowElem.val(Math.ceil(noItems / columnElem.val()));
cssElem.html(".container .item {flex: 0 0 calc(" + (100 / columnElem.val()) + "% - 1em);}");
});
rowElem.on("change", function() {
columnElem.val(Math.ceil(noItems / rowElem.val()));
cssElem.html(".container .item {flex: 0 0 calc(" + (100 / columnElem.val()) + "% - 1em);}");
});
});
const COLORS = ['#FE9', '#9AF', '#F9A', "#AFA", "#FA7"];
function addItem(container, template) {
let color = COLORS[_.random(COLORS.length - 1)];
let num = _.random(10000);
container.append(Mustache.render(template, {
color,
num
}));
}
$(() => {
const tmpl = $('#item_template').html()
const container = $('#app');
for (let i = 0; i < 5; i++) {
addItem(container, tmpl);
}
$('#add_el').click(() => {
addItem(container, tmpl);
})
container.on('click', '.del_el', (e) => {
$(e.target).closest('.item').remove();
});
});
.container {
width: 100%;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
.container .item {
min-height: 120px;
margin: 0.25em 0.5em;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style id="Dynam"></style>
<button id="add_el">Add element</button> rows:
<input id="rows" /> columns:<input id="columns" />
<div id="app" class="container">
</div>
<template id="item_template">
<div class="item" style="background: {{color}}">
<p>{{ num }}</p>
<p>
<button class="del_el">Delete</button>
</p>
</div>
</template>
这是网格中动态列的一个非常简单的示例
.container {
display: grid;
grid-template-columns: repeat(auto-fit, 250px);
grid-row-gap: 5px;
grid-column-gap: 5px;
justify-content: center;
width: 90%;
margin: 0 auto;
list-style: none;
}
.container>.item {
padding: 5px;
background-color: gray;
}
<div class="container">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
<div class="item">item4</div>
</div>
您不需要使用重复。相反,您只需从 javascript 代码中设置一个变量 --grid-template-columns 即可。
rootEl.style.setProperty('--grid-template-columns' theGridTemplateColumnsValue)
theGridTemplateColumnsValue 是一个字符串,还可以包含其他 css 变量。 这样您就可以拥有每行的动态列数。