【问题标题】:Can I make a CSS grid with dynamic number of rows or columns?我可以制作具有动态行数或列数的 CSS 网格吗?
【发布时间】:2017-08-24 06:11:40
【问题描述】:

我想做的是用动态数量的单元格制作CSS grid。为了简单起见,我们假设每行总是有四个单元格。我可以指定具有这种动态行数的网格吗?

为方便起见,下面是 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 Grid Layout.重新创建这个效果

【问题讨论】:

  • 您想要每行始终有 4 个单元格,还是想要每行动态显示这些单元格?不清楚
  • 每行动态单元格会很酷,但我现在满足于每行有 4 个单元格。

标签: css css-grid


【解决方案1】:

这样的?

$(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>

【讨论】:

  • 对不起,如果我不够清楚,我想重新创建我使用最近创建的CSS Grid layout.的效果
  • 哦?这真的很新鲜caniuse.com/#feat=css-grid ...我很惊讶它被大多数浏览器同时采用。抱歉,我目前对 CSS 网格的了解为零。
【解决方案2】:

好的,看完MDN reference,我找到了答案!动态行(或列)的关键是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>

P.S. 或者您可以在我的特定示例中使用 grid-auto-rows

【讨论】:

  • 网格模板列:重复(自动填充,Xpx); ...终于找到了:)谢谢!
  • @Sandro 我想我实际上建议使用grid-auto-rows,但如果“自动行”没有最后插入,AFAIK 它将不起作用。无论如何,祝你好运!
  • 还有grid-auto-columns
  • 是的,但我没有让他们使用动态数量的列。它只用了一个。
  • grid-auto-flow 设置为column 有帮助吗? codepen.io/art-solopov/pen/xLNYVw
【解决方案3】:

您不需要使用重复。相反,您可以从您的 javascript 代码中设置一个变量 --grid-template-columns。

rootEl.style.setProperty('--grid-template-columns' theGridTemplateColumnsValue)

theGridTemplateColumnsValue 是一个字符串,也可以包含其他 css 变量。 这样,您可以在每行中拥有动态的列数。

【讨论】:

  • CSS Grid 的规范有 auto-fit、auto-fill、repeat 以及 grid-auto-columns 和 grid-auto-rows 可以使用,它们和 flexbox 相互协作,以便无需将 JavaScript 引入图片即可解决布局挑战。 CSS Grid 是为所有二维布局挑战而创建的。 (Flexbox 用于流量控制。)不需要 JavaScript。正如他们在 CSS Grid 的规范中发现的那样,请参阅 OP 下面的答案。 developer.mozilla.org/en-US/docs/Web/CSS/grid
【解决方案4】:

对于那些在这里寻找一种动态表的方法的人来说,项目包装到新行,并且仍然跨行对齐,一个很好的解决方案是将flexflex-wrap和@987654324一起使用@ 代表所有元素:

.container {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.container .item {
  flex: 1;
}

【讨论】:

【解决方案5】:

只需使用以下代码自动生成网格列

.container {
  display: grid;
  grid-auto-flow: column;
}

【讨论】:

  • 但是这个改变给出了几乎相等的宽度。我们如何使它根据子列宽度进行渲染。假设我的第一列是220px,我想要的第二列是auto 或者说200px auto auto220px auto 220px
  • 在不知道长度和计数的情况下保留内联块是个好主意
猜你喜欢
  • 2018-05-16
  • 2020-02-13
  • 2018-06-02
  • 2017-09-16
  • 2017-06-04
  • 1970-01-01
  • 2021-11-26
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多