Search code examples
htmlcssflexboxcss-grid

How to overlap the child element of a grid item to the next column?


So, i want to build a calendar, which displays the current month. So I build the calender with an css grid. Now i want to add events, which could durate longer than a day(a is a grid item). The problem I face now, is that the div element, which should display my event, is the child element of the grid item, so I can't just add grid-column: span 2; to adjust the length of the event over multiple days. How can a child of the grid-item (which is the day of the month) can overlap to the next calendar day?

Edit: To turn up the width to 200% would be a solution,but then the event of the next day wouldn't align with the current event. At the latest, at window resize, those two lines wouldn't line up anymore. enter image description here

I made a quick mock of my project to show the problem more visually: https://codepen.io/eliasroebl/pen/yLMXOwy

<div class="Calendar calendar">
  <div class="calendar__header">
    <div>Monday</div>
    <div>Tuesday</div>
    <div>Wednesday</div>
    <div>Thursday</div>
    <div>Friday</div>
    <div>Saturday</div>
    <div>Sunday</div>
  </div>
  <div class="calendar__week">
    <div class="calendar__day day">1</div>
    <div class="calendar__day day">2</div>
    <div class="calendar__day day">3</div>
    <div class="calendar__day day">4</div>
    <div class="calendar__day day">5</div>
    <div class="calendar__day day">6</div>
    <div class="calendar__day day">7</div>
  </div>
  <div class="calendar__week">
    <div class="calendar__day day">8</div>
    <div class="calendar__day day">9
      <div class="event">
        Event 1
      </div>
    </div>
    <div class="calendar__day day">10</div>
    <div class="calendar__day day">11</div>
    <div class="calendar__day day">12</div>
    <div class="calendar__day day">13</div>
    <div class="calendar__day day">14</div>
  </div>
  <div class="calendar__week">
    <div class="calendar__day day">15</div>
    <div class="calendar__day day">16</div>
    <div class="calendar__day day">17</div>
    <div class="calendar__day day">18</div>
    <div class="calendar__day day">19</div>
    <div class="calendar__day day">20</div>
    <div class="calendar__day day">21</div>
  </div>
  <div class="calendar__week">
    <div class="calendar__day day">22</div>
    <div class="calendar__day day">23</div>
    <div class="calendar__day day">24</div>
    <div class="calendar__day day">25</div>
    <div class="calendar__day day">26</div>
    <div class="calendar__day day">27</div>
    <div class="calendar__day day">28</div>
  </div>
</div>
</div>
.calendar__week,
.calendar__header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
.calendar__week {
  grid-auto-rows: 6vw;
  text-align: right;
}

.different_month_days{
  background-color: #c1d5e0;
}


.event{
  grid-column: col 2 / span 4;
  grid-row: 2;
  background-color: aqua;
  border-radius: 5vw;
  text-align: left;
}



.calendar__header {
  grid-auto-rows: 3vw;
  align-items: center;
  text-align: center;
  font-family: Montserrat;
  background-color: #8f9bff;

}

.calendar__day {
  padding: 16px;
  font-family: Montserrat;
}

.calendar {
  background-color: white;
  border: 1px solid #e1e1e1;
}

.calendar__header > div {
  text-transform: uppercase;
  font-size: 1em;
  font-weight: bold;
}

.calendar__day {
  border-right: 1px solid  #e1e1e1;
  border-top: 1px solid #e1e1e1;

}

.calendar__day:last-child {
  border-right: 0;
}

Thanks already for the help


