Open demo

CSS code

HTML
<div class="qcal">
  <h2>Q4 2026</h2>
  <p class="sub">Studio closed 24 Nov – 2 Dec · one range across the month boundary</p>
  <div class="months">
    <table class="m">
      <caption>October</caption>
      <thead><tr><th scope="col"><span aria-hidden="true">M</span><span class="sr-only">Monday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="sr-only">Tuesday</span></th><th scope="col"><span aria-hidden="true">W</span><span class="sr-only">Wednesday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="sr-only">Thursday</span></th><th scope="col"><span aria-hidden="true">F</span><span class="sr-only">Friday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="sr-only">Saturday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="sr-only">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td><span class="out">28</span></td><td><span class="out">29</span></td><td><span class="out">30</span></td><td><span class="">1</span></td><td><span class="">2</span></td><td><span class="">3</span></td><td><span class="">4</span></td></tr>
        <tr><td><span class="">5</span></td><td><span class="">6</span></td><td><span class="">7</span></td><td><span class="">8</span></td><td><span class="">9</span></td><td><span class="">10</span></td><td><span class="">11</span></td></tr>
        <tr><td><span class="">12</span></td><td><span class="">13</span></td><td aria-current="date"><span class="today">14<span class="sr-only">, today</span></span></td><td><span class="">15</span></td><td><span class="">16</span></td><td><span class="">17</span></td><td><span class="">18</span></td></tr>
        <tr><td><span class="">19</span></td><td><span class="">20</span></td><td><span class="">21</span></td><td><span class="">22</span></td><td><span class="">23</span></td><td><span class="">24</span></td><td><span class="">25</span></td></tr>
        <tr><td><span class="">26</span></td><td><span class="">27</span></td><td><span class="">28</span></td><td><span class="">29</span></td><td><span class="">30</span></td><td><span class="">31</span></td><td><span class="out">1</span></td></tr>
      </tbody>
    </table>
    <table class="m">
      <caption>November</caption>
      <thead><tr><th scope="col"><span aria-hidden="true">M</span><span class="sr-only">Monday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="sr-only">Tuesday</span></th><th scope="col"><span aria-hidden="true">W</span><span class="sr-only">Wednesday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="sr-only">Thursday</span></th><th scope="col"><span aria-hidden="true">F</span><span class="sr-only">Friday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="sr-only">Saturday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="sr-only">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td><span class="out">26</span></td><td><span class="out">27</span></td><td><span class="out">28</span></td><td><span class="out">29</span></td><td><span class="out">30</span></td><td><span class="out">31</span></td><td><span class="">1</span></td></tr>
        <tr><td><span class="">2</span></td><td><span class="">3</span></td><td><span class="">4</span></td><td><span class="">5</span></td><td><span class="">6</span></td><td><span class="">7</span></td><td><span class="">8</span></td></tr>
        <tr><td><span class="">9</span></td><td><span class="">10</span></td><td><span class="">11</span></td><td><span class="">12</span></td><td><span class="">13</span></td><td><span class="">14</span></td><td><span class="">15</span></td></tr>
        <tr><td><span class="">16</span></td><td><span class="">17</span></td><td><span class="">18</span></td><td><span class="">19</span></td><td><span class="">20</span></td><td><span class="">21</span></td><td><span class="">22</span></td></tr>
        <tr><td><span class="">23</span></td><td><span class="s">24<span class="sr-only">, studio closed, first day</span></span></td><td><span class="in">25<span class="sr-only">, studio closed</span></span></td><td><span class="in">26<span class="sr-only">, studio closed</span></span></td><td><span class="in">27<span class="sr-only">, studio closed</span></span></td><td><span class="in">28<span class="sr-only">, studio closed</span></span></td><td><span class="in">29<span class="sr-only">, studio closed</span></span></td></tr>
        <tr><td><span class="in">30<span class="sr-only">, studio closed</span></span></td><td><span class="out">1</span></td><td><span class="out">2</span></td><td><span class="out">3</span></td><td><span class="out">4</span></td><td><span class="out">5</span></td><td><span class="out">6</span></td></tr>
      </tbody>
    </table>
    <table class="m">
      <caption>December</caption>
      <thead><tr><th scope="col"><span aria-hidden="true">M</span><span class="sr-only">Monday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="sr-only">Tuesday</span></th><th scope="col"><span aria-hidden="true">W</span><span class="sr-only">Wednesday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="sr-only">Thursday</span></th><th scope="col"><span aria-hidden="true">F</span><span class="sr-only">Friday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="sr-only">Saturday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="sr-only">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td><span class="out">30</span></td><td><span class="in">1<span class="sr-only">, studio closed</span></span></td><td><span class="e">2<span class="sr-only">, studio closed, last day</span></span></td><td><span class="">3</span></td><td><span class="">4</span></td><td><span class="">5</span></td><td><span class="">6</span></td></tr>
        <tr><td><span class="">7</span></td><td><span class="">8</span></td><td><span class="">9</span></td><td><span class="">10</span></td><td><span class="">11</span></td><td><span class="">12</span></td><td><span class="">13</span></td></tr>
        <tr><td><span class="">14</span></td><td><span class="">15</span></td><td><span class="">16</span></td><td><span class="">17</span></td><td><span class="">18</span></td><td><span class="">19</span></td><td><span class="">20</span></td></tr>
        <tr><td><span class="">21</span></td><td><span class="">22</span></td><td><span class="">23</span></td><td><span class="">24</span></td><td><span class="">25</span></td><td><span class="">26</span></td><td><span class="">27</span></td></tr>
        <tr><td><span class="">28</span></td><td><span class="">29</span></td><td><span class="">30</span></td><td><span class="">31</span></td><td><span class="out">1</span></td><td><span class="out">2</span></td><td><span class="out">3</span></td></tr>
      </tbody>
    </table>
  </div>
  <ul class="key">
    <li><i aria-hidden="true" style="background:#6d28d9"></i> Range start / end</li>
    <li><i aria-hidden="true" style="background:#ede7fb"></i> Within range</li>
    <li><i aria-hidden="true" style="box-shadow:inset 0 0 0 2px #6d28d9"></i> Today</li>
  </ul>
