Styling the clock
Although, it has been instructed in the description of this project that we shouldn't include anything inside .clock
, we have to do so at least in these early stages of development. It's impossible to design a clock without thoroughly testing the design of each of its components.
We have to fill .clock
with all of its components, style them, see how they look, and then once everything looks great, then consider about removing the components from the HTML, leaving this job to JavaScript.
So first thing's first, let's start with designing .clock
.
Here's the CSS for .clock
:
.clock {
position: relative;
display: inline-block;
border: 6px solid lightgrey;
background-color: #f8f8f8;
padding: 80px;
border-radius: 50%;
}
Let's understand the purpose of each style declaration here:
position: relative
is applied so that later on we canabsolute
ly position elements inside.clock
.display: inline-block
is given only to enable the clock to be easily center-aligned on the HTML document (by applyingtext-align: center
on thebody
element).border: 6px solid lightgrey
creates a nice thick frame around the clock.background-color: #f8f8f8
is just a preferential style.padding: 80px
gives.clock
a160px
of visual width and height. If you want to, you can increase or decrease this value depending on how large you want the clock to look. This is easier to set up than defining two separate statements, one forwidth: 160px
and the other forheight: 160px
.border-radius: 50%
makes the clock round. Omitting this will give us a square-shaped clock which we don't find that interesting.
Altogether, this gives us the following:
Great!
Next up, let's get done with the graduations.
There are a total of 60 graduations on a clock, some of which are small while the others are large. Every 5th graduation in particular is large. Hence, we'd have the following HTML markup for the graduations:
<div class="clock">
<div class="clock_graduation clock_graduation--large"></div>
<div class="clock_graduation"></div>
<div class="clock_graduation"></div>
<div class="clock_graduation"></div>
<div class="clock_graduation"></div>
<!-- More graduations here... -->
<div class="clock_graduation clock_graduation--large"></div>
<div class="clock_graduation"></div>
<div class="clock_graduation"></div>
<div class="clock_graduation"></div>
<div class="clock_graduation"></div>
</div>
But before this, we need to design .clock_graduation
in such a way that it's easy for us to rotate it later on without much CSS. Likewise, let's first test our CSS with just one graduation — the smaller one:
<div class="clock">
<div class="clock_graduation"></div>
</div>
The idea we use to style this element .clock_graduation
is very simple.
Get the element to cover the entire area of .clock
and then use the :before
pseudo-element to act as the actual graduation, center-aligned horizontally and vertically-aligned to the top edge of the parent element.
The benefit of this approach is that we can easily rotate the graduation without having to configure transform-origin
to an appropriate pivotal point.
Here's the CSS for .clock_graduation
:
.clock_graduation {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.clock_graduation:before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 1px;
height: 6px;
background-color: grey;
}
First, let's understand the intuition behind the styles of .clock_graduation
:
position: absolute
freely positions.clock_graduation
in.clock
so that it's easy to move it via the propertiestop
,right
,bottom
andleft
.top: 0
,bottom: 0
,left: 0
andright: 0
all together make.clock_graduation
fill the entire height and width of its container (i.e..clock
).
.clock_graduation
won't be round in shape; it will be a square. The reason why we don't need to worry about rounding it is simply because it doesn't have any background color applied to it and likewise, we won't be able to notice this shape disparity between .clock
and .clock_graduation
.So far, so good.
Now, let's come to .clock_graduation:before
:
content: ''
makes the:before
element be rendered into view. As we know, without thecontent
property applied to:before
, the CSS engine doesn't consider its styles anyway.position: absolute
freely positions this pseudo-element in its parent (i.e..clock_graduation
) so that, later on, we can easily center-align it using thetop
andleft
properties.top: 0
positions the top edge of this element to the top edge of its parent in order to start the graduation mark right from the clock's frame. If you want to, you can make the graduation a little bit further away from the edge of the clock's frame.left: 50%
andtransform: translateX(-50%)
together center-align this element horizontally in its parent.width: 1px
andheight: 6px
together give a dimension to the graduation mark.background-color: grey
applies a color to the mark.
Time to test it on our single element:
Notice the small vertical mark at the top of the clock's face. That's our minor graduation mark, represented as .clock_graduation
.
Superb!
Now as instructed before, some graduations are large and represented via the class .clock_graduation--large
. This is defined as follows:
.clock_graduation--large:before {
height: 12px;
width: 3px;
}
The large width and height declarations make .clock_graduation--large
actually larger than just the .clock_graduation
element.
Let's test this class as well:
And it looks great.
Now, it's time to test all these graduations in the clock at the same time, not just one single graduation. Obviously, for this we have to rotate each subsequent graduation by 6 degrees (360 / 60 = 6):
<div class="clock">
<div class="clock_graduation clock_graduation--large" style="transform: rotate(0deg)"></div>
<div class="clock_graduation" style="transform: rotate(6deg)"></div>
<div class="clock_graduation" style="transform: rotate(12deg)"></div>
<div class="clock_graduation" style="transform: rotate(18deg)"></div>
<div class="clock_graduation" style="transform: rotate(24deg)"></div>
<!-- More graduations here... -->
<div class="clock_graduation clock_graduation--large" style="transform: rotate(330deg)"></div>
<div class="clock_graduation" style="transform: rotate(336deg)"></div>
<div class="clock_graduation" style="transform: rotate(342deg)"></div>
<div class="clock_graduation" style="transform: rotate(348deg)"></div>
<div class="clock_graduation" style="transform: rotate(354deg)"></div>
</div>
For now, we have to manually rotate each element in this testing phase. However, once we accomplish this in JavaScript, it'll automatically do this itself.
Here's the output of the HTML above:
Note that as per your preference, you can modulate the styles of these graduations as you like them to be for your clock.
Moving on, now it's time to consider the clock's hand.
.clock_hand
represents a clock hand, which begins at the center of clock and is meant to rotate. In order to achieve this, we can once again go with the same old approach — get .clock_hand
fill the entire area of .clock
and then use its :before
pseudo-element as the actual hand.
But before it, let's formulate its markup:
<div class="clock">
<!-- More graduations here... -->
<div class="clock_graduation" style="transform: rotate(354deg)"></div>
<div class="clock_hand clock_hand--hours"></div>
<div class="clock_hand clock_hand--minutes"></div>
<div class="clock_hand clock_hand--seconds"></div>
</div>
With this markup in place, let's now consider the styles of each of these new elements, starting with .clock_hand
:
.clock_graduation,
.clock_hand {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.clock_graduation:before { /* ... */ }
.clock_hand:before {
content: '';
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 50%;
}
.clock_hand
is the same as .clock_graduation
, hence we've reused the same ruleset for both of these elements.
Next, we have the definition of .clock_hand:before
. It goes as follows:
content: ''
makes this pseudo-element be rendered into view.position: absolute
allows it to move freely in its parent (i.e..clock_hand
).left: 50%
andtransform: translateX(-50%)
, as before, together help center-align this element in its parent, horizontally.bottom: 50%
aligns the bottom edge of this element with the vertical mid-point of its parent. This makes the clock hand seem to originate from the center. If you want to, you can reduce this value in order to make the clock hand extend before the mid point.
Note that the ruleset of .clock_hand:before
, as shown above, is incomplete for showcasing a given clock hand. And that's because the rest of the styles, which will be different for every hand, will be applied to the elements .clock_hand--hours
, .clock_hand--minutes
and .clock_hand--seconds
separately.
Time to do that next:
.clock_hand:before { /* ... */ }
.clock_hand--hours:before {
top: 25%;
width: 3px;
background-color: darkgrey;
}
.clock_hand--minutes:before {
top: 15%;
width: 3px;
background-color: darkgrey;
}
.clock_hand--seconds:before {
top: 5%;
width: 1px;
background-color: red;
}
Below is an explanation for the styles of .clock_hand--hours
:
top: 25%
positions the hours hand25%
from the top of the clock. (Recall that it is positioned by50%
from the bottom, hence, the height of the hours hand is25%
(100 - 50 - 25) of its parent.)width: 3px
sets the width of the hours hand. Typically, the hours and minutes hands on a clock are thicker than the seconds hand. Hence, the given styles.background-color: darkgrey
simply gives a color to the hours hand.
Similar reasoning can be applied for .clock_hand--minutes:before
and .clock_hand--seconds:before
. One important thing to note here is that, as per stated in the description of this project, the color of the seconds hand is red.
Let's now test these clock hands:
Wait a second... All the three clock hands overlap each other and consequently it's difficult to distinguish between them.
A simple way to solve this problem is to rotate the hours and minutes hand to some arbitrary angle. That's what we do below:
<div class="clock">
<!-- More graduations here... -->
<div class="clock_graduation" style="transform: rotate(354deg)"></div>
<div class="clock_hand clock_hand--hours" style="transform: rotate(60deg)"></div>
<div class="clock_hand clock_hand--minutes" style="transform: rotate(151deg)"></div>
<div class="clock_hand clock_hand--seconds"></div>
</div>
And now it looks spectacular. What do you think?
The last thing left to be done is to add a hand nut at the center of the clock to hold all the three hands in place (obviously just for the sake of visual similarity with a real analog clock).
This is accomplished with the addition of a .clock_hand-nut
element to our HTML:
<div class="clock">
<!-- More graduations here... -->
<div class="clock_graduation" style="transform: rotate(354deg)"></div>
<div class="clock_hand clock_hand--hours"></div>
<!-- More hands here... -->
<div class="clock_hand-nut"></div>
</div>
The CSS is as follows:
.clock_hand-nut {
position: absolute;
padding: 6px;
border-radius: 50%;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
z-index: 1;
background-color: grey;
}
And here's the result:
Perfect!
With this, we have completely tested and perfected all the components of our clock. The next thing is to start thinking about its logic.