Solution

  • Here you go...

    Inspired by this codepen.

    I changed the code a little bit and made it more responsive because the source code on codepen wasn't responsive at all. Colorful boxes and all the text (days of the week, numbers and event text) are now responsive.

    I solved your main problem with events not aligning when resizing the window. The events now align perfectly regardless of the window size.

    For example, the first event with class='event--1' starts at the third box and is spread across the next two boxes which is done with grid-column: 3 / span 2;. The second event with class='event--2' starts at the fourth box and is spread across the next three boxes which is done with grid-column: 4 / span 3;.

    But you also have to put these boxes which have assigned events kind of "back into place". For the fifteenth box this is done with the following CSS:

    div.date:nth-child(15) {
      grid-column: 3;
      grid-row: 3;
    }
    

    Try to delete this from the CSS and you will get the point.

    Also, I used a little bit of Bootstrap 5 to be able to vertically align days of the week.

    .days {
      font-size: 1.2vw;
      height: 8vh;
      font-weight: 700;
    }
    
    .main-content {
      display: grid;
      grid-auto-flow: row;
      grid-template-rows: repeat(4, 35vh);
      grid-template-columns: repeat(7, minmax(calc(100vw/7), 1fr));
    }
    
    .date {
      background: var(--color);
      padding: 4%;
      position: relative;
      font-size: 1.3vw;
    }
    
    .event {
      z-index: 10;
      background: transparent;
      height: 10%;
      padding-top: 2.3vw;
    }
    
    .event--1 {
      grid-column: 3 / span 2;
      grid-row: 3;
    }
    
    .event--2 {
      grid-column: 4 / span 3;
      grid-row: 3;
      padding-top: 6vw;
    }
    
    .event__name {
      background: rgba(255, 255, 255, 0.4);
      border-radius: 10vw;
      height: 2.5vh;
      padding: 10px;
      margin: 10px;
      font-size: 0.9vw;
    }
    
    div.date:nth-child(15) {
      grid-column: 3;
      grid-row: 3;
    }
    
    div.date:nth-child(16) {
      grid-column: 4;
      grid-row: 3;
    }
    
    div.date:nth-child(17) {
      grid-column: 5;
      grid-row: 3;
    }
    
    div.date:nth-child(18) {
      grid-column: 6;
      grid-row: 3;
    }
    <!DOCTYPE html>
    <html lang='en'>
    
    <head>
      <meta charset='UTF-8'>
      <meta http-equiv='X-UA-Compatible' content='IE=edge'>
      <meta name='viewport' content='width=device-width, initial-scale=1.0'>
      <title>Document</title>
      <link href='https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css' rel='stylesheet' integrity='sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl' crossorigin='anonymous'>
    </head>
    
    <body>
    
      <div class='d-flex align-items-center days'>
        <div class='col text-center'>Monday</div>
        <div class='col text-center'>Tuesday</div>
        <div class='col text-center'>Wednesday</div>
        <div class='col text-center'>Thursday</div>
        <div class='col text-center'>Friday</div>
        <div class='col text-center'>Saturday</div>
        <div class='col text-center'>Sunday</div>
      </div>
    
      <div class='main-content'>
        <div class='date' style='--color:#db7f7a'>1</div>
        <div class='date' style='--color:#db847a'>2</div>
        <div class='date' style='--color:#db8d7a'>3</div>
        <div class='date' style='--color:#db8d7a'>4</div>
        <div class='date' style='--color:#db917a'>5</div>
        <div class='date' style='--color:#db967a'>6</div>
        <div class='date' style='--color:#db9a7a'>7</div>
        <div class='date' style='--color:#db9a7a'>8</div>
        <div class='date' style='--color:#db9f7a'>9</div>
        <div class='date' style='--color:#dba37a'>10</div>
        <div class='date' style='--color:#dba87a'>11</div>
        <div class='date' style='--color:#dbac7a'>12</div>
        <div class='date' style='--color:#dbb07a'>13</div>
        <div class='date' style='--color:#dbb57a'>14</div>
        <div class='date' style='--color:#dbbe7a'>15</div>
        <div class='date' style='--color:#dbc27a'>16</div>
        <div class='date' style='--color:#dbc77a'>17</div>
        <div class='date' style='--color:#dbd07a'>18</div>
        <div class='date' style='--color:#dbd47a'>19</div>
        <div class='date' style='--color:#dbd97a'>20</div>
        <div class='date' style='--color:#d9db7a'>21</div>
        <div class='date' style='--color:#d0db7a'>22</div>
        <div class='date' style='--color:#cbdb7a'>23</div>
        <div class='date' style='--color:#c7db7a'>24</div>
        <div class='date' style='--color:#c2db7a'>25</div>
        <div class='date' style='--color:#bedb7a'>26</div>
        <div class='date' style='--color:#b9db7a'>27</div>
        <div class='date' style='--color:#b5db7a'>28</div>
    
        <div class='event event--1'>
          <div class='event__name d-flex align-items-center justify-content-center'>Valentines party with Ames ❤️</div>
        </div>
        <div class='event event--2'>
          <div class='event__name d-flex align-items-center justify-content-center'>Die Hard binge weekend 😎</div>
        </div>
      </div>
    
    </body>
    
    </html>