SOLVED: by @[email protected] using columns property

TL;DR: I want to achieve this behavior for the menu layout, but all I can get is this; note the different menu options order.

Two days ago I asked for help for implementing the current behavior without hardcoding the menu height for each resolution step, and there were two suggestions to try display: grid. It looked promising and after reading some documentation I was able to get something very close to what I’m looking for.

The only difference being that I want the chapters to be sorted vertically (as in the current version), but what I got sorts the chapters horizontally.

Here it is (what I think is) the relevant code:

#menu ul {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-auto-flow: row dense;
}

Sorry, I don’t have the display: grid version online.

I did a quick search for display grid multiple columns vertical sort and saw this StackOverflow post: CSS Grid vertical columns with infinite rows which, if I understand correctly, says it’s not possible. But I’m pretty sure I’m not understanding it correctly.

Any help will be welcome, thanks!

EDIT: I also tried grid-audto-flow: column (as suggested here) but it just renders a single row. Probably because I’m missing something…

#menu ul {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-auto-flow: column;
}

EDIT-2: I was told that for grid-audto-flow: column to work I need to specify the numbers of columns. If I understand correctly, then that doesn’t really help. The original issue is that I need to edit the CSS file every time a new chapter is added. Which would be the same if I have to hardcode the number of rows.

I mean, it’s a bit cleaner to hardcode the number of rows than the height in pixels, but I was looking for a solution that doesn’t require magic numbers in the CSS.

  • g6d3np81@kbin.social
    link
    fedilink
    arrow-up
    2
    ·
    edit-2
    1 year ago

    Generally you don’t need anything for child element, except in rare case, which you have seen before a fix…
    Columns usually try to balance every columns to have same height, and last column have least items.

    EDIT: In your case, <li> having a margin-top, which got clipped when new column starts. I don’t know if there is a fix for this but I would use padding instead.

    CSS is chaotic, dude.

    ul {
      /* reset */
      margin: 0;
      padding: 16px;
    
      columns: 2;
      /* box-sizing: border-box; */
    }
      @media screen and (min-width: 640px) {
        ul {
          columns: 3;
        }
      }
      @media screen and (min-width: 960px) {
        ul {
          columns: 4;
        }
      }
    
      ul li {
        list-style-type: none;
        padding: 2px 16px 2px 4px;
        font-size: 120%;
    
        display: flex;
        break-inside: avoid;
      }
      ul li a {
        /* display: inline-block; */
        background-color: #35516c;
        color: #d2dade;
        text-decoration: none;
        padding: 2px 8px;
        border: solid 1px #d2dade;
    
        flex-grow: 0;
      }
        ul li a:first-child {
          flex-grow: 1;
          /* width: 106px; */
          /* margin-right: -3px; */
        }
        ul li a:hover {
          background-color: #1e445d;
          color: #fff;
          border: solid 1px #fff;
        }
    
    
    • Crul@lemm.ee
      link
      fedilink
      arrow-up
      1
      ·
      1 year ago

      Generally you don’t need anything for child element,

      Makes sense. in this case the margin was there from the “display: flex version” and I didn’t realize in the first tests.

      Columns usually try to balance every columns to have same height, and last column have least items.

      Which is exactly what I wanted… and was confused as to why there wasn’t an easy option. This is perfect.

      Thank you very much!