htmlcsshtml-listsdynamic-columns

Dynamic number of columns for words with different length


So I tried to create an ul with multiple li-entries. These word entries in the li are supposed to be displayed in columns, however I wanted these columns to be dynamic, meaning that longer words create fewer columns and that shorter words create more columns. The page is supposed to be displayed in DINA4 format. I already attempted to use Flexbox & Grid, however that only works when I define a fixed amount of columns, thus not having it be dynamic.

If possible I would like to avoid using javaScript as the page should be made up of CS and HTML alone. Short words with more columns Longs words with fewer columns

With grid auto-fill I get this results: Result with long words

My code:

  ul.words-o {
  margin-top: 0;
  margin-bottom: 1em;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0 20px;
}

Solution

  • You may use javascript to update the minmax value via a custom CSS var(--);

    var bigW = "0";
    // go through all children and keep the widest value
    for (let e of document.querySelectorAll("ol > li")) {
      elW = e.offsetWidth;
      if (elW < 5) {} else if (elW > bigW) {
        bigW = elW
      }
    // upddate the CSS var()
      document.documentElement.style.setProperty("--min-content", bigW + 1 + "px");
      // delay time to display as a grid untill every children's width have been tested
      setTimeout(document.querySelector("ol#ol-grid").classList.add("grid"), 10);// if your computer is slow, increase it a bit , if your eye notices it, its too long
    }
    * {
      margin: 0;
      padding: 0;
    }
    .grid {
      display: grid;
    }
    ol {
      grid-template-columns: repeat(
        auto-fit,
        minmax(var(--min-content,200px), max-content)
      );
      gap: 20px;
    }
    li {
      display: inline-block;
      border: solid;
    }
    <ol id="ol-grid">  
      <li>lkgdsflkdgsh</li>
      <li>klfqh</li>
      <li>Lorem</li>
      <li> ipsum</li>
      <li> dolor</li>
      <li> sit</li>
      <li> amet</li>
      <li>consectetuer</li>
      <li> adipiscing</li>
      <li> elit.</li>
       <li>Aliquam</li>
      <li> tincidunt</li>
      <li> mauris</li>
      <li> eu</li>
      <li> risus.</li>
       <li>VestibulumVestibulum</li>
      <li> auctor</li>
      <li> dapibus</li>
      <li> neque</li>
    </ol>

    codepen to play with


    Also, You might use column-count and javascript to reassign a value to column-count onload and onresize

    example

    function checkGridWidth() {
      let colCount = 12; // set col numbers to start with
      document.documentElement.style.setProperty('--colCount', colCount); // reset while on resize needs it
      let list = document.querySelector("#ol-grid");
      let vw = list.parentNode.offsetWidth;
      let myW = list.offsetWidth;
      if (myW > vw) {
        let dif = myW - vw;
        let colW = (myW / colCount);
        let newColCount = vw / colW;
        document.documentElement.style.setProperty('--colCount', Math.floor(newColCount - 1));
      }
    }
    window.onresize = checkGridWidth;
    window.onload = checkGridWidth;
    * {
      margin: 0;
      padding: 0;
    }
    
    div {
      margin: 3cm;
    }
    
    @media print {
      div>h1 {
        display: none;
      }
    }
    
    ol {
      padding: 5px;
      column-gap: 5px;
      column-fill: balance;
      column-count: var(--colCount, 12);
      min-width: max-content;
      /* you need it so it can overflow its parent, js will use this width value*/
      margin: auto;
      border: solid;
      /*see me*/
    }
    
    li {
      display: block;
      border: solid;
      /*see me*/
    }
    
    li:not(:last-of-type) {
      margin-bottom: 5px;
    }
    <div>
      <h1> Redraw the right amount of column than can fit in here if too wide</h1>
      <ol id="ol-grid">
        <li>lkgdsflkdgsh</li>
        <li>klfqh</li>
        <li>Lorem</li>
        <li> ipsum</li>
        <li> dolor</li>
        <li> sit</li>
        <li> amet</li>
        <li>consectetuer</li>
        <li> adipiscing</li>
        <li> elit.</li>
        <li>Aliquam</li>
        <li> tincidunt</li>
        <li> mauris</li>
        <li> eu</li>
        <li> risus.</li>
        <li>VestibulumVestibulum</li>
        <li> auctor</li>
        <li> dapibus</li>
        <li> neque</li>
        <li>lkgdsflkdgsh</li>
        <li>klfqh</li>
        <li>Lorem</li>
        <li> ipsum</li>
        <li> dolor</li>
        <li> sit</li>
        <li> amet</li>
        <li>consectetuer</li>
        <li> adipiscing</li>
        <li> elit.</li>
        <li>Aliquam</li>
        <li> tincidunt</li>
        <li> mauris</li>
        <li> eu</li>
        <li> risus.</li>
        <li>VestibulumVestibulum</li>
        <li> auctor</li>
        <li> dapibus</li>
        <li> neque</li>
      </ol>
    </div>

    codepen to play with