Schedule Timetable — Free HTML CSS Snippet

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

Share & Support

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.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to work out the today-column and rowspan interactions on your own. Paste this snippet's HTML and CSS into an AI coding assistant like Claude and ask it to explain exactly why removing the wrong td when adding rowspan misaligns every following column, and how the .today header class and the .today-col cell class have to be kept in sync across a whole column rather than a single cell. The same assistant is useful for optimizing it — ask whether hand-maintaining rowspan and today-column classes in static markup will scale to a real booking calendar with dozens of events, or whether the table should instead be generated from a data array with a small render function. It is just as useful for extending the effect — ask it to add click-to-book event creation on empty cells, compute the today column automatically from the real date instead of a hardcoded class, or add 30-minute slot resolution. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a weekly schedule timetable in plain HTML and CSS, using a semantic HTML table (not CSS grid or flexbox) as the layout mechanism, with only a minimal amount of optional JavaScript for interactivity.

Requirements:
- A table with one header row showing five weekday columns plus a narrow leading time column, and one body row per hourly time slot from 9:00 to 16:00, with the time value right-aligned in the first cell of each row.
- Event entries are divs placed inside the relevant day/time td, each carrying one of at least six color-variant classes (for example indigo, blue, green, pink, orange, teal), each variant using a low-saturation tinted rgba background with a matching darker text color, sharing identical padding, font size, and border-radius across all variants.
- The current day's column must be visually distinguished with a two-part highlight: a class on that column's th showing an accent color and a filled circle around the date number, and a matching class on every td in that same column applying a soft tinted background — both classes must move together if the current day changes.
- Support events that span multiple hours using the native rowspan attribute on the td, with the corresponding td removed from each subsequent row for that column so the table does not misalign.
- Wrap the table in a container with overflow-x: auto so the grid scrolls horizontally on narrow viewports while remaining readable, with a minimum column width that prevents columns from compressing below a legible size.
- Add week navigation (Prev/Next) controls and a week-range label above the table, styled but not necessarily wired to real date logic.

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.

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.