Home > Net >  Prevent HTML elements from moving after changing content with JavaScript
Prevent HTML elements from moving after changing content with JavaScript

Time:10-16

'use strict';

const countdown = () => {
  // function to calcute time until launch in Days/Hours/Minutes/Seconds

  // time difference
  const countDate = new Date('May 25, 2024 00:00:00').getTime();
  const now = new Date().getTime();
  const gap = countDate - now;

  const second = 1000;
  const minute = second * 60;
  const hour = minute * 60;
  const day = hour * 24;

  const textDay = Math.floor(gap / day);
  const textHour = Math.floor((gap % day) / hour);
  const textMinute = Math.floor((gap % hour) / minute);
  const textSecond = Math.floor((gap % minute) / second);

  // update time in HTML
  document.querySelector('.day').innerText = textDay;
  document.querySelector('.hour').innerText = textHour;
  document.querySelector('.minute').innerText = textMinute;
  document.querySelector('.second').innerText = textSecond;
};

// runs function every second
setInterval(countdown, 1000);
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
html {
  font-size: 62.5%;
  font-family: 'Rubik', sans-serif;
  color: #f8f9fa;
}
.countdown-container {
  color: #343a40;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-image: linear-gradient(
      rgba(34, 34, 34, 0.1),
      rgba(34, 34, 34, 0.1)
    ),
    url(./img/countdown.jpg);
  background-size: cover;
}
.countdown-container h2 {
  letter-spacing: 0.1rem;
  font-size: 10rem;
  font-weight: 700;
  padding: 5rem;
  padding-bottom: 8vh;
}
.countdown {
  display: flex;
  text-align: center;
  justify-content: space-around;
}
.day,
.hour,
.minute,
.second {
  font-size: 5rem;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;600;700&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="style.css">
  <title>Test</title>
</head>

<body>
  <section class="countdown-container">
    <div>
      <h2 class="countdown-header">Time until Launch</h2>
      <div class="countdown">
        <div class="container-day">
          <h3 class="day">Time</h3>
          <h3>Days</h3>
        </div>
        <div class="container-hour">
          <h3 class="hour">Time</h3>
          <h3>Hours</h3>
        </div>
        <div class="container-minute">
          <h3 class="minute">Time</h3>
          <h3>Minutes</h3>
        </div>
        <div class="container-second">
          <h3 class="second">Time</h3>
          <h3>Seconds</h3>
        </div>
      </div>
    </div>
  </section>
  <script src="./app.js"></script>
</body>
</html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Hi,

i built a countdown timer, but every time the numbers are updated the elements move a little bit. How can i prevent this? I added the code, in the code snippet you can see the problem...

(Random text, i cannot post without adding more text... Lorem, ipsum dolor sit amet consectetur adipisicing elit. Porro qui inventore ad fugit ea non harum est quas deserunt quia!)

Thanks :)

CodePudding user response:

What causes this is justify-content: space-around; in .countdown. Since the div holding the seconds (and all others) don't have a defined width, the width of the containing div changes as the width of the text changes when using a variable-width font. Then justify-content: space-around; dutifully adjusts the row to make sure everything is evenly spaced.

You could also try a monospace font to help with this if your design goals will tolerate that.

I added a width to all of the time segments to prevent this.

div.countdown>div {
  width: 40px;
}

I used a fixed 40px width which may not be exactly what works for you. I tried it with 25% width as well which works but the seconds still move a bit.

'use strict';

const countdown = () => {
  // function to calcute time until launch in Days/Hours/Minutes/Seconds

  // time difference
  const countDate = new Date('May 25, 2024 00:00:00').getTime();
  const now = new Date().getTime();
  const gap = countDate - now;

  const second = 1000;
  const minute = second * 60;
  const hour = minute * 60;
  const day = hour * 24;

  const textDay = Math.floor(gap / day);
  const textHour = Math.floor((gap % day) / hour);
  const textMinute = Math.floor((gap % hour) / minute);
  const textSecond = Math.floor((gap % minute) / second);

  // update time in HTML
  document.querySelector('.day').innerText = textDay;
  document.querySelector('.hour').innerText = textHour;
  document.querySelector('.minute').innerText = textMinute;
  document.querySelector('.second').innerText = textSecond;
};

// runs function every second
setInterval(countdown, 1000);
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
html {
  font-size: 62.5%;
  font-family: 'Rubik', sans-serif;
  color: #f8f9fa;
}
.countdown-container {
  color: #343a40;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-image: linear-gradient(
      rgba(34, 34, 34, 0.1),
      rgba(34, 34, 34, 0.1)
    ),
    url(./img/countdown.jpg);
  background-size: cover;
}
.countdown-container h2 {
  letter-spacing: 0.1rem;
  font-size: 10rem;
  font-weight: 700;
  padding: 5rem;
  padding-bottom: 8vh;
}
.countdown {
  display: flex;
  text-align: center;
  justify-content: space-around;
}
.day,
.hour,
.minute,
.second {
  font-size: 5rem;
}

div.countdown>div {
  width: 40px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;600;700&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="style.css">
  <title>Test</title>
</head>

<body>
  <section class="countdown-container">
    <div>
      <h2 class="countdown-header">Time until Launch</h2>
      <div class="countdown">
        <div class="container-day">
          <h3 class="day">Time</h3>
          <h3>Days</h3>
        </div>
        <div class="container-hour">
          <h3 class="hour">Time</h3>
          <h3>Hours</h3>
        </div>
        <div class="container-minute">
          <h3 class="minute">Time</h3>
          <h3>Minutes</h3>
        </div>
        <div class="container-second">
          <h3 class="second">Time</h3>
          <h3>Seconds</h3>
        </div>
      </div>
    </div>
  </section>
  <script src="./app.js"></script>
</body>
</html>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related