Orion31 Orion31 - 26 days ago 9
CSS Question

Everything moves around when clock ticks

I made a clock where the format is the following.


HH:MM AM
HH:MM S


My problem is that whenever the seconds changed, the minutes and the hours get pushed around to fit the number. My font,
Modern Sans
, is not monospace, which is probably the main cause for this, but I would like to keep that font, of course only if possible. I would also like to keep the clock centered on the page.

Thanks for your help!

EDIT: Please view the snippet in fullscreen. It acts a little weird(er) in the regular box.


function updateClock() {
var date = new Date();
var h = (date.getHours() + 24) % 12 || 12,
m = date.getMinutes(),
s = date.getSeconds(),
dm = "AM";
if (h >= 12)
dm = "PM";
if (m < 10) m = '0' + m;
if (s < 10) s = '0' + s;
$(".mt.h").html(h);
$(".mt.m").html(m);
$(".mt.s").html(s);
$(".mt.dm").html(dm);
setTimeout(updateClock, 1000);
}

body,
html {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
display: table;
}

* {
font-family: "Modern Sans", Helvetica;
}

.main-content {
text-align: center;
display: table-cell;
vertical-align: middle;
padding: 10px;
}

.search {
vertical-align: middle;
}

.clock {
color: rgba(0, 0, 0, 0.65);
}

.clock .unflex div {
display: inline-block;
}

.clock .unflex {
display: inline;
}

.mt.h,
.mt.m,
.mt.c {
font-size: 250px;
}

.mt.s {
font-size: 125px;
color: rgba(250, 0, 0, 0.45);
}

.mt.dm {
font-size: 75px;
}

.flexclock {
position: relative;
top: -125.5px;
display: inline-flex;
justify-content: flex-start;
flex-wrap: wrap;
align-content: center;
}

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.2.1.js" type="text/javascript"></script>
</head>

<body onload="updateClock()">
<div class="main-content">
<div class="clock">
<div class="unflex">
<div class="mt h"></div>
<div class="mt c">:</div>
<div class="mt m"></div>
</div>
<div class="flexclock">
<div class="mtsdm">
<div class="mt dm"></div>
<div class="mt s"></div>
</div>
</div>
</div>
</div>
</body>

</html>




Answer Source

As different number characters have different width, and to avoid text to move in cases like this, one can set a width wide enough on each item so they won't effect their surroundings.

An alternative is also absolute positioning, though I find the below better and more responsive.

Here I added/updated these rules

.mt.h {
  width: 160px;
}
.mt.m {
  width: 320px;
}
.mt.c {
  width: 80px;
}

.mt.s {
  font-size: 125px;
  color: rgba(250, 0, 0, 0.45);
  width: 160px;
}

Stack snippet

function updateClock() {
  var date = new Date();
  var h = (date.getHours() + 24) % 12 || 12,
    m = date.getMinutes(),
    s = date.getSeconds(),
    dm = "AM";
  if (h >= 12)
    dm = "PM";
  if (m < 10) m = '0' + m;
  if (s < 10) s = '0' + s;
  $(".mt.h").html(h);
  $(".mt.m").html(m);
  $(".mt.s").html(s);
  $(".mt.dm").html(dm);
  setTimeout(updateClock, 1000);
}
body,
html {
  height: 100%;
  margin: 0;
  padding: 0;
  width: 100%;
  display: table;
}

* {
  font-family: "Modern Sans", Helvetica;
}

.main-content {
  text-align: center;
  display: table-cell;
  vertical-align: middle;
  padding: 10px;
}

.search {
  vertical-align: middle;
}

.clock {
  color: rgba(0, 0, 0, 0.65);
}

.clock .unflex div {
  display: inline-block;
}

.clock .unflex {
  display: inline;
}

.mt.h,
.mt.m,
.mt.c {
  font-size: 250px;
}

.mt.h {
  width: 160px;
}
.mt.m {
  width: 320px;
}
.mt.c {
  width: 80px;
}

.mt.s {
  font-size: 125px;
  color: rgba(250, 0, 0, 0.45);
  width: 160px;
}

.mt.dm {
  font-size: 75px;
}

.flexclock {
  position: relative;
  top: -125.5px;
  display: inline-flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  align-content: center;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <script src="https://code.jquery.com/jquery-3.2.1.js" type="text/javascript"></script>
</head>

<body onload="updateClock()">
  <div class="main-content">
    <div class="clock">
      <div class="unflex">
        <div class="mt h"></div>
        <div class="mt c">:</div>
        <div class="mt m"></div>
      </div>
      <div class="flexclock">
        <div class="mtsdm">
          <div class="mt dm"></div>
          <div class="mt s"></div>
        </div>
      </div>
    </div>
  </div>
</body>

</html>