Search code examples
csscss-gridcss-counter

How to set the grid-template-columns repeat() integer dynamically via a counter?


Not adding columns to the grid via fill or fit.

Incrementing/decrementing the grid-template-columns repeat() integer when <app-panel>s are dynamically added/removed to/from the DOM.

Something like this...

CSS:

:root {
  --columns: column-sum;
}

app-container {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(100px, 1fr));
  /* other styles... */
}

app-column {
  counter-increment: column-sum;
  /* other styles... */
}

HTML: (custom tags)

<app-container>
  <app-column></app-column>
  <app-column></app-column>
  <app-column></app-column>
  <app-column></app-column>
</app-container>

Rendered output should read:

app-container {
  display: grid;
  grid-template-columns: repeat(4, minmax(100px; 1fr));
  /* other styles... */
}

CodePen

Why doesn't that work?


Solution

  • Here's a little JS snippet to set columns based on the amount of children elements. Also consider using flex for this

    const containers = Array.from(document.getElementsByClassName('container'));
    
    containers.forEach( container => container.style.cssText = `--columns: ${container.children.length}` );
    /* DISPLAY GRID */
    .container {
      display: grid;
      grid-template-columns: repeat( var(--columns), 1fr );
    }
    
    /* DISPLAY FLEX */
    .container2 { display: flex }
    .container2 > div { flex: 1 1 auto }
    
    
    /* COMMON STYLES FOR EXAMPLE PURPOSES */
    .container, .container2 {
      border: 1px solid blue;
      gap: 1em;
      margin-bottom: 1em
    }
    .container > div, .container2 > div { border: 1px solid red }
    <div class="container">
      <div>Grid Col 1</div>
      <div>Grid Col 2</div>
      <div>Grid Col 3</div>
      <div>Grid Col 4</div>
    </div>
    
    <div class="container">
      <div>Grid Col 1</div>
      <div>Grid Col 2</div>
      <div>Grid Col 3</div>
      <div>Grid Col 4</div>
      <div>Grid Col 5</div>
      <div>Grid Col 6</div>
    </div>
    
    <div class="container">
      <div>Grid Col 1</div>
      <div>Grid Col 2</div>
      <div>Grid Col 3</div>
    </div>
    
    <div class="container2">
      <div>Flex Col 1</div>
      <div>Flex Col 2</div>
      <div>Flex Col 3</div>
      <div>Flex Col 4</div>
    </div>
    
    <div class="container2">
      <div>Flex Col 1</div>
      <div>Flex Col 2</div>
      <div>Flex Col 3</div>
      <div>Flex Col 4</div>
      <div>Flex Col 5</div>
      <div>Flex Col 6</div>
    </div>
    
    <div class="container2">
      <div>Flex Col 1</div>
      <div>Flex Col 2</div>
      <div>Flex Col 3</div>
    </div>