3 columns grid (top to bottom) using grid CSS

前端 未结 4 1991
醉梦人生
醉梦人生 2021-01-17 13:59

Ok, here\'s the situation, let\'s say I have a list with unknown number of items, it could be 10 or a 100, and I want to lay them out in 3 columns going top to bottom not le

4条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-17 14:38

    I have a list with unknown number of items, it could be 10 or a 100

    As you already observed, CSS Multi-Column Layout produces the desired layout with pure CSS - without having to know in advance the number of items in the container.

    This is not the case with CSS grids - you would have to know in advance the number of items in the grid in order to calculate the necessary number of rows - which is quite a limitation.

    So I would suggest you stick with Multi-Column Layout for your layout.


    Assuming the above limitation is ok - then you can create the layout with css as follows:

    (Note: @Ander already answered this but for what it's worth here's a small explanation)

    1) On the grid container change the grid-auto-flow property to column - This lays out the grid items vertically instead of horizontally (the default).

    2) Once you know the number of items, you can calculate the number of rows necessary to create a balanced grid as follows:

    #rows =  ceil( #items / #columns )
    

    So for 22 items - the # rows = ceil(22/3) = 8

    ul {
       display: grid;
       grid-auto-flow: column; /* 1 */
       grid-template-rows: repeat(8, 1fr);  /* 2 */
    }
    

    We can slightly improve this solution with SASS - to produce a more generic solution which calculates the number of rows. (SASS has a ceil function)

    ul {
      list-style: none;
      padding: 0;
      display:grid;
      $num-items: 22;
      $num-cols: 3;
      $num-rows: ceil($num-items / $num-cols);
      grid-template-columns: repeat($num-cols, 1fr);
      grid-template-rows: repeat($num-rows, 1fr);
      grid-auto-flow: column;
      border: 5px solid gold;
    }
    

    Codepen Demo


    FWIW: Here's an alternative solution which uses nth-child selectors without needing to change the grid-auto-flow property. Unfortunately it has the same limitation that the #items must be known in advance.

    li:nth-child(-n + 24) {
      grid-column: 3;
    }
    
    li:nth-child(-n + 16) {
      grid-column: 2;
    }
    
    li:nth-child(-n + 8) {
      grid-column: 1;
    }
    

    SASS Codepen

提交回复
热议问题