CSS Grid with variable number of “auto” rows, but one row should take “1fr”

前端 未结 1 753
深忆病人
深忆病人 2020-12-03 22:06

I\'m fiddling around with a CSS grid-based frontend and the following behaviour is required over and over and over again in different parts of the frontend:

  1. A
相关标签:
1条回答
  • 2020-12-03 22:25

    Considering your three requirements:

    1. A grid with a variable number of rows.
    2. Every row should have a variable size (auto will do).
    3. The last row should always take up all the remaining space.

    Flexbox is well-suited for the job. In fact, it may be the perfect fit (depending on your other requirements). I've provided a code sample below.

    But if Grid Layout is what you want, then I think you're going to be disappointed. I don't believe Level 1 can do the job.

    The closest you can get would be:

    grid-template-rows: repeat(auto-fit, minmax(auto, 1px)) 1fr;
    

    But it won't work because the current grid spec doesn't support this syntax.

    repeat(auto-fit, auto) 1fr

    This is the code you tried. It's not valid because auto and fr cannot be used with auto-fit.

    7.2.2.1. Syntax of repeat()

    Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes.

    • An intrinsic sizing function is min-content, max-content, auto, fit-content().

    • A flexible sizing function is <flex> (fr).

    You can get around the auto limitation with something like this:

    repeat(auto-fit, minmax(auto, 1px)) 1fr

    minmax(min,max)

    Defines a size range greater than or equal to min and less than or equal to max.

    If max < min, then max is ignored and minmax(min,max) is treated as min.

    As a maximum, a <flex> value sets the track’s flex factor; it is invalid as a minimum.

    That works to properly auto-size your rows, whether the container has the default auto height or a height / min-height defined. demo

    But it still doesn't solve the last row problem, since the 1fr remains invalid, and causes the entire rule to fail. demo

    Something like this would be valid:

    repeat(auto-fit, minmax(auto, 1px)) 10em

    But the auto-fit doesn't work as you expect: the 10em is applied to the second row. demo

    And the rule doesn't work as expected if the container has a height or min-height defined. demo


    Even with CSS Grid Layout now widely available, Flexbox is still the better choice in some cases.

    This covers all your requirements with clean and simple code:

    article {
      display: flex;
      flex-direction: column;
      height: 100vh;
    }
    
    section:last-child {
      flex-grow: 1;
    }
    
    section {
      /* flex-basis: auto <-- this is a default setting */
      margin-bottom: 10px;
      background-color: lightgreen;
    }
    
    body {
      margin: 0;
    }
    <article>
      <section>text text text</section>
      <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
        text text text text text text text text text text </section>
      <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
      <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
      <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
    </article>

    0 讨论(0)
提交回复
热议问题