</div>
CSS
/* Quarter view: three month tables side by side; one closed range runs across the month boundary.
   Range and today are drawn in colour and also spelled out in visually hidden text. */
.qcal{--q-accent:#6d28d9;--q-range:#ede7fb;--q-muted:#5f6b7c;
  box-sizing:border-box;width:100%;max-width:820px;padding:22px 24px 24px;background:#fff;border-radius:16px;
  box-shadow:0 14px 34px -18px rgba(18,24,40,.25)}
.qcal h2{font-size:.98rem;margin:0 0 2px}
.qcal .sub{font-size:.79rem;color:var(--q-muted);margin:0 0 18px}
.qcal .months{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;align-items:start}
.qcal table{width:100%;border-collapse:separate;border-spacing:1px;table-layout:fixed}
.qcal caption{font-size:.84rem;font-weight:700;padding-bottom:8px;text-align:center}
.qcal th{font-size:.56rem;font-weight:800;color:var(--q-muted);padding:6px 0;text-align:center}
.qcal td{padding:0}
.qcal td > span{aspect-ratio:1;display:grid;place-items:center;font-size:.7rem;font-weight:600;color:#2c3546;border-radius:6px}
.qcal .out{color:#667284;font-weight:400}
.qcal .in{background:var(--q-range);border-radius:0}
.qcal .s,.qcal .e{background:var(--q-accent);color:#fff}
.qcal .s{border-radius:6px 0 0 6px}.qcal .e{border-radius:0 6px 6px 0}
.qcal .today{box-shadow:inset 0 0 0 2px var(--q-accent);color:var(--q-accent)}
.qcal .key{display:flex;gap:16px;margin:18px 0 0;padding:0;list-style:none;font-size:.76rem;color:var(--q-muted);flex-wrap:wrap}
.qcal .key li{display:flex;align-items:center;gap:6px}
.qcal .key i{width:11px;height:11px;border-radius:3px}
@media (max-width:720px){.qcal .months{grid-template-columns:1fr;gap:22px}}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="qcal card w-100">
  <h2 class="fw-bold mb-1" style="font-size:.98rem">Q4 2026</h2>
  <p class="mb-3" style="font-size:.79rem;color:var(--q-muted)">Studio closed 24 Nov – 2 Dec · one range across the month boundary</p>
  <div class="row row-cols-1 row-cols-md-3 g-4">
    <div class="col"><table class="table table-borderless text-center caption-top mb-0">
      <caption>October</caption>
      <thead><tr><th scope="col"><span aria-hidden="true">M</span><span class="visually-hidden">Monday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="visually-hidden">Tuesday</span></th><th scope="col"><span aria-hidden="true">W</span><span class="visually-hidden">Wednesday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="visually-hidden">Thursday</span></th><th scope="col"><span aria-hidden="true">F</span><span class="visually-hidden">Friday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="visually-hidden">Saturday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="visually-hidden">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td><span class="out">28</span></td><td><span class="out">29</span></td><td><span class="out">30</span></td><td><span class="">1</span></td><td><span class="">2</span></td><td><span class="">3</span></td><td><span class="">4</span></td></tr>
        <tr><td><span class="">5</span></td><td><span class="">6</span></td><td><span class="">7</span></td><td><span class="">8</span></td><td><span class="">9</span></td><td><span class="">10</span></td><td><span class="">11</span></td></tr>
        <tr><td><span class="">12</span></td><td><span class="">13</span></td><td aria-current="date"><span class="today">14<span class="visually-hidden">, today</span></span></td><td><span class="">15</span></td><td><span class="">16</span></td><td><span class="">17</span></td><td><span class="">18</span></td></tr>
        <tr><td><span class="">19</span></td><td><span class="">20</span></td><td><span class="">21</span></td><td><span class="">22</span></td><td><span class="">23</span></td><td><span class="">24</span></td><td><span class="">25</span></td></tr>
        <tr><td><span class="">26</span></td><td><span class="">27</span></td><td><span class="">28</span></td><td><span class="">29</span></td><td><span class="">30</span></td><td><span class="">31</span></td><td><span class="out">1</span></td></tr>
      </tbody>
    </table></div>
    <div class="col"><table class="table table-borderless text-center caption-top mb-0">
      <caption>November</caption>
      <thead><tr><th scope="col"><span aria-hidden="true">M</span><span class="visually-hidden">Monday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="visually-hidden">Tuesday</span></th><th scope="col"><span aria-hidden="true">W</span><span class="visually-hidden">Wednesday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="visually-hidden">Thursday</span></th><th scope="col"><span aria-hidden="true">F</span><span class="visually-hidden">Friday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="visually-hidden">Saturday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="visually-hidden">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td><span class="out">26</span></td><td><span class="out">27</span></td><td><span class="out">28</span></td><td><span class="out">29</span></td><td><span class="out">30</span></td><td><span class="out">31</span></td><td><span class="">1</span></td></tr>
        <tr><td><span class="">2</span></td><td><span class="">3</span></td><td><span class="">4</span></td><td><span class="">5</span></td><td><span class="">6</span></td><td><span class="">7</span></td><td><span class="">8</span></td></tr>
        <tr><td><span class="">9</span></td><td><span class="">10</span></td><td><span class="">11</span></td><td><span class="">12</span></td><td><span class="">13</span></td><td><span class="">14</span></td><td><span class="">15</span></td></tr>
        <tr><td><span class="">16</span></td><td><span class="">17</span></td><td><span class="">18</span></td><td><span class="">19</span></td><td><span class="">20</span></td><td><span class="">21</span></td><td><span class="">22</span></td></tr>
        <tr><td><span class="">23</span></td><td><span class="s">24<span class="visually-hidden">, studio closed, first day</span></span></td><td><span class="in">25<span class="visually-hidden">, studio closed</span></span></td><td><span class="in">26<span class="visually-hidden">, studio closed</span></span></td><td><span class="in">27<span class="visually-hidden">, studio closed</span></span></td><td><span class="in">28<span class="visually-hidden">, studio closed</span></span></td><td><span class="in">29<span class="visually-hidden">, studio closed</span></span></td></tr>
        <tr><td><span class="in">30<span class="visually-hidden">, studio closed</span></span></td><td><span class="out">1</span></td><td><span class="out">2</span></td><td><span class="out">3</span></td><td><span class="out">4</span></td><td><span class="out">5</span></td><td><span class="out">6</span></td></tr>
      </tbody>
    </table></div>
    <div class="col"><table class="table table-borderless text-center caption-top mb-0">
      <caption>December</caption>
      <thead><tr><th scope="col"><span aria-hidden="true">M</span><span class="visually-hidden">Monday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="visually-hidden">Tuesday</span></th><th scope="col"><span aria-hidden="true">W</span><span class="visually-hidden">Wednesday</span></th><th scope="col"><span aria-hidden="true">T</span><span class="visually-hidden">Thursday</span></th><th scope="col"><span aria-hidden="true">F</span><span class="visually-hidden">Friday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="visually-hidden">Saturday</span></th><th scope="col"><span aria-hidden="true">S</span><span class="visually-hidden">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td><span class="out">30</span></td><td><span class="in">1<span class="visually-hidden">, studio closed</span></span></td><td><span class="e">2<span class="visually-hidden">, studio closed, last day</span></span></td><td><span class="">3</span></td><td><span class="">4</span></td><td><span class="">5</span></td><td><span class="">6</span></td></tr>
        <tr><td><span class="">7</span></td><td><span class="">8</span></td><td><span class="">9</span></td><td><span class="">10</span></td><td><span class="">11</span></td><td><span class="">12</span></td><td><span class="">13</span></td></tr>
        <tr><td><span class="">14</span></td><td><span class="">15</span></td><td><span class="">16</span></td><td><span class="">17</span></td><td><span class="">18</span></td><td><span class="">19</span></td><td><span class="">20</span></td></tr>
        <tr><td><span class="">21</span></td><td><span class="">22</span></td><td><span class="">23</span></td><td><span class="">24</span></td><td><span class="">25</span></td><td><span class="">26</span></td><td><span class="">27</span></td></tr>
        <tr><td><span class="">28</span></td><td><span class="">29</span></td><td><span class="">30</span></td><td><span class="">31</span></td><td><span class="out">1</span></td><td><span class="out">2</span></td><td><span class="out">3</span></td></tr>
      </tbody>
    </table></div>
  </div>
  <ul class="key list-unstyled d-flex flex-wrap gap-3 mt-3 mb-0" style="font-size:.76rem;color:var(--q-muted)">
    <li class="d-flex align-items-center gap-2"><i aria-hidden="true" style="background:#6d28d9"></i> Range start / end</li>
    <li class="d-flex align-items-center gap-2"><i aria-hidden="true" style="background:#ede7fb"></i> Within range</li>
    <li class="d-flex align-items-center gap-2"><i aria-hidden="true" style="box-shadow:inset 0 0 0 2px #6d28d9"></i> Today</li>
  </ul>
</div>
CSS
/* Bootstrap card, .row-cols grid and .table, restyled through --bs-table-* variables. */
.qcal{--q-accent:#6d28d9;--q-range:#ede7fb;--q-muted:#5f6b7c;
  max-width:820px;padding:22px 24px 24px;border:0;border-radius:16px;box-shadow:0 14px 34px -18px rgba(18,24,40,.25)}
.qcal .table{--bs-table-bg:transparent;--bs-table-color:#2c3546;border-collapse:separate;border-spacing:1px;table-layout:fixed}
.qcal .table>:not(caption)>*>*{padding:0;border:0}
.qcal caption{font-size:.84rem;font-weight:700;color:#191e28;padding:0 0 8px;text-align:center}
.qcal .table th{font-size:.56rem;font-weight:800;color:var(--q-muted);padding:6px 0}
.qcal td > span{aspect-ratio:1;display:grid;place-items:center;font-size:.7rem;font-weight:600;border-radius:6px}
.qcal .out{color:#667284;font-weight:400!important}
.qcal .in{background:var(--q-range);border-radius:0!important}
.qcal .s,.qcal .e{background:var(--q-accent);color:#fff}
.qcal .s{border-radius:6px 0 0 6px!important}.qcal .e{border-radius:0 6px 6px 0!important}
.qcal .today{box-shadow:inset 0 0 0 2px var(--q-accent);color:var(--q-accent)}
.qcal .key i{width:11px;height:11px;border-radius:3px}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div class="qcal w-full max-w-[820px] rounded-2xl bg-white px-6 pt-[22px] pb-6 shadow-[0_14px_34px_-18px_rgba(18,24,40,.25)]">
  <h2 class="mb-0.5 text-[.98rem] font-bold">Q4 2026</h2>
  <p class="mb-[18px] text-[.79rem] text-q-muted">Studio closed 24 Nov – 2 Dec · one range across the month boundary</p>
  <div class="grid grid-cols-3 items-start gap-[26px] max-[720px]:grid-cols-1 max-[720px]:gap-[22px]">
    <table class="w-full table-fixed border-separate border-spacing-px">
      <caption class="pb-2 text-center text-[.84rem] font-bold">October</caption>
      <thead><tr><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">M</span><span class="sr-only">Monday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">T</span><span class="sr-only">Tuesday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">W</span><span class="sr-only">Wednesday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">T</span><span class="sr-only">Thursday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">F</span><span class="sr-only">Friday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">S</span><span class="sr-only">Saturday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">S</span><span class="sr-only">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">28</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">29</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">30</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">1</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">2</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">3</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">4</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">5</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">6</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">7</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">8</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">9</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">10</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">11</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">12</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">13</span></td><td class="p-0" aria-current="date"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-q-accent shadow-[inset_0_0_0_2px_var(--color-q-accent)]">14<span class="sr-only">, today</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">15</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">16</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">17</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">18</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">19</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">20</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">21</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">22</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">23</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">24</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">25</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">26</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">27</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">28</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">29</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">30</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">31</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">1</span></td></tr>
      </tbody>
    </table>
    <table class="w-full table-fixed border-separate border-spacing-px">
      <caption class="pb-2 text-center text-[.84rem] font-bold">November</caption>
      <thead><tr><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">M</span><span class="sr-only">Monday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">T</span><span class="sr-only">Tuesday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">W</span><span class="sr-only">Wednesday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">T</span><span class="sr-only">Thursday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">F</span><span class="sr-only">Friday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">S</span><span class="sr-only">Saturday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">S</span><span class="sr-only">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">26</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">27</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">28</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">29</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">30</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">31</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">1</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">2</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">3</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">4</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">5</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">6</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">7</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">8</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">9</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">10</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">11</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">12</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">13</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">14</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">15</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">16</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">17</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">18</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">19</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">20</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">21</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">22</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">23</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-l-md bg-q-accent text-white">24<span class="sr-only">, studio closed, first day</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold bg-q-range text-[#2c3546]">25<span class="sr-only">, studio closed</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold bg-q-range text-[#2c3546]">26<span class="sr-only">, studio closed</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold bg-q-range text-[#2c3546]">27<span class="sr-only">, studio closed</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold bg-q-range text-[#2c3546]">28<span class="sr-only">, studio closed</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold bg-q-range text-[#2c3546]">29<span class="sr-only">, studio closed</span></span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold bg-q-range text-[#2c3546]">30<span class="sr-only">, studio closed</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">1</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">2</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">3</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">4</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">5</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">6</span></td></tr>
      </tbody>
    </table>
    <table class="w-full table-fixed border-separate border-spacing-px">
      <caption class="pb-2 text-center text-[.84rem] font-bold">December</caption>
      <thead><tr><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">M</span><span class="sr-only">Monday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">T</span><span class="sr-only">Tuesday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">W</span><span class="sr-only">Wednesday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">T</span><span class="sr-only">Thursday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">F</span><span class="sr-only">Friday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">S</span><span class="sr-only">Saturday</span></th><th scope="col" class="py-1.5 text-center text-[.56rem] font-extrabold text-q-muted"><span aria-hidden="true">S</span><span class="sr-only">Sunday</span></th></tr></thead>
      <tbody>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">30</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold bg-q-range text-[#2c3546]">1<span class="sr-only">, studio closed</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-r-md bg-q-accent text-white">2<span class="sr-only">, studio closed, last day</span></span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">3</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">4</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">5</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">6</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">7</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">8</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">9</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">10</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">11</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">12</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">13</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">14</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">15</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">16</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">17</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">18</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">19</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">20</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">21</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">22</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">23</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">24</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">25</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">26</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">27</span></td></tr>
        <tr><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">28</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">29</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">30</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md text-[#2c3546]">31</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">1</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">2</span></td><td class="p-0"><span class="grid aspect-square place-items-center text-[.7rem] font-semibold rounded-md font-normal text-[#667284]">3</span></td></tr>
      </tbody>
    </table>
  </div>
  <ul class="mt-[18px] flex flex-wrap gap-4 text-[.76rem] text-q-muted">
    <li class="flex items-center gap-1.5"><i aria-hidden="true" class="size-[11px] rounded-[3px] bg-q-accent"></i> Range start / end</li>
    <li class="flex items-center gap-1.5"><i aria-hidden="true" class="size-[11px] rounded-[3px] bg-q-range"></i> Within range</li>
    <li class="flex items-center gap-1.5"><i aria-hidden="true" class="size-[11px] rounded-[3px] shadow-[inset_0_0_0_2px_var(--color-q-accent)]"></i> Today</li>
  </ul>
</div>
CSS
@theme {
  --color-q-accent: #6d28d9;
  --color-q-range: #ede7fb;
  --color-q-muted: #5f6b7c;
}

About this set

Three months side by side, October to December 2026, with today ringed and a closure range from 24 November to 2 December that runs across the month boundary. A key under the months explains the range start and end, the days within the range and today. Use it for planning screens, holiday and leave calendars, school terms or any view where a range spans more than one month. Each month is a real table with a caption and weekday column headers that carry the full day name for screen readers. The range is drawn with three classes, a rounded start, flat middle cells and a rounded end, and every range day also contains visually hidden text such as studio closed, first day, so the information is not carried by colour alone. Today has aria-current=”date”. Days from the neighbouring months are shown in a lighter weight but still reach 4.5:1 contrast. On narrow screens the three months stack into one column (below 720 pixels, or the md breakpoint in Bootstrap). The Bootstrap version uses .row-cols for the columns and .table for each month, and the Tailwind version builds the same tables from utilities.

What’s included

  • Three month tables with captions and weekday headers
  • A date range that crosses a month boundary
  • Range and today stated in hidden text, not only colour
  • aria-current="date" on today
  • Stacks to one column on narrow screens

Accessibility

Each month is a table with a caption and column headers whose visually hidden text gives the full weekday name. Range days include hidden text describing the closure and today has aria-current="date" plus hidden "today" text. There are no interactive controls and nothing animates.

Customise it

Change --q-accent, --q-range and --q-muted on .qcal in plain CSS and Bootstrap, or the --color-q-* theme colours in Tailwind. Mark days with the s, in, e and today classes.