-1

I want to create a layout like this:

test test test
data-0 data-1 data-2
test test test
data-3 data-4 data-5

But the following code produces this:

test test test test test test
data-0 data-1 data-2 data-3 data-4 data-5

This example shows the layout for 3 columns, 2*2 rows and 6 items. In practice I want to work with 10 columns, auto*2 rows and a dynamic amount of items. As a bonus, it would be awesome, if the amount of column adjusts based on the available width. The problem seems to be that overflowing elements are just added to the first row with a given name, instead of the first non-full row with a given name.

Current implementation using react:

const items = new Array(6)
  .fill(undefined)
  .map((e, i) => ({ title: "test", data: "data-" + i }));

const root = (
  <div
    style={{
      display: "grid",
      gridTemplateColumns: "repeat(3, auto)",
      gridTemplateRows: "repeat(2, [title] auto [data] auto)",
    }}
  >
    {items.map((item, i) => (
      <React.Fragment key={i}>
        <div style={{ gridRow: "title" }}>{item.title}</div>
        <div style={{ gridRow: "data" }}>{item.data}</div>
      </React.Fragment>
    ))}
  </div>
);

ReactDOM.render(root, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
pyBlob
  • 83
  • 1
  • 5

2 Answers2

1

Right at the end of: Subgrid - CSS - MDN

There is a short video example: Don't Wait to Use Subgrid for Better Card Layouts

The presented card layout can be used without change for the required use case. The grid components will have a row span of 2 (instead of 3).

As of writing this answer, the subgrid feature only works in firefox. The implementation for other major browsers has started. As a workaround, the video suggests using grid-template-rows: ...; before grid-template-rows: subgrid;.

.table {
  display: grid;
  grid-template-columns: repeat(3, 5em);
  grid-template-rows: repeat(2, auto auto);
  gap: 1em;
}

.card {
  display: grid;
  grid-row: span 2;
  gap: 0;

  /* fallback for browsers that don't support subgrid with following behaviour:
       1fr: title gets as much space as it needs
      auto: data is assumed to be of fixed size
   */
  grid-template-rows: 1fr auto;

  /* enable subgrid */
  grid-template-rows: subgrid;
}

.title {
  background: lightblue;
}
<div class="table">
  <div class="card"><div class="title">long<br />title-0</div><div class="data">data-0</div></div>
  <div class="card"><div class="title">title-1</div><div class="data">data-1</div></div>
  <div class="card"><div class="title">title-2</div><div class="data">data-2</div></div>
  <div class="card"><div class="title">title-3</div><div class="data">data-3</div></div>
  <div class="card"><div class="title">title-4</div><div class="data">data-4</div></div>
  <div class="card"><div class="title">title-5</div><div class="data">data-5</div></div>
</div>
pyBlob
  • 83
  • 1
  • 5
  • Yes, this is a good way to solve the problem. I didn't post it because subgrid is still lacking full suport, and I thought that you explicitly wanted a "flat" design. Good answer! – vals Nov 29 '21 at 08:17
0

You need some more css classes, you need to set positions using nth-child selector:

.container {
    display: grid;
    grid-template-columns: repeat(3, 50px);
    grid-auto-rows:  30px;
    grid-auto-flow: column dense;
}


.title:nth-child(6n+3) {
    grid-column: 2;
    background-color: lightblue;
}
.data:nth-child(6n+4) {
    grid-column: 2;
    background-color: lightblue;
}

.title:nth-child(6n+5) {
    grid-column: 3;
    background-color: lightgreen;
}
.data:nth-child(6n) {
    grid-column: 3;
    background-color: lightgreen;
}
<div class="container">
<div class="title">title1</div>
<div class="data">data1</div>
<div class="title">title2</div>
<div class="data">data2</div>
<div class="title">title3</div>
<div class="data">data3</div>
<div class="title">title4</div>
<div class="data">data4</div>
<div class="title">title5</div>
<div class="data">data5</div>
<div class="title">title6</div>
<div class="data">data6</div>
<div class="title">title7</div>
<div class="data">data7</div>
<div class="title">title8</div>
<div class="data">data8</div>
<div class="title">title9</div>
<div class="data">data9</div>
<div class="title">title10</div>
<div class="data">data10</div>
<div class="title">title</div>
<div class="data">data</div>
<div class="title">title</div>
<div class="data">data</div>
</div>
vals
  • 61,425
  • 11
  • 89
  • 138
  • This solution is the one I will use for now. I was hoping, if there is a way to do this using the new subgrid feature? – pyBlob Nov 27 '21 at 14:32