Let’s create an Animated Bouncy Clock using HTML, CSS, and JavaScript. This project will display a real-time clock with a fun, bouncy animation effect to make it visually engaging.
We’ll use HTML to structure the clock, CSS to style it and add the bouncy effect, and JavaScript to update the time dynamically.
Let’s get started on building the Animated Bouncy Clock. Whether you’re a beginner or an experienced developer, this project is a great way to practice animation techniques and real-time updates in JavaScript. Let’s make time bounce in style!
HTML :
This HTML structure creates a bouncy block clock using div
elements for each time unit (hours, minutes, seconds, and AM/PM). Each block contains two sets of digits (a
and b
) that switch with a bouncing effect when the time updates. The aria-label
ensures screen reader accessibility, while colons are conditionally displayed for larger screens. External CSS (style.css
) and JavaScript (script.js
) handle styling, animations, and real-time updates to display the current time dynamically.
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>Bouncy Block Clock | codingstella</title> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=DM+Sans&display=swap'> <link rel="stylesheet" href="./style.css"> </head> <body> <div class="clock" aria-label="00:00:00 AM"> <div class="clock__block clock__block--delay2" aria-hidden="true" data-time-group> <div class="clock__digit-group"> <div class="clock__digits" data-time="a">00</div> <div class="clock__digits" data-time="b">00</div> </div> </div> <div class="clock__colon"></div> <div class="clock__block clock__block--delay1" aria-hidden="true" data-time-group> <div class="clock__digit-group"> <div class="clock__digits" data-time="a">00</div> <div class="clock__digits" data-time="b">00</div> </div> </div> <div class="clock__colon"></div> <div class="clock__block" aria-hidden="true" data-time-group> <div class="clock__digit-group"> <div class="clock__digits" data-time="a">00</div> <div class="clock__digits" data-time="b">00</div> </div> </div> <div class="clock__block clock__block--delay2 clock__block--small" aria-hidden="true" data-time-group> <div class="clock__digit-group"> <div class="clock__digits" data-time="a">PM</div> <div class="clock__digits" data-time="b">AM</div> </div> </div> </div> <script src="./script.js"></script> </body> </html>
CSS :
This CSS styles a digital clock with a bouncing animation effect when the time updates. It defines a responsive design with color themes that adapt to light and dark modes using CSS variables. The .clock__block
elements represent the time digits, styled with shadows, rounded corners, and smooth transitions. The @keyframes bounce
and @keyframes roll
animations create a bouncing and rolling effect when digits change. The layout adapts for larger screens, displaying colons between numbers, while mobile devices stack the digits vertically. The clock also supports smooth background and color transitions for a polished look.
* { border: 0; box-sizing: border-box; margin: 0; padding: 0; } :root { --hue: 223; --bg: hsl(var(--hue),90%,90%); --fg: hsl(var(--hue),10%,10%); --primary: hsl(var(--hue),90%,55%); --trans-dur: 0.3s; font-size: calc(16px + (20 - 16) * (100vw - 320px) / (1280 - 320)); } body { background-color: var(--bg); color: var(--fg); font: 1em/1.5 "DM Sans", sans-serif; height: 100vh; display: grid; place-items: center; transition: background-color var(--trans-dur), color var(--trans-dur); } .clock { display: flex; flex-direction: column; flex-wrap: wrap; align-items: center; } .clock__block { background-color: hsl(var(--hue),10%,90%); border-radius: 0.5rem; box-shadow: 0 1rem 2rem hsla(var(--hue),90%,50%,0.3); font-size: 3em; line-height: 2; margin: 0.75rem; overflow: hidden; text-align: center; width: 6rem; height: 6rem; transition: background-color var(--trans-dur), box-shadow var(--trans-dur); } .clock__block--small { border-radius: 0.25rem; box-shadow: 0 0.5rem 2rem hsla(var(--hue),90%,50%,0.3); font-size: 1em; line-height: 3; width: 3rem; height: 3rem; } .clock__colon { display: none; font-size: 2em; opacity: 0.5; position: relative; } .clock__colon:before, .clock__colon:after { background-color: currentColor; border-radius: 50%; content: ""; display: block; position: absolute; top: -0.05em; left: -0.05em; width: 0.1em; height: 0.1em; transition: background-color var(--trans-dur); } .clock__colon:before { transform: translateY(-200%); } .clock__colon:after { transform: translateY(200%); } .clock__digit-group { display: flex; flex-direction: column-reverse; } .clock__digits { width: 100%; height: 100%; } .clock__block--bounce { animation: bounce 0.75s; } .clock__block--bounce .clock__digit-group { animation: roll 0.75s ease-in-out forwards; transform: translateY(-50%); } .clock__block--delay1, .clock__block--delay1 .clock__digit-group { animation-delay: 0.1s; } .clock__block--delay2, .clock__block--delay2 .clock__digit-group { animation-delay: 0.2s; } /* Dark theme */ @media (prefers-color-scheme: dark) { :root { --bg: hsl(var(--hue),10%,10%); --fg: hsl(var(--hue),10%,90%); } .clock__block { background-color: hsl(var(--hue),90%,40%); box-shadow: 0 1rem 2rem hsla(var(--hue),90%,60%,0.4); } .clock__block--small { box-shadow: 0 0.5rem 2rem hsla(var(--hue),90%,60%,0.4); } } /* Beyond mobile */ @media (min-width: 768px) { .clock { flex-direction: row; } .clock__colon { display: inherit; } } /* Animations */ @keyframes bounce { from, to { animation-timing-function: ease-in; transform: translateY(0); } 50% { animation-timing-function: ease-out; transform: translateY(15%); } } @keyframes roll { from { transform: translateY(-50%); } to { transform: translateY(0); } }
JavaScript:
This JavaScript code creates a digital clock with a bouncing animation effect when the time changes. The BouncyBlockClock
class updates and displays the current time, formatting it into hours, minutes, seconds, and AM/PM. It checks for changes in digits and applies a bounce animation when a number updates. The loop()
function continuously updates the time every second, and removeAnimations()
clears the bounce effect after 900ms. The DOMContentLoaded
event initializes the clock when the page loads.
window.addEventListener("DOMContentLoaded",() => { const clock = new BouncyBlockClock(".clock"); }); class BouncyBlockClock { constructor(qs) { this.el = document.querySelector(qs); this.time = { a: [], b: [] }; this.rollClass = "clock__block--bounce"; this.digitsTimeout = null; this.rollTimeout = null; this.mod = 0 * 60 * 1000; this.loop(); } animateDigits() { const groups = this.el.querySelectorAll("[data-time-group]"); Array.from(groups).forEach((group,i) => { const { a, b } = this.time; if (a[i] !== b[i]) group.classList.add(this.rollClass); }); clearTimeout(this.rollTimeout); this.rollTimeout = setTimeout(this.removeAnimations.bind(this),900); } displayTime() { // screen reader time const timeDigits = [...this.time.b]; const ap = timeDigits.pop(); this.el.ariaLabel = `${timeDigits.join(":")} ${ap}`; // displayed time Object.keys(this.time).forEach(letter => { const letterEls = this.el.querySelectorAll(`[data-time="${letter}"]`); Array.from(letterEls).forEach((el,i) => { el.textContent = this.time[letter][i]; }); }); } loop() { this.updateTime(); this.displayTime(); this.animateDigits(); this.tick(); } removeAnimations() { const groups = this.el.querySelectorAll("[data-time-group]"); Array.from(groups).forEach(group => { group.classList.remove(this.rollClass); }); } tick() { clearTimeout(this.digitsTimeout); this.digitsTimeout = setTimeout(this.loop.bind(this),1e3); } updateTime() { const rawDate = new Date(); const date = new Date(Math.ceil(rawDate.getTime() / 1e3) * 1e3 + this.mod); let h = date.getHours(); const m = date.getMinutes(); const s = date.getSeconds(); const ap = h < 12 ? "AM" : "PM"; if (h === 0) h = 12; if (h > 12) h -= 12; this.time.a = [...this.time.b]; this.time.b = [ (h < 10 ? `0${h}` : `${h}`), (m < 10 ? `0${m}` : `${m}`), (s < 10 ? `0${s}` : `${s}`), ap ]; if (!this.time.a.length) this.time.a = [...this.time.b]; } }
In conclusion, creating an Animated Bouncy Clock using HTML, CSS, and JavaScript has been a fun and engaging project. By combining real-time updates with smooth animations, we’ve made a simple clock more visually interesting.
If you run into any hiccups with your project, worry not. You can easily grab the source code for this project. Just hit the Download button to get started on your coding adventure. Happy coding!