Search code examples
htmlcsscss-grid

CSS Grid BarChart - Force new <li> items onto a new row without specifying grid-row-start


I am trying to create a configurable BarChart using only HTML/CSS... I started with a tutorial from Josh Collingsworth: https://joshcollinsworth.com/blog/css-grid-bar-charts

It uses a CSS GRID to auto-size based on the provided column-spans. The problem I have (and he also explains in his example but doesnt give clearly a solution) is that if one of the items is large, the natural behaviour of GRID is to put the other items together on the next row(s) because there is enough space.

As I am trying to create a simple bar-chart, I want to force each item on a new row.

section {
  width: 100%;
  max-width: 30rem;
  padding: 1.5rem 1.5rem 2rem;
  border: 2px solid #a7a8aa;
  border-radius: 0.5rem;
  margin: auto;
  box-sizing: border-box;
}

.chart {
  display: grid;
  grid-template-columns: auto;
  grid-auto-columns: 1fr;
  gap: 0.1em 0;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style-type: none;
  border-left: 3px solid grey; 
}

li {
  background: gold;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.3rem 0.5rem;
  border-radius: 0 0.5em 0.5em 0;
}
<section>
  <h2>Players per sports team</h2> 
  <ul class="chart">
    <li style="grid-column: span 11">
      Baseball:
      <span>11</span>
    </li>

    <li style="grid-column: span 4">
      Football:
      <span>4</span>
    </li>

    <li style="grid-column: span 3">
      Basketball:
      <span>3</span>
    </li>
    <li style="grid-column: span 3; grid-row-start:4;">
      Basketball:
      <span>3</span>
    </li>
  </ul> 
</section>

As my data will be dynamic, I am looking for a simple way through CSS to force each ListItem to start on a separate row.

I found that if I specify the row explicitly with each item it works, but it feels like I am missing something simple from the CSS which would accomplish the same thing ?? <li style="grid-column: span 4; grid-row-start: 1">

I also tried to force each ListItem to begin at column1 using grid-column-start:1 in the ListItem CSS but this doesnt work.


Solution

  • In fact the example does give an solution.

    Fortunately, there’s an easy solution.

    First, set grid-column-start: 1 on each grid item in your CSS;

    Then, simply use grid-column-end instead of grid-column on each bar’s inline styles. (Either grid-column-end: span x;, or grid-column-end: x + 1; would work, where x is the data point’s value.)

    This works.

    section {
      width: 100%;
      max-width: 30rem;
      padding: 1.5rem 1.5rem 2rem;
      border: 2px solid #a7a8aa;
      border-radius: 0.5rem;
      margin: auto;
      box-sizing: border-box;
    }
    
    .chart {
      display: grid;
      grid-template-columns: auto;
      gap: 0.1em 0;
      align-items: center;
      margin: 0;
      padding: 0;
      list-style-type: none;
      border-left: 3px solid grey;
    }
    
    li {
      background: gold;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0.5rem 0.5rem;
      border-radius: 0 0.5em 0.5em 0;
      grid-column-start: 1;
    }
    <section>
      <h2>Players per sports team</h2>
      <ul class="chart">
        <li style="grid-column-end: 11">
          Baseball:
          <span>11</span>
        </li>
    
        <li style="grid-column-end: 3">
          Football:
          <span>3</span>
        </li>
    
        <li style="grid-column-end: 4">
          Volleyball:
          <span>4</span>
        </li>
        <li style="grid-column-end: 3;">
          Basketball:
          <span>3</span>
        </li>
      </ul>
    </section>