Search code examples
htmlcssimageflexbox

CSS: in this flex container, how to make the <li> move to the empty space automatically


Calendar screenshot that helps explain my question

In this calendar, after date 6, I added a new

  • to contain the "upcoming events" image, which should take 2 columns of height. Ideally the date 8 should move below 6, and 9 below 7 to fill up the space, but it is not doing so.

    Appreciate any of your help and advice!

    .event_calendar ul {
      padding: 0 20px;
      display: flex;
      list-style: none;
      flex-wrap: wrap;
      color: #000000;
      text-align: center;
    }
    
    .event_calendar .days {
      margin-bottom: 20px;
      justify-content: space-between;
    }
    
    .event_calendar li {
      display: flex;
      color: #333;
      width: calc(100% / 5);
    }
    
    .event_calendar .days li {
      z-index: 1;
      width: 100px;
      height: 100px;
      cursor: pointer;
      position: relative;
      margin-top: 5px;
      justify-content: center;
      font-size: 30px;
      font-weight: 600;
      color: #fff;
    }
    
    .days li::before {
      position: absolute;
      content: "";
      height: 100px;
      width: 100px;
      z-index: -1;
      border-radius: 5px;
      transform: translate(0%, -30%);
    }
    
    .days li.event_date::before {
      position: absolute;
      content: "";
      background: #f2f2f2;
      background-image: url('https://st2.depositphotos.com/1635204/7654/i/450/depositphotos_76549817-stock-photo-word-events-on-colorful-wooden.jpg');
      background-size: cover;
      height: 100px;
      width: 100px;
      z-index: -1;
      border-radius: 5px;
      transform: translate(0%, -30%);
    }
    
    .days li.upcoming_event_preview {
      z-index: 1;
      cursor: pointer;
      position: relative;
      justify-content: center;
      margin-top: 5px;
      width: 300px;
      height: 250px;
      font-size: 30px;
      font-weight: 600;
      color: #fff;
    }
    
    .days li.upcoming_event_preview::before {
      position: absolute;
      content: "";
      background-image: url('https://clipart-library.com/img1/1038152.png');
      background-size: contain;
      margin: 5px;
      width: 300px;
      height: 250px;
      z-index: -1;
      border-radius: 5px;
      transform: translate(0%, -10%);
    }
    <div class="event_calendar">
      <ul class="days">
        <li class="event_date"> 1 </li>
        <li class="event_date"> 2 </li>
        <li class="event_date"> 3 </li>
        <li class="event_date"> 4 </li>
        <li class="event_date"> 5 </li>
        <li class="event_date"> 6 </li>
        <li class="upcoming_event_preview"></li>
        <li class="event_date"> 7 </li>
        <li class="event_date"> 8 </li>
        <li class="event_date"> 9 </li>
        <li class="event_date"> 10 </li>
        <li class="event_date"> 11</li>
        <li class="event_date"> 12 </li>
      </ul>
    </div>

    I have tried to play around with the flexbox, but nothing worked so far. (I do not want to make any the date stretch and fill by doing flex: 1 )


  • Solution

  • Since flexbox won't get you what here, here's an example using display: grid;

    I've commented the CSS.

    NOTE: I did use the original specific px values for the columns that were set in the original question, e.g., 100px. I would recommend changing these to percent values or something that would respond as browser size changes.

    .event_calendar ul {
      padding: 0 20px;
      display: grid; /* GRID */
      list-style: none;
      color: #000000;
      grid-template-columns: repeat(5, 100px); /* SET THE COLUMNS - 5, repeats 100px */
      grid-template-rows: repeat(4, 25%); /* SET 4 ROWS, EQUAL HEIGHT */
      grid-gap: 10px; /* USE GAP INSTEAD OF MARGIN */
      text-align: center;
    }
    
    .event_calendar .days {
      margin-bottom: 20px;
    }
    
    .event_calendar li {
      display: flex;
      color: #333;
     }
    
    .event_calendar .days li {
      z-index: 1;
      width: 100px;
      height: 100px;
      cursor: pointer;
      position: relative;
      justify-content: center;
      font-size: 30px;
      font-weight: 600;
      color: #fff;
    }
    
    .days li::before {
      position: absolute;
      content: "";
      height: 100px;
      width: 100px;
      z-index: -1;
      border-radius: 5px;
      transform: translate(0%, -30%);
    }
    
    .days li.event_date::before {
      position: absolute;
      content: "";
      background: #f2f2f2;
      background-image: url('https://st2.depositphotos.com/1635204/7654/i/450/depositphotos_76549817-stock-photo-word-events-on-colorful-wooden.jpg');
      background-size: cover;
      height: 100px;
      width: 100px;
      z-index: -1;
      border-radius: 5px;
      transform: translate(0%, -30%);
    }
    
    .days li.upcoming_event_preview {
      z-index: 1;
      cursor: pointer;
      position: relative;
      justify-content: center;
      width: 100%;
      height: 100%;
      font-size: 30px;
      font-weight: 600;
      color: #fff;
      grid-column: 2/span 3; /* POSITION THE IMAGE LI IN THE 2ND COLUMN AND MAKE IT SPAN 3 COLUMNS TOTAL */
      grid-row: 2/span 2; /* POSITION THE IMAGE LI IN THE 2ND ROW AND MAKE IT SPAN 2 ROWS TOTAL */
    }
    
    .days li.upcoming_event_preview::before {
      position: absolute;
      content: '';
      /* a little house keeping for the image to be in the middle of the li element */
      background-image: url('https://clipart-library.com/img1/1038152.png');
      background-size: contain;
      background-position: center center;
      background-repeat: no-repeat;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: -1;
      transform: translate(0%, -10%);
    }
    <div class="event_calendar">
      <ul class="days">
        <li class="event_date"> 1 </li>
        <li class="event_date"> 2 </li>
        <li class="event_date"> 3 </li>
        <li class="event_date"> 4 </li>
        <li class="event_date"> 5 </li>
        <li class="event_date"> 6 </li>
        <li class="upcoming_event_preview"></li>
        <li class="event_date"> 7 </li>
        <li class="event_date"> 8 </li>
        <li class="event_date"> 9 </li>
        <li class="event_date"> 10 </li>
        <li class="event_date"> 11</li>
        <li class="event_date"> 12 </li>
      </ul>
    </div>

    Responsive

    .event_calendar ul {
      padding: 0 20px;
      display: grid;
      /* GRID */
      list-style: none;
      color: #000000;
      grid-template-columns: repeat(5, calc(20% - 10px));
      /* SET THE COLUMNS - 5, repeats 20% - 10px to account for the gap */
      grid-template-rows: repeat(4, 25%);
      /* SET 4 ROWS, EQUAL HEIGHT */
      grid-gap: 10px;
      /* USE GAP INSTEAD OF MARGIN */
      text-align: center;
    }
    
    .event_calendar .days {
      margin-bottom: 20px;
    }
    
    .event_calendar li {
      display: flex;
      color: #333;
    }
    
    .event_calendar .days li {
      z-index: 1;
      width: 100%;
      height: 100%;
      min-height: 100px;
      cursor: pointer;
      position: relative;
      justify-content: center;
      font-size: 30px;
      font-weight: 600;
      color: #fff;
    }
    
    .days li::before {
      position: absolute;
      content: "";
      height: 100%;
      width: 100%;
      z-index: -1;
      border-radius: 5px;
      transform: translate(0%, -30%);
    }
    
    .days li.event_date::before {
      position: absolute;
      content: "";
      background: #f2f2f2;
      background-image: url('https://st2.depositphotos.com/1635204/7654/i/450/depositphotos_76549817-stock-photo-word-events-on-colorful-wooden.jpg');
      background-size: cover;
      background-position: center center;
      height: 100%;
      width: 100%;
      z-index: -1;
      border-radius: 5px;
    }
    
    .days li.upcoming_event_preview {
      z-index: 1;
      cursor: pointer;
      position: relative;
      justify-content: center;
      width: 100%;
      height: 100%;
      font-size: 30px;
      font-weight: 600;
      color: #fff;
      grid-column: 2/span 3;
      /* POSITION THE IMAGE LI IN THE 2ND COLUMN AND MAKE IT SPAN 3 COLUMNS TOTAL */
      grid-row: 2/span 2;
      /* POSITION THE IMAGE LI IN THE 2ND ROW AND MAKE IT SPAN 2 ROWS TOTAL */
    }
    
    .days li.upcoming_event_preview::before {
      position: absolute;
      content: '';
      /* a little house keeping for the image to be in the middle of the li element */
      background-image: url('https://clipart-library.com/img1/1038152.png');
      background-size: contain;
      background-position: center center;
      background-repeat: no-repeat;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: -1;
      transform: translate(0%, -10%);
    }
    <div class="event_calendar">
      <ul class="days">
        <li class="event_date"> 1 </li>
        <li class="event_date"> 2 </li>
        <li class="event_date"> 3 </li>
        <li class="event_date"> 4 </li>
        <li class="event_date"> 5 </li>
        <li class="event_date"> 6 </li>
        <li class="upcoming_event_preview"></li>
        <li class="event_date"> 7 </li>
        <li class="event_date"> 8 </li>
        <li class="event_date"> 9 </li>
        <li class="event_date"> 10 </li>
        <li class="event_date"> 11</li>
        <li class="event_date"> 12 </li>
      </ul>
    </div>