webdevpuneet.com

Schedule Timetable — Free HTML CSS Snippet

Schedule / Timetable · Tables · Plain HTML & CSS · Live preview

CategoryTables

Copy & paste

Source Code

<div class="schedule-wrap">
  <div class="schedule-header">
    <h2 class="schedule-title">Weekly Schedule</h2>
    <div class="week-nav">
      <button class="nav-btn">← Prev</button>
      <span class="week-label">May 26 – Jun 1, 2025</span>
      <button class="nav-btn">Next →</button>
    </div>
  </div>
  <div class="table-scroll">
  <table class="schedule-table">
    <thead>
      <tr>
        <th class="time-col"></th>
        <th>Mon <span class="day-num">26</span></th>
        <th>Tue <span class="day-num">27</span></th>
        <th class="today">Wed <span class="day-num today-num">28</span></th>
        <th>Thu <span class="day-num">29</span></th>
        <th>Fri <span class="day-num">30</span></th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="time-label">9:00</td>
        <td><div class="event indigo">Team standup<span>9:00–9:30</span></div></td>
        <td><div class="event indigo">Team standup<span>9:00–9:30</span></div></td>
        <td class="today-col"><div class="event indigo">Team standup<span>9:00–9:30</span></div></td>
        <td><div class="event indigo">Team standup<span>9:00–9:30</span></div></td>
        <td><div class="event indigo">Team standup<span>9:00–9:30</span></div></td>
      </tr>
      <tr>
        <td class="time-label">10:00</td>
        <td><div class="event blue">Design review<span>10:00–11:00</span></div></td>
        <td></td>
        <td class="today-col"></td>
        <td><div class="event green">1:1 with PM<span>10:00–10:30</span></div></td>
        <td></td>
      </tr>
      <tr>
        <td class="time-label">11:00</td>
        <td></td>
        <td><div class="event pink">Sprint planning<span>11:00–12:30</span></div></td>
        <td class="today-col"><div class="event orange">Client call<span>11:00–11:45</span></div></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td class="time-label">12:00</td>
        <td></td>
        <td></td>
        <td class="today-col"></td>
        <td></td>
        <td><div class="event teal">Team lunch<span>12:00–13:00</span></div></td>
      </tr>
      <tr>
        <td class="time-label">14:00</td>
        <td><div class="event teal">Code review<span>14:00–15:00</span></div></td>
        <td></td>
        <td class="today-col"><div class="event blue">Architecture review<span>14:00–15:30</span></div></td>
        <td></td>
        <td><div class="event pink">Retro<span>14:00–15:00</span></div></td>
      </tr>
      <tr>
        <td class="time-label">15:00</td>
        <td></td>
        <td><div class="event orange">Workshop<span>15:00–17:00</span></div></td>
        <td class="today-col"></td>
        <td><div class="event green">Demo prep<span>15:00–16:00</span></div></td>
        <td></td>
      </tr>
      <tr>
        <td class="time-label">16:00</td>
        <td></td>
        <td></td>
        <td class="today-col"></td>
        <td><div class="event indigo">Product demo<span>16:00–17:00</span></div></td>
        <td></td>
      </tr>
    </tbody>
  </table>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Weekly calendar grid: days as columns, hourly time slots as rows via HTML table
Six colour-coded event variants using rgba tinted backgrounds with matching text colours
.today class on header + .today-col on all cells highlights the current day column
Event divs fill cell height via height: 100% and display: flex for name + time layout
.time-col right-aligned with min-width for consistent time label column
overflow-x: auto on .schedule-wrap — horizontal scroll on narrow screens
Week navigation Prev/Next buttons for date-range browsing
rowspan support: remove next-row td for multi-hour events
Pure HTML and CSS — no JavaScript required for layout
Export as HTML file, React JSX component, or React + Tailwind CSS

About this UI Snippet

Schedule Timetable — Weekly Calendar Grid, Colour-Coded Events & Today Column Highlight

Screenshot of the Schedule / Timetable snippet rendered live

A weekly schedule timetable displays events in a calendar grid — days as columns across the top, time slots as rows down the left. This layout is used in team meeting calendars, class timetables, booking systems, shift schedules, and project sprint planners. This snippet gives you a complete HTML CSS schedule grid with six event colour types, a today column highlight, week navigation controls, and horizontal scroll for mobile — no JavaScript required for the base layout.

How the grid structure works

The timetable is a standard HTML table where each column is a weekday (Mon–Fri) and each row is an hourly time slot (9:00 AM to 4:00 PM). The first column (.time-col) displays the hour label, right-aligned. Each subsequent cell is a day/time intersection where events can be placed. Event blocks are .event divs inside cells — they use height: 100% and display: flex to fill the cell vertically and show the event name and time as a flex column.

Six colour-coded event types

Six colour variants (.indigo, .blue, .green, .pink, .orange, .teal) differentiate event categories. Each uses an rgba() tinted background with matching text colour — rgba(99,102,241,0.12) with #3730a3 text for indigo, for example. The colours are low-saturation tints so multiple events on the same day do not create visual chaos. All six variants share the same padding, font size, and border-radius for visual consistency.

Today column highlight

The current day column gets a two-part treatment: the column header th gets .today which applies an accent colour and shows the day number in a filled circle. Each cell in that column gets .today-col which applies a soft tinted background. This is the same pattern used by Google Calendar and Apple Calendar — users recognise it immediately as "today." Moving it to a different column requires only moving the .today class on the header and .today-col on the cells.

