skip to Main Content

I have a grid. Each cell will be an image with a max-width (used simple colored div in ex). Is there a way to have the grid automatically add another column when the images reach their max-width instead of just increasing the gap between them. (same for removing a column when shrink to min-width). Here is the sample code

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <style>
      .pet-grid {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 10px;
        width: 100vw;
      }

      .pet {
        aspect-ratio: 1/1;
        background-color: cadetblue;
        max-width: 205px;
      }
    </style>
  </head>

  <body>
    <header></header>

    <main>
      <div class="pet-grid">
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
      </div>
    </main>

    <footer></footer>
  </body>
</html>

2

Answers


  1. Use grid-template-columnswith auto-fill or auto-fit

    https://css-tricks.com/auto-sizing-columns-css-grid-auto-fill-vs-auto-fit/

    auto-fill FILLS the row with as many columns as it can fit. So it creates implicit columns whenever a new column can fit, because it’s trying to FILL the row with as many columns as it can. The newly added columns can and may be empty, but they will still occupy a designated space in the row.

    auto-fit FITS the CURRENTLY AVAILABLE columns into the space by expanding them so that they take up any available space. The browser does that after FILLING that extra space with extra columns (as with auto-fill ) and then collapsing the empty ones.

    .pet-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(auto,205px));
      gap: 10px;
      width: 100vw;
    }
    
    .pet {
      aspect-ratio: 1/1;
      background-color: cadetblue;
      max-width: 205px;
    }
    <main>
      <div class="pet-grid">
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
        <div class="pet"></div>
      </div>
    </main>
    Login or Signup to reply.
  2. I think this might be what you are looking for. The idea here is to calculate the number of columns based on a maximum column width much like auto-fit does. but round the column number up when the available width is between the multiples of the cell’s maximum width instead of down.

    To do this we need to divide the viewport width by the cell’s maximum width, and to do this, this answer leans heavily on the information provided in the article CSS Type Casting to Numeric: tan(atan2()) Scalars by Jane Ori.

    Here we define a custom property "–1bcw" to mean 1 body content box width. i.e. 100vw – 16px for the body’s margin.

    To calculate the target number of columns, we take the body content box width and divide it by the sum of the maximum width of a cell and the width of the gap. However we add one gap width to the body content box width because the grid will have one fewer gaps than columns. Then we round it up to the nearest integer.

    The final calculation looks like this:

    :root {
      --gap: 10px;
      --max-width: 205px;
      --1bcw: calc(100vw - 16px);
      --target-columns: calc(round(up, tan(atan2(var(--1bcw) + var(--gap), 
                                       var(--max-width) + var(--gap))), 1));
    }
    

    Then the cells will grow up to a width of 205px, and then add another column, reducing the cell width down to match.

    This is a bit new and a bit hacky. It seems to work in Chrome and Firefox, but I haven’t tried it on Safari.

    @property --1bcw {
      syntax: "<length>";
      initial-value: 0px;
      inherits: false;
    }
    
    :root {
      --gap: 10px;
      --max-width: 205px;
      --1bcw: calc(100vw - 16px);
      --target-columns: calc(round(up, tan(atan2(var(--1bcw) + var(--gap), 
                             var(--max-width) + var(--gap))), 1));
    }
    
    .pet-grid {
      display: grid;
      grid-template-columns: repeat(var(--target-columns), 1fr);
      gap: var(--gap);
      width: calc(100vw - 16px);
    }
    
    .pet {
      aspect-ratio: 1/1;
      background-color: cadetblue;
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      </head>
    
      <body>
        <header></header>
    
        <main>
          <div class="pet-grid">
            <div class="pet"></div>
            <div class="pet"></div>
            <div class="pet"></div>
            <div class="pet"></div>
            <div class="pet"></div>
            <div class="pet"></div>
            <div class="pet"></div>
            <div class="pet"></div>
          </div>
        </main>
    
        <footer></footer>
      </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search