Search code examples
csscss-grid

CSS Grid, How to make list items resize to always show 2.5


Using CSS Grid, how can I make sure that only 2 and half of the grey squares, represented by the list items are visible, even when you resize the window.

As I resize the window I expect the grey squares to get bigger and smaller to maintain that only two and a half squares are always shown.

The number of list items will be dynamic, so I cant use the qty of items in any way.

Just to be clear on 2.5, I expect two of the grey squares to be visible and the third square to be only half shown and the other half and the rest of the squares will not be visible because they will be in the scroll area.

 ul {
  display: grid;
  grid-gap: 20px;
  grid-auto-flow: column;
  overflow-x: auto;
  overflow-y: hidden;
}
li {
  display: inline-block;
  vertical-align: top;
  width: 130px;
  height: 130px;
  white-space: normal;
  background: grey;
  cursor: pointer;
  border-radius: 4px;
  user-select: none;
}
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
<ul/>


Solution

  • add grid-auto-columns:calc((100% - 2*20px)*2/5);. From the width your remove 2 gaps and then you multiply by 2/5 (this is the opposite of 5/2=2.5 ).

    ul {
      --g:20px;
      display: grid;
      grid-gap: var(--g);
      grid-auto-flow: column;
      grid-auto-columns:calc((100% - 2*var(--g))*2/5);
      overflow-x: auto;
      cursor: grab;
      padding: 0;
      padding-left: 50px;
    }
    
    li {
      list-style:none;
      display:flex;
      white-space: normal;
      background: grey;
      cursor: pointer;
      border-radius: 4px;
      user-select: none;
      
      /* to illustrate the center */
      background:linear-gradient(red 0 0) center/2px 100% no-repeat grey; 
    }
    
    li::before {
      content:"";
      padding-top:100%;
    }
    <ul>
      <li id="about">Item 1</li>
      <li id="test">Item 2</li>
      <li id="big">Item 3</li>
      <li id="here">Item 4</li>
      <li id="there">Item 5</li>
      <li id="big">Item 6</li>
      <li id="small">Item 7</li>
      <li id="storm">Item 8</li>
      <ul/>