- Building a vertical calendar with HTML, CSS & JS
- Result
- Getting started
- The Hour Grid: Basic Setup
- Hour Grid: Construction
- Hour Grid: Highlighting current time
- Event Grid: Basic Setup
- Event Grid: Determine number of rows
- Event Grid: Display Events
- Event Grid: Calculating Event Position
- Event Grid: Past Events
- Календарь-1 для сайта на JavaScript
- 1. Стиль календаря
- 2. Код календаря на страние сайта.html
- 3. Скрипт календаря
- CSS Calendars
- Related Articles
- Author
- Links
- Made with
- About a code
- CSS Winter Animation Calendar
- Author
- Links
- Made with
- About a code
- Calendar
- Author
- Links
- Made with
- About a code
- Days
- Author
- Links
- Made with
- About a code
- Calendar
- Author
- Links
- Made with
- About a code
- CSS-Only Calendar Layout
- Author
- Links
- Made with
- About a code
- Datepicker
- Author
- Links
- Made with
- About a code
- Calendar UI
- Author
- Links
- Made with
- About a code
- Calendar
- Author
- Links
- Made with
- About the code
- CSS Calendar UI Design
- Author
- Links
- Made with
- About the code
- Calendar Mobile App UI
- Author
- Links
- Made with
- About the code
- Calendar Plan — Tasks Events App
- Author
- Links
- Made with
- About the code
- Light & Dark Calendar
- Author
- Links
- Made with
- About the code
- Simple Calendar
- Author
Building a vertical calendar with HTML, CSS & JS
Today let’s build together a small vertical calendar using CSS grid layout, the tag and a little bit of JavaScript.
This article is an extract of a larger project dashboard I coded. For the impatient ones or those who want to see how the entire dashboard is built (starting from 14:13):
Result
Getting started
- Hour grid: The lower layer is the hour grid that visually provides the time scale
- Event grid: On top of the hour grid we place an event grid that puts the events in the right place on the time scale.
So, let’s start with a little bit of markup:
class="my-day"> class="calendar">
Therefore the container .calendar needs to have set position: relative; in order to make the absolute position of both children (hour grid and event grid) work correctly.
.calendar /* we'll need that later */ --left-margin: var(--sp-base); position: relative; > .calendar > * position: absolute; left: 0; right: 0; bottom: 0; top: 0; >
The Hour Grid: Basic Setup
First some basic calculations: We need to define from which hour onwards the calendar is starting and at which hour it is ending:
const startHour = 8; const endHour = 18;
Since we need these values in the JS and the CSS code, it’s a good idea to define them in one place (the JS code in this case) and pass it on to the CSS code. Through .style.setProperty we’re easily able to programmatically change values of CSS custom properties:
const calendar = document .querySelector('.calendar'); calendar.style.setProperty( '--start-hour', startHour); calendar.style.setProperty( '--end-hour', endHour);
So the number of hours can be calculated by subtracting the start hour from the end hour:
.calendar --hours: calc(var(--end-hour) - var(--start-hour)); >
Hour Grid: Construction
we’ll use the tag here (see the MDN Docs), in order to be able to dynamically construct the hour grid. So instead of having a fixed number of hours, we’ll have the hour grid constructed depending on the actual number of hour’s we’ll need.
class="calendar"> class="calendar__hour-grid"> id="template-hour"> class="calendar__hour"> class="label">
In this article I’m using plain HTML/JS without UI libraries such as React/Vue/Svelte/. Using the tag is slightly similar to using UI components in these frameworks and their respective loop rendering technique (e.g. v-for in Vue). So transferring this code into a UI library of your choice should not be too much trouble.
Now it’s time to actually construct the hour grid:
// Retrieve a reference to the tag const hourTemplate = document.querySelector( '#template-hour'); // Retrieve a reference to the // calendar hour grid element const hourGrid = document.querySelector( '.calendar__hour-grid');
So for the required number of hours (from start hour to end hour) we’ll clone the hour template content and set its label to the hour it represents:
for (let i = startHour; i endHour; i++) //clone the template and const hourNode = hourTemplate.content .firstElementChild.cloneNode(true); // . append it to the hour grid hourGrid.appendChild(hourNode); // set the hour label hourNode.querySelector('.label') .innerText = `$i>`.padStart(2, '0'); >
And to make the hour grid appear as a vertical list, we’ll configure the .calendar__hour-grid class to
- be a grid layout container
- generate one row for each element in grid auto flow mode
- give each row the same amount of space ( 1fr )
.calendar__hour-grid display: grid; grid-auto-flow: row; grid-auto-rows: 1fr; > .calendar__hour > .label font-size: var(--fs-sm-1); line-height: 2.5; >
In order to have a nicely visible grid, each hour element is given a dashed top border. Additionally, the last hour (identified through :last-child ) is also given a border at the bottom:
.calendar__hour border-top: 1px dashed var(--bg-secondary); > .calendar__hour:last-child border-bottom: 1px dashed var(--bg-secondary); >
Hour Grid: Highlighting current time
Since it’s also quite usual in a calendar to display the current time, we’ll put the current hour and minute we want to highlight in two variables:
const currentHour = 12; const currentMinute = 25;
Hour and minute are fixed in this example, you could of course also retrieve them from a freshly created Date object, providing the current time.
Now, when we generate the hour grid, we simply check, if the hour currently being generated is the current hour. If this is the case we simply add the active class to the hour element and update the —current-minute custom CSS property (which is then used a little later):
for (let i = startHour; i endHour; i++) // . if (currentHour === i) hourNode.classList.add('active'); hourNode.style.setProperty( '--current-minute', currentMinute ); > >
The current hour is simply highlighted through text color .
.calendar__hour.active color: var(--hi-primary); >
. and the current minute is rendered as a ::before pseudo-element with a dashed line at its bottom border:
.calendar__hour.active position: relative; > .calendar__hour.active::before content: ""; position: absolute; left: calc(1.5 * var(--left-margin)); right: 0; height: 1px; border-bottom: 2px dashed var(--hi-primary); >
The position of the current minute is then calculated by dividing the current minute by 60 and then converting it to a percentage by multiplying with 100% :
.calendar__hour.active::before /* . */ top: calc(100% * var(--current-minute) / 60); /* . */ >
Event Grid: Basic Setup
Since we’re now able to display the hour grid Similar to the hour grid, the event grid contains also a tag which is used for each event being rendered:
class="calendar"> class="calendar__events"> id="template-event"> class="calendar__event"> class="label">
Unlike the hour grid the event grid itself is not operating in auto flow mode, but is given the number of rows it should render. The calculation of the number of rows is shown in the following section.
.calendar__events display: grid; grid-template-columns: 1fr; grid-template-rows: repeat(var(--rows), 1fr); left: calc(2 * var(--left-margin)); >
Let’s also directly retrieve the necessary element references as we’re going to need them later: One for the event template and one for the event grid.
const eventTemplate = document .querySelector('#template-event'); const calendarEvents = document .querySelector('.calendar__events');
Event Grid: Determine number of rows
In our JS code we define the resolution of the event grid. 2 defines that each hour is subdivided into two parts, i.e. half hours. This value we also pass on to the —resolution custom CSS property:
const resolution = 2; calendar.style.setProperty( '--resolution', resolution);
The number of rows we have in our event grid is can now be easily calculated by multiplying the —resolution with the number of —hours . So, if we have a resolution of 2 and 10 hours (from 8:00 to 18:00) the event grid needs to have 20 rows:
.calendar /* . */ --rows: calc( var(--resolution) * var(--hours) ); >
Event Grid: Display Events
Now it’s time to actually add the events to the event grid. This is the array of events that we’ll display:
Note that the second event has a fraction at the start and end time.
const events = [ start: 8, end: 10, title: 'Focus Time', past: true, >, start: 10.5, end: 11.5, title: '1:1 with Tamika', past: true, >, start: 14, end: 15, title: 'Technical Weekly', >, ];
Just like in the hour grid, we clone the event template for each event we want to display and set its label. Additionally, the custom CSS properties for —start and —end for being able to correctly display the event at its start and end time.
events.forEach((event) => const eventNode = eventTemplate.content .firstElementChild.cloneNode(true); calendarEvents.appendChild(eventNode); eventNode.querySelector('.label') .innerText = event.title; eventNode.style.setProperty( '--start', event.start); eventNode.style.setProperty( '--end', event.end); >);
Event Grid: Calculating Event Position
The cool thing now is, that we can calculate the start and end row with the same formula for each event.
Note that the + 1 is required since grid lines start counting at 1 and clock time starts counting at 0 ( 00:00 )
.calendar__event /* . */ --start: 0; --end: 0; grid-row-start: calc( (var(--start) - var(--start-hour)) * var(--resolution) + 1 ); grid-row-end: calc( (var(--end) - var(--start-hour)) * var(--resolution) + 1 ); >
Event Grid: Past Events
Finally, let’s add some necessary styling to each event:
.calendar__event padding: var(--sp-sm-2); border-radius: calc(2 / 3 * var(--bd-radius)); background: var(--bg-hi); > .calendar__event > .label font-weight: var(--fw-sm); >
And each event that’s in the past should be displayed muted, so let’s add for each past event the past class.
events.forEach((event) => // . if (event.past) eventNode.classList.add('past'); > >);
. and add some styling for past events:
.calendar__event.past background: var(--bg-primary); >
Календарь-1 для сайта на JavaScript
Простой календарь для сайта на CSS и JavaScript.
Представленный календарь предназначен для просмотра ближайших дней плюс-минус месяц. Календарь можно листать до нужного года как вперед, так и назад.
- Разместить все три части на одной странице.
- Разместить часть 1 (стиль календаря) в отдельном файле.css.
- Разместить часть 3 (скрипт календаря) в отдельном файле.js и подключить к странице сайта.
1. Стиль календаря
.look-calendar < width:220px; border:1px solid #c0c0c0; padding:6px; margin: 0 auto; >#calendar < width: 100%; line-height: 1.2em; font-size: 15px; text-align: center; border-spacing:0px; >#calendar tr.dn td < font-size: 15px; >#calendar thead tr:last-child < font-size: small; color: #555555; >#calendar thead tr:nth-child(1) td:nth-child(2) < color: #323232; >#calendar thead tr:nth-child(1) td:nth-child(1):hover, #calendar thead tr:nth-child(1) td:nth-child(3):hover < cursor: pointer; >#calendar tbody td < color: #2c567a; >#calendar tbody td:nth-child(n+6), #calendar .holiday < color: #e78c5c; >#calendar tbody td.today
2. Код календаря на страние сайта.html
‹ › ПнВтСрЧтПтСбВс
3. Скрипт календаря
function calendar(id, year, month) < var Dlast = new Date(year, month + 1, 0).getDate(), D = new Date(year, month, Dlast), DNlast = new Date(D.getFullYear(), D.getMonth(), Dlast).getDay(), DNfirst = new Date(D.getFullYear(), D.getMonth(), 1).getDay(), calendar = '', month = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"]; if (DNfirst != 0) < for (var i = 1; i < DNfirst; i++) calendar += ''; > else < for (var i = 0; i < 6; i++) calendar += ''; > for (var i = 1; i ‘ + i; > else < calendar += '' + i; > if (new Date(D.getFullYear(), D.getMonth(), i).getDay() == 0) < calendar += ''; > > for (var i = DNlast; i < 7; i++) calendar += ''; document.querySelector('#' + id + ' tbody').innerHTML = calendar; document.querySelector('#' + id + ' thead td:nth-child(2)').innerHTML = month[D.getMonth()] + ' ' + D.getFullYear(); document.querySelector('#' + id + ' thead td:nth-child(2)').dataset.month = D.getMonth(); document.querySelector('#' + id + ' thead td:nth-child(2)').dataset.year = D.getFullYear(); if (document.querySelectorAll('#' + id + ' tbody tr').length < 6) < // чтобы при перелистывании месяцев не "подпрыгивала" вся страница, добавляется ряд пустых клеток. Итог: всегда 6 строк для цифр document.querySelector('#' + id + ' tbody').innerHTML += ' '; > > calendar(«calendar», new Date().getFullYear(), new Date().getMonth()); // переключатель минус месяц document.querySelector(‘#calendar thead tr:nth-child(1) td:nth-child(1)’).onclick = function() < calendar("calendar", document.querySelector('#calendar thead td:nth-child(2)').dataset.year, parseFloat(document.querySelector('#calendar thead td:nth-child(2)').dataset.month) - 1); >// переключатель плюс месяц document.querySelector(‘#calendar thead tr:nth-child(1) td:nth-child(3)’).onclick = function() < calendar("calendar", document.querySelector('#calendar thead td:nth-child(2)').dataset.year, parseFloat(document.querySelector('#calendar thead td:nth-child(2)').dataset.month) + 1); >
Для этого календаря Примеры оформления (меняем только CSS).
CSS Calendars
Welcome to our collection of CSS Calendars! This curated compilation features a wide range of free HTML and CSS calendar code examples sourced from popular platforms like CodePen, GitHub, and other valuable resources. With the July 2023 update, we are excited to present six new additions to our ever-growing collection.
Whether you’re looking for simple, responsive, event-based, or other types of calendars, this collection has it all. Explore our handpicked selection and enhance your web design projects with these CSS calendars!
Related Articles
- jQuery Calendars
- Tailwind Calendars
Author
Links
Made with
About a code
CSS Winter Animation Calendar
A calendar with beautiful subtle animation made in CSS featuring a beautiful night in the mountains with moon and twinkling stars in the clear sky.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Calendar
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Days
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Calendar
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
CSS-Only Calendar Layout
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Datepicker
Recreation of Jakub Antalik’s Date Picker from Dribbble.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Calendar UI
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Calendar
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
CSS Calendar UI Design
HTML calendar UI design with CSS Grid.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Calendar Mobile App UI
Calendar mobile app UI in HTML and CSS.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Calendar Plan — Tasks Events App
Based on and inspired from Dribbble shot.
Author
Links
Made with
About the code
Light & Dark Calendar
Here is a light and dark version of a calendar planner page.
Author
Links
Made with
About the code
Simple Calendar
Clean and modern simple calendar.