Search code examples
htmlcssreactjshtml-table

How to adjust html table borders and column width?


I want to change styles of html table. Right now it looks like this:enter image description here

And here is the code:

    <div className="student-schedule">
      <table className="student-calendar-table">
        <thead>
          <tr>
            <th className=''></th>
            {weekDays.map((day) => (
              <th className='student-th border-left' colSpan={6} key={day}>
                {day}
              </th>
            ))}
          </tr>
          <tr>
            <th className=''></th>
            {dates.map((date) => (
              <th className='student-th border-left' colSpan={6} key={date}>
                {date}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {timeSlots.map((time, i) => (
            <tr key={time}>
              <td className='student-td cell'>{time}</td>
              {tableCells[i].map((cell, index) => {
                const cellsLen = cell.length;
                const tdElements = [];
                if (cellsLen < 4) {
                  for (let j = 0; j < cellsLen; j++) {
                    tdElements.push(<td onClick={() => handleCellClick(cell[j])} className={findCss(cell[j], j)} key={index + '-' + j} colSpan={6 / cellsLen}>{cell[j].isReserved ? cell[j].lessonWith : cell[j].lessonWith}</td>);
                  }
                  return tdElements;
                }
                else {
                  return (<td onClick={() => OpenMultipleInstructorPopupVisible(cell)} className='student-td multiple-instructors student-block border-left' colSpan={6}>3+ osoby</td>);
                }

              })}

            </tr>
          ))}
        </tbody>
      </table>
      <div>
        {isReservationPopupVisible && <ReservationPopup onClose={closePopup} block={block} myReservations={myReservations} blocks={blocks} />}
        {isMultipleInstructorPopupVisible && <MultipleInstructorsPopup onClose={closePopup} blocks={extraInstructors} myReservations={myReservations} allBlocks={blocks} />}
      </div>
    </div>

and CSS:

.student-th{
  color: rgb(71, 71, 71);
}
.student-td {
  border-radius: 10px;
  border-right: 3px solid #dedbd9; 
  border-left: 3px solid #dedbd9; 
  border-top: 1px solid #dedbd9; 
  border-bottom: 1px solid #dedbd9;
  color: rgb(71, 71, 71);
  box-sizing:content-box;
}

.student-calendar-table {
  border-collapse: separate;
  background-color: #dedbd9;
  margin: auto;
  width: 98%;
  border-radius: 30px; 
  overflow: hidden;
  margin: 0 auto; 
}

/* .border-left {
  border-left: 10px solid #f70b0b;
} */

.cell {
  height: 80px;
}

.student-block {
  cursor: pointer;
  transition: background-color 0.3s;
  text-align: center;
  color: rgb(71, 71, 71);
}

all that findCss function does is handle the colors. I have been struggling with 2 things very bad:

  1. Set same width for each column, regardless of how many blocks are in the column
  2. Space between each day column I would like it to be like in the screenshot below, where the width for columns (marked blue boxes) is same size and there is nice gap between the columns that does not cut the left border of the first cells in each column (marked red). Now I achieved this cutting gap by setting border-left for each first cell like this:
.border-left {
  border-left: 10px solid #dedbd9;
}

But it does not solve the issue as the left side is cut. I will be gratefull for help

enter image description here

<div class="student-schedule"><table class="student-calendar-table"><thead><tr><th class=""></th><th class="student-th border-left" colspan="6" style="width: 200px;">Poniedziałek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Wtorek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Środa</th><th class="student-th border-left" colspan="6" style="width: 200px;">Czwartek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Piątek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Sobota</th><th class="student-th border-left" colspan="6" style="width: 200px;">Niedziela</th></tr><tr><th class=""></th><th class="student-th border-left" colspan="6" style="width: 200px;">13/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">14/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">15/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">16/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">17/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">18/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">19/11/2023</th></tr></thead><tbody><tr><td class="student-td cell">8:00</td><td class="student-td student-block instructor-0 border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1" colspan="3">Aneta Gajos</td><td class="student-td student-block instructor-2 border-left" colspan="2">Krzysztof Wiśniewski</td><td class="student-td not-available student-block-unavailable" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-1 border-left" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-2" colspan="2">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-0 border-left" colspan="6">Paweł Jankowski</td><td class="student-td student-block instructor-0 border-left" colspan="6">Paweł Jankowski</td><td class="student-td student-block instructor-2 border-left" colspan="6">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-0 border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-3" colspan="3">Robert Maj</td></tr><tr><td class="student-td cell">10:00</td><td class="student-td student-block instructor-0 border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1" colspan="3">Aneta Gajos</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td><td class="student-td not-available student-block-unavailable" colspan="2">Aneta Gajos</td><td class="student-td not-available student-block-unavailable" colspan="2">Krzysztof Wiśniewski</td><td class="student-td reserved-by-me student-block" colspan="2">Robert Maj</td><td class="student-td student-block instructor-3 border-left" colspan="3">Robert Maj</td><td class="student-td student-block instructor-0" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-2 border-left" colspan="3">Krzysztof Wiśniewski</td><td class="student-td not-available student-block-unavailable" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1 border-left" colspan="3">Aneta Gajos</td><td class="student-td student-block instructor-2" colspan="3">Krzysztof Wiśniewski</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td></tr><tr><td class="student-td cell">12:00</td><td class="student-td student-block instructor-0 border-left" colspan="3">Paweł Jankowski</td><td class="student-td not-available student-block-unavailable" colspan="3">Aneta Gajos</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td><td class="student-td student-block instructor-1 border-left" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-2" colspan="2">Krzysztof Wiśniewski</td><td class="student-td not-available student-block-unavailable" colspan="2">Robert Maj</td><td class="student-td student-block instructor-3 border-left" colspan="3">Robert Maj</td><td class="student-td student-block instructor-0" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-2 border-left" colspan="2">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-0" colspan="2">Paweł Jankowski</td><td class="student-td not-available student-block-unavailable border-left" colspan="2">Aneta Gajos</td><td class="student-td not-available student-block-unavailable" colspan="2">Robert Maj</td><td class="student-td not-available student-block-unavailable" colspan="2">Krzysztof Wiśniewski</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td></tr><tr><td class="student-td cell">14:00</td><td class="student-td not-available student-block-unavailable border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1" colspan="3">Aneta Gajos</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td><td class="student-td student-block instructor-1 border-left" colspan="2">Aneta Gajos</td><td class="student-td not-available student-block-unavailable" colspan="2">Krzysztof Wiśniewski</td><td class="student-td not-available student-block-unavailable" colspan="2">Robert Maj</td><td class="student-td student-block instructor-3 border-left" colspan="3">Robert Maj</td><td class="student-td student-block instructor-0" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-2 border-left" colspan="2">Krzysztof Wiśniewski</td><td class="student-td not-available student-block-unavailable" colspan="2">Robert Maj</td><td class="student-td not-available student-block-unavailable" colspan="2">Paweł Jankowski</td><td class="student-td student-block instructor-1 border-left" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-2" colspan="2">Krzysztof Wiśniewski</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td></tr><tr><td class="student-td cell">16:00</td><td class="student-td not-available student-block-unavailable border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1" colspan="3">Aneta Gajos</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td><td class="student-td student-block instructor-2 border-left" colspan="3">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-3" colspan="3">Robert Maj</td><td class="student-td student-block instructor-3 border-left" colspan="3">Robert Maj</td><td class="student-td student-block instructor-0" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-2 border-left" colspan="2">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-0" colspan="2">Paweł Jankowski</td><td class="student-td not-available student-block-unavailable border-left" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-2" colspan="2">Krzysztof Wiśniewski</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td></tr><tr><td class="student-td cell">18:00</td><td class="student-td not-available student-block-unavailable border-left" colspan="6">Paweł Jankowski</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td><td class="student-td student-block instructor-2 border-left" colspan="3">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-3" colspan="3">Robert Maj</td><td class="student-td student-block instructor-3 border-left" colspan="3">Robert Maj</td><td class="student-td student-block instructor-0" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-3 border-left" colspan="6">Robert Maj</td><td class="student-td student-block instructor-1 border-left" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-2" colspan="2">Krzysztof Wiśniewski</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td></tr><tr><td class="student-td cell">20:00</td></tr></tbody></table><div></div></div>

Solution

  • This is incredibly challenging and I have failed. The best I could do was to use width and min-width to balance the columns and a pseudo element to add a border where you wanted a wider gap.

    .student-th{
      color: rgb(71, 71, 71);
      width:calc(100% / 7);
      max-width:calc(100% / 7);
      min-width:calc(100% / 7);
      border-right: 3px solid #dedbd9; 
      border-left: 3px solid #dedbd9; 
      border-top: 1px solid #dedbd9; 
      border-bottom: 1px solid #dedbd9;
    }
    .student-td {
      border-radius: 10px;
      border-right: 3px solid #dedbd9; 
      border-left: 3px solid #dedbd9; 
      border-top: 1px solid #dedbd9; 
      border-bottom: 1px solid #dedbd9;
      color: rgb(71, 71, 71);
      box-sizing:content-box;
      background-color: rgb(200, 200, 71);
      width:calc(100% / 43);
      min-width:calc(100% / 43);
      overflow-wrap: anywhere;
    }
    
    .student-calendar-table {
      border-collapse: separate;
      background-color: #dedbd9;
      margin: auto;
      width: 98%;
      border-radius: 30px; 
      overflow: hidden;
      margin: 0 auto; 
    }
    
    .border-left {
        position:relative;
    }
    .border-left:before {
        content: "";
        display: block;
        border-radius: 10px;
        background: #7d7d7d;
        position: absolute;
        top: 0;
        bottom: -4px;
        left: -5px;
        width: 2px;
    }
    
    .cell {
      height: 80px;
    }
    
    .student-block {
      cursor: pointer;
      transition: background-color 0.3s;
      text-align: center;
      color: rgb(71, 71, 71);
    }
    <div class="student-schedule"><table class="student-calendar-table"><thead><tr><th class=""></th><th class="student-th border-left" colspan="6" style="width: 200px;">Poniedziałek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Wtorek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Środa</th><th class="student-th border-left" colspan="6" style="width: 200px;">Czwartek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Piątek</th><th class="student-th border-left" colspan="6" style="width: 200px;">Sobota</th><th class="student-th border-left" colspan="6" style="width: 200px;">Niedziela</th></tr><tr><th class=""></th><th class="student-th border-left" colspan="6" style="width: 200px;">13/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">14/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">15/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">16/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">17/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">18/11/2023</th><th class="student-th border-left" colspan="6" style="width: 200px;">19/11/2023</th></tr></thead><tbody><tr><td class="student-td cell">8:00</td><td class="student-td student-block instructor-0 border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1" colspan="3">Aneta Gajos</td><td class="student-td student-block instructor-2 border-left" colspan="2">Krzysztof Wiśniewski</td><td class="student-td not-available student-block-unavailable" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-1 border-left" colspan="2">Aneta Gajos</td><td class="student-td student-block instructor-2" colspan="2">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-3" colspan="2">Robert Maj</td><td class="student-td student-block instructor-0 border-left" colspan="6">Paweł Jankowski</td><td class="student-td student-block instructor-0 border-left" colspan="6">Paweł Jankowski</td><td class="student-td student-block instructor-2 border-left" colspan="6">Krzysztof Wiśniewski</td><td class="student-td student-block instructor-0 border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-3" colspan="3">Robert Maj</td></tr><tr><td class="student-td cell">10:00</td><td class="student-td student-block instructor-0 border-left" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1" colspan="3">Aneta Gajos</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td><td class="student-td not-available student-block-unavailable border-left" colspan="2">Aneta Gajos</td><td class="student-td not-available student-block-unavailable" colspan="2">Krzysztof Wiśniewski</td><td class="student-td reserved-by-me student-block" colspan="2">Robert Maj</td><td class="student-td student-block instructor-3 border-left" colspan="3">Robert Maj</td><td class="student-td student-block instructor-0" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-2 border-left" colspan="3">Krzysztof Wiśniewski</td><td class="student-td not-available student-block-unavailable" colspan="3">Paweł Jankowski</td><td class="student-td student-block instructor-1 border-left" colspan="3">Aneta Gajos</td><td class="student-td student-block instructor-2" colspan="3">Krzysztof Wiśniewski</td><td class="student-td multiple-instructors student-block border-left" colspan="6">3+ osoby</td></tr></tr></tbody></table><div></div></div>

    I recommend entirely rewriting it to use css grid instead!