Full height calendar with Bootstrap 4 table

Viewed 814

I'm trying to create a calendar using a Bootstrap 4 bordered table that takes up 100%vh, has each row the same width but a different height for the header(which contains the days of the week). https://codepen.io/GeoHurdle/pen/ZEpyzLZ

<div class="table-responsive">
  <table class="table table-bordered">
    <thead>
      <tr class="d-flex">
        <th scope="col" class="col-3">Sun</th>
        <th scope="col" class="col-3">Mon</th>
        <th scope="col" class="col-3">Tue</th>
        <th scope="col" class="col-3">Wed</th>
        <th scope="col" class="col-3">Thu</th>
        <th scope="col" class="col-3">Fri</th>
        <th scope="col" class="col-3">Sat</th>
      </tr>
    </thead>
    <tbody>
      <tr class="d-flex">
        <td class="col-3" scope="row">1</td>
        <td class="col-3">2</td>
        <td class="col-3">3</td>
        <td class="col-3">4</td>
        <td class="col-3">5</td>
        <td class="col-3">6</td>
        <td class="col-3">7</td>
      </tr>
      <tr class="d-flex">
        <td class="col-3" scope="row">8</td>
        <td class="col-3">9</td>
        <td class="col-3">10</td>
        <td class="col-3">11</td>
        <td class="col-3">12</td>
        <td class="col-3">13</td>
        <td class="col-3">14</td>
      </tr>
    </tbody>
  </table>
</div>
html,
body {
  overflow-y: hidden;
}

.table [class^='col-'] {
  flex-shrink: 1;
}

tr {
  height: calc(100vh / 3);
}
2 Answers

Instead of the table if you use grid layout, you can do it more easily

html, body {
        height: 100%;
        margin: 0;
        }
        .wrapper {
        border: 1px solid blue;
        height: 100%;
        padding: 10px;
        }

        .grid {
        width: 100%;
        height: 100%;
        display: grid;
        grid-template-columns: auto auto auto auto auto auto auto;
        grid-template-rows: 50px auto auto;
        row-gap: 7px;
        }

        .grid>div {
        width: 100%;
        height: 100%;
        border: 1px solid;
        background-color: rgba(255, 255, 255, 0.8);
        font-size: 30px;
        display: flex;
        justify-content: center;
        align-items: center;
        }
<div class="wrapper">
        <div class="grid">
            <div>Sun</div>
            <div>Mon</div>
            <div>Tue</div>
            <div>Wed</div>
            <div>Thu</div>
            <div>Fri</div>
            <div>Sat</div>
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
            <div>5</div>
            <div>6</div>
            <div>7</div>
            <div>8</div>
            <div>9</div>
            <div>10</div>
            <div>11</div>
            <div>12</div>
            <div>13</div>
            <div>14</div>
            
        </div>
    </div>

There is already a discussion on why not use tables for layout in HTML. If you have to use Bootstrap table to structure the calendar, then you can ignore my answer, or just delete it.

If you want to see how it can be done in flexbox, then keep on reading.

Structure

Just by looking at your source code, I can tell there are 3 major sections in your calendar. So I would first structure them like following:

<section class="calendar">
    <section class="month-selection">
        <a href="#">
            <i class="fas fa-arrow-left"></i>
        </a>
        <div class="month">DECEMBER</div>
        <a href="#">
            <i class="fas fa-arrow-right"></i>
        </a>
    </section>
    <section class="days-of-week">
        <div class="day-of-week">Sunday</div>
        ...
    </section>
    <section class="days">
        <div class="day">1</div>
        ...
    </section>
</section>

One of your requirements is that you want the calendar to take up 100% view height.

It's not hard to do via CSS/SCSS:

.calendar {
    height: 100vh;
}

I guess the tricky part is how to make the days in days section to automatically fill up the gaps while not setting fixed heights on month-selection and days-of-week section.

The trick I had is that I have the calendar display as flexbox, and I set its flow to column, and I only set the height of days section to 100%. Yes, days section will try to set self height to 100% of HTML body, but since it's a child of a flexbox, it will shrink (by default) to take up only available space! (if flowing as column is hard to imagine, think about the row flow)

.calendar {
    height: 100vh;
    display: flex;
    flex-flow: column nowrap;

    .days {
        height: 100%;
    }
}

As long as days section is taking up the rest of available space, later on when we style each individual day, we would be able to automatically adjust their heights!

Height of each day

Another question would be how to automatically adjust the height of each day box in days section so that they will take up the rest of spaces.

Well believe or not, it's super easy with flexbox!

The only thing you need to do, beside setting days section as flexbox, is to set align-items to stretch (which is even the default)!

.days {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
    align-items: stretch;
    height: 100%;

    ...
}

Screenshot

enter image description here

demo: https://jsfiddle.net/davidliang2008/uc4stzp5/107/

Related