2

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);
}
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
LarryN
  • 216
  • 1
  • 2
  • 12

2 Answers2

0

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>
Anwar Hossen
  • 536
  • 5
  • 11
  • Your code doesn't make the table fill the height of the view-port and I see your using Bootstrap 5 (which is still in beta) not Bootstrap 4. – LarryN Dec 17 '20 at 22:05
  • In this case, Bootstrap 5 or Bootstrap 4 does not matter really. Because I did not touch your HTML code. I have just changed your custom CSS. It seems that you have changed your codepen codes. Instead of "thead tr" you just declare a class (theHeader) there. Is your problem solved or not? – Anwar Hossen Dec 18 '20 at 05:38
  • Sorry about the change to the Codepen (multiple versions and changes). No, it's still not filling the height of the view-port. – LarryN Dec 19 '20 at 04:32
  • Add a photo in your post, so that we can understand better. – Anwar Hossen Dec 19 '20 at 06:04
  • I can't embed a picture yet, I don't have enough reputation points, but if you look at the codepen the last row of the calendar should go all the way to the bottom of the page. (all rows except the one that contains the days of the week should be the same height) – LarryN Dec 19 '20 at 18:45
  • I don't want to use div's, as I stated in the original question, I want to use a Bootstrap 4 bordered table. – LarryN Dec 21 '20 at 19:15
  • OK, I was partially successful in making the table, but I the positioning of my "forward" and "back" buttons isn't right and I'm not sure how to fix them. https://jsfiddle.net/9e5c6xk8/ – LarryN Dec 29 '20 at 19:39
  • check this - https://stackoverflow.com/questions/65484753/positioning-buttons-next-to-image/65485414#65485414 – Anwar Hossen Dec 29 '20 at 19:57
0

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/

David Liang
  • 20,385
  • 6
  • 44
  • 70