The provided code snippet showcases an intriguing Bouncy Block Clock designed by the Target Media Agency. Let’s delve into the analysis of the HTML and CSS components and the underlying JavaScript functionality.
##HTML Structure
The HTML structure starts with the declaration of the document type (<!DOCTYPE html>
) followed by the html
tag, specifying the language as English. The head
section contains the meta tag for character encoding and the title of the web page. It also includes a link to an external CSS file. The body
section contains the main clock structure with nested div
elements, each representing a block or a part of the clock. The script
tag at the end imports a JavaScript file.
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Bouncy Block Clock - Target Media Agency</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<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>
<!-- partial -->
<script src="./script.js"></script>
</body>
</html>
##CSS Styling
The CSS section begins with the universal selector setting the border, box-sizing, margin, and padding to zero, ensuring a consistent layout. The :root
selector defines custom CSS variables for hue, background color, foreground color, primary color, and transition duration. The body
styling sets the background image and various layout properties such as color, font, height, and display type. The .clock
class governs the clock’s container, while .clock__block
and .clock__block--small
classes define the styling for the clock blocks of varying sizes.
* {
border: 0;
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--hue: 108.42;
--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-image:url("https://i.postimg.cc/bJVhddQc/back-Target.png");
color: var(--fg);
font: 1em/1.5 "DM Sans", sans-serif;
height: 100vh;
display: grid;
place-items: center;
}
.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 Functionality
The JavaScript component is responsible for managing the Bouncy Block Clock’s dynamic behavior. It initializes the clock, handles animation of digits, displays time, updates time, and manages the ticking functionality. Additionally, it includes a class BouncyBlockClock
with various methods to control the clock’s behavior.
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];
}
}
##Media Queries
The code also incorporates media queries to provide a seamless transition between light and dark themes based on the user’s preferences. It adjusts the hue, background color, foreground color, and box shadow properties for different screen sizes, enabling a responsive design.
##Animations
The CSS section includes keyframes for the “bounce” and “roll” animations. The “bounce” animation applies a dynamic movement to the clock digits, while the “roll” animation creates a rolling effect for the clock blocks, contributing to the engaging visual appeal of the Bouncy Block Clock.
##Conclusion
Overall, the combination of HTML, CSS, and JavaScript results in an interactive and visually captivating Bouncy Block Clock that would be a striking addition to any website or application.
GET IN TOUCH