This tutorial will guide you through creating an analog clock using HTML, CSS, and JavaScript. We’ll build a visually appealing clock that updates in real-time, and even includes a theme toggle to switch between light and dark modes. This project is perfect for beginners looking to enhance their front-end development skills.
Step 1: Setting up the HTML Structure
First, we create the basic HTML structure for our analog clock. This includes divs for the clock face, hour, minute, and second hands, as well as a button to switch the theme.
<!-- Inspired by https://www.youtube.com/watch?v=weZFfrjF-k4 --> <div class="page-header"> Analog Clock </div> <div class="clock"> <div class="hour"></div> <div class="min"></div> <div class="sec"></div> </div> <div class="switch-cont"> <button class="switch-btn"> Light </button> </div>
Step 2: Styling with CSS
Next, we add CSS styles to make our clock look appealing and functional. We’ll use variables for colors to easily switch between themes, and apply styles to position the hands and create the clock’s visual elements.
:root {
--main-bg-color: #fff;
--main-text-color: #888888;
}
[data-theme="dark"] {
--main-bg-color: #1e1f26;
--main-text-color: #ccc;
}
* {
box-sizing: border-box;
/* transition: all ease 0.2s; */
}
body {
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
font-size: 16px;
background-color: var(--main-bg-color);
position: relative;
transition: all ease 0.2s;
}
.page-header {
font-size: 2rem;
color: var(--main-text-color);
padding: 2rem 0;
font-family: monospace;
text-transform: uppercase;
letter-spacing: 4px;
transition: all ease 0.2s;
}
.clock {
min-height: 18em;
min-width: 18em;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--main-bg-color);
background-image: url("https://imvpn22.github.io/analog-clock/clock.png");
background-position: center center;
background-size: cover;
border-radius: 50%;
border: 4px solid var(--main-bg-color);
box-shadow: 0 -15px 15px rgba(255, 255, 255, 0.05),
inset 0 -15px 15px rgba(255, 255, 255, 0.05), 0 15px 15px rgba(0, 0, 0, 0.3),
inset 0 15px 15px rgba(0, 0, 0, 0.3);
transition: all ease 0.2s;
}
.clock:before {
content: "";
height: 0.75rem;
width: 0.75rem;
background-color: var(--main-text-color);
border: 2px solid var(--main-bg-color);
position: absolute;
border-radius: 50%;
z-index: 1000;
transition: all ease 0.2s;
}
.hour,
.min,
.sec {
position: absolute;
display: flex;
justify-content: center;
border-radius: 50%;
}
.hour {
height: 10em;
width: 10em;
}
.hour:before {
content: "";
position: absolute;
height: 50%;
width: 6px;
background-color: var(--main-text-color);
border-radius: 6px;
}
.min {
height: 12em;
width: 12em;
}
.min:before {
content: "";
height: 50%;
width: 4px;
background-color: var(--main-text-color);
border-radius: 4px;
}
.sec {
height: 13em;
width: 13em;
}
.sec:before {
content: "";
height: 60%;
width: 2px;
background-color: #f00;
border-radius: 2px;
}
/* Style for theme switch btn */
.switch-cont {
margin: 2em auto;
/* position: absolute; */
bottom: 0;
}
.switch-cont .switch-btn {
font-family: monospace;
text-transform: uppercase;
outline: none;
padding: 0.5rem 1rem;
background-color: var(--main-bg-color);
color: var(--main-text-color);
border: 1px solid var(--main-text-color);
border-radius: 0.25rem;
cursor: pointer;
transition: all ease 0.3s;
}
Step 3: Adding JavaScript Functionality
Now, we’ll add the JavaScript code to make the clock hands move dynamically. We’ll use `Date` object to get current time and some trigonometry to position the hands accurately. A theme switching function is also included.
// Just noticed accessing localStorage is banned from codepen, so disabling saving theme to localStorage
const deg = 6;
const hour = document.querySelector(".hour");
const min = document.querySelector(".min");
const sec = document.querySelector(".sec");
const setClock = () => {
let day = new Date();
let hh = day.getHours() * 30;
let mm = day.getMinutes() * deg;
let ss = day.getSeconds() * deg;
hour.style.transform = `rotateZ(${hh + mm / 12}deg)`;
min.style.transform = `rotateZ(${mm}deg)`;
sec.style.transform = `rotateZ(${ss}deg)`;
};
// first time
setClock();
// Update every 1000 ms
setInterval(setClock, 1000);
const switchTheme = (evt) => {
const switchBtn = evt.target;
if (switchBtn.textContent.toLowerCase() === "light") {
switchBtn.textContent = "dark";
// localStorage.setItem("theme", "dark");
document.documentElement.setAttribute("data-theme", "dark");
} else {
switchBtn.textContent = "light";
// localStorage.setItem("theme", "light"); //add this
document.documentElement.setAttribute("data-theme", "light");
}
};
const switchModeBtn = document.querySelector(".switch-btn");
switchModeBtn.addEventListener("click", switchTheme, false);
let currentTheme = "dark";
// currentTheme = localStorage.getItem("theme")
// ? localStorage.getItem("theme")
// : null;
if (currentTheme) {
document.documentElement.setAttribute("data-theme", currentTheme);
switchModeBtn.textContent = currentTheme;
}
Congratulations! You’ve successfully created an analog clock using HTML, CSS, and JavaScript. I hope this tutorial was helpful!



