web-dev-qa-db-ja.com

動的な数のセル/行を持つCSSグリッドを使用できますか?

私がやりたいのは、動的なセル数で CSSグリッド を作成することです。簡単にするために、行ごとに常に4つのセルがあると仮定します。このような動的な行数でグリッドを指定できますか?

簡単にするため、ここに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>

PSどうやら、最初は十分にはっきりしていなかったようです...最新の CSS Grid Layout

31
art-solopov

さて、 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>

PS。または、特定の例では grid-auto-rows を使用できます。

26
art-solopov

このようなもの?

$(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>
0
Adam K.