Making events span multiple hours

To make an event fill two hours, use rowspan="2" on the td: the cell takes up two row heights automatically. Remove the td that would have appeared in the next row for that column. The event div inside the tall cell stretches to fill the full height. For 30-minute resolution, add half-hour rows with reduced cell height in CSS.

Responsive horizontal scroll

A five-day schedule grid is inherently wider than most phone screens. The .schedule-wrap wrapper uses overflow-x: auto — the table scrolls horizontally while the time column stays visible. The minimum cell width prevents columns from becoming too narrow to read on any device.

Adding event interaction

The snippet is pure HTML and CSS by default. Add click-to-book functionality with a few lines of JavaScript: attach a click listener to each empty td, create an .event div inside it on click, and prompt for an event title. For a full booking system, use a modal (see the Modal snippet) for the event details form, and a calendar widget for month-level date picking.

Step by step

How to Use

  1. 1
    Update event text and colourIn the HTML panel, change the event div text and the .time span inside each event. Change the colour class on each event div (.indigo, .blue, .green, .pink, .orange, or .teal) to match your category.
  2. 2
    Update day headers and date numbersChange the day name text (Mon, Tue...) and the .day-num span inside each th to the actual date numbers for the current week. Update the .week-label text above the table.
  3. 3
    Mark the correct today columnMove the .today class to the th for the current day. Move .today-col to every td in that same column. Remove .today and .today-col from all other headers and cells.
  4. 4
    Make an event span multiple hoursAdd rowspan="2" (or more) to the td containing the event. Remove the td that would appear in the next row for that same column. The event div stretches to fill the taller cell automatically.
  5. 5
    Add a new event colourAdd a CSS rule in the panel: .event.purple { background: rgba(168,85,247,0.12); color: #7c3aed; } Then use class="event purple" on any event div to apply the new colour.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component mapping a timeSlots and events array, or "Tailwind" for a React + Tailwind CSS version.

Real-world uses

Common Use Cases

Team meeting calendars and shared weekly schedules
Show the week view of team meetings, standups, reviews, and workshops. Colour-code by team — engineering meetings in indigo, design sessions in pink, company all-hands in orange — so anyone can read the calendar at a glance.
Class and course timetables for education platforms
Display weekly class schedules with subjects colour-coded by course. Use rowspan to indicate double-period or multi-hour lessons. The time-label column keeps every row anchored to a readable hour.
Booking and appointment scheduling interfaces
Render available slots as empty cells with a hover highlight and booked slots as .event divs. Add a click listener to empty cells to trigger a booking modal. The weekly grid layout matches the mental model users already have from calendar apps.
Learn HTML table as a pixel-aligned visual grid
The timetable uses a plain HTML table — not CSS Grid or Flexbox — as the layout mechanism. Table cells create perfectly aligned rows and columns with no float or position tricks. Studying the structure teaches when HTML tables are still the right layout tool for aligned grid data.
Sprint and project planning calendar views
Display sprint tasks and milestones in a weekly grid. Use rowspan for multi-day tasks. Each cell can show a task name, owner avatar initials, and a status colour. Combine with the Data Table snippet for a list/calendar toggle view.
Employee shift and rota scheduling tables
Show staff shifts across Mon–Sun with morning, afternoon, and night slot rows. Each cell shows an employee name or initials with a shift-type colour badge. Empty cells indicate days off. Add a weekend Sat and Sun column for 7-day rotas.
Related: Table Column Visibility Toggle Menu
See the Table Column Visibility Toggle Menu for a related tables pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Add rowspan="2" to the td that contains the event div — this makes the cell occupy two row heights. For each additional hour of span, increase the rowspan number. Remove the corresponding td cells from the next rows for that same column — if you do not remove them, the table will have extra cells and the columns will misalign.

Read the current day: const dayIndex = new Date().getDay() (0=Sunday, 1=Monday, ..., 5=Friday). Map dayIndex to a column number (column 2 = Monday, column 6 = Friday for a Mon-Fri table). Then: document.querySelector("th:nth-child(" + colNum + ")").classList.add("today"); document.querySelectorAll("td:nth-child(" + colNum + ")").forEach(td => td.classList.add("today-col"));

Add half-hour tr rows between each hourly row: duplicate the tr and change the .time-label to "9:30", "10:30", etc. Reduce the td min-height in the CSS to keep the layout compact — 40-48px per half-hour slot works well. For multi-hour events at 30-minute resolution, increase the rowspan accordingly.

Add a click listener to each empty td: td.addEventListener("click", function() { if (this.querySelector(".event")) return; const title = prompt("Event name:"); if (!title) return; const ev = document.createElement("div"); ev.className = "event indigo"; ev.textContent = title; this.appendChild(ev); }). For a better UX, replace prompt() with the Modal snippet for a proper event creation form.

Add two more th elements to the header row for Sat and Sun. Add corresponding td cells to every time-slot row. For weekends, optionally apply a different background: th:nth-child(6), th:nth-child(7), td:nth-child(6), td:nth-child(7) { background: #f8fafc; } to visually distinguish work days from weekends.

Define a timeSlots array (["9:00 AM", "10:00 AM", ...]) and a days array (["Mon", "Tue", ...]). Define an events array with day, time, title, and colour properties. Map timeSlots to tr rows. Inside each row, map days to td cells. Find events matching the current day+time with events.find(e => e.day === day && e.time === slot). Render the event div or an empty cell. Apply .today class conditionally based on the current date.