Creating an Interactive Countdown Timer with JavaScript

I am currently working on a website that includes a modified version of a JavaScript countdown element. While I have been learning a lot about flex grids, I haven't delved much into block/inline-block layouts.

One issue I'm facing is that when the countdown reaches around 945px, the four inline-block boxes remain in four columns and end up overflowing to the edge of the screen: https://i.sstatic.net/EV2Ls.png

My goal is for the four columns to collapse into two side-by-side at around 945px, with the text still aligned properly under each box. I managed to accidentally achieve this by tinkering with the code in Chrome's "inspect" tool, but the four lines of text ended up below the boxes rather than in their correct positions. Here is an example of my desired outcome:

https://i.sstatic.net/e73iF.jpg

Here is the relevant code snippet:

https://codepen.io/Lancewalker/pen/QxpbZx

$(function (){

function countdown() {

var now = new Date();
var eventDate = new Date(2019, 0, 1);
var currentTime = now.getTime();
var evenTime = eventDate.getTime();

var remTime = evenTime - currentTime;

var sec = Math.floor(remTime / 1000);
var min = Math.floor(sec / 60);
var hur = Math.floor(min / 60);
var day = Math.floor(hur / 24);

 hur %= 24;
 min %= 60;
 sec %= 60;

hur = (hur < 10) ? "0" + hur : hur;
min = (min < 10) ? "0" + min : min;
sec = (sec < 10) ? "0" + sec : sec;

$('.seconds').text(sec);
$('.minutes').text(min);
$('.hours').text(hur);
$('.days').text(day);

setTimeout(countdown, 1000);
}

countdown();
});
    body {
    background-color: #333;
}
    .container {
    width: 800px;
    height: 350px;
    margin:  auto;
    text-align: center
}

    .container h2 {
    color: #fff;
    font-size: 30px;
    font-family: Exo, Arial, Sans-serif;
    padding: 50px 0 20px;
    font-weight: normal
}

    .container .content {
    width: 100%;
}

    .container .content > div {
    display: inline-block;
    margin: 35px 10px 0;
    width: 120px;
    height: 130px;
    background: rgb(146, 163, 191, .6);
    border-radius: 8px;
    border: 1px solid #fff;
    color: #fff;
    line-height: 138px;
    font-family: Exo, arial, sans-serif;
    font-size: 55px;
}

    .container .title {
    width: ;
    height: 50px;
    position: relative
}

    .container .title span {
    display: inline-block;
    width: 140px;
    font-size: 20px;
    font-family: 'Exo', arial, sans-serif;
    color: #fff;
    line-height: 50px;
}
<div class="container">
     <h2>Apartments Coming Soon!</h2>
     <div class="content">
       <div class="days">85</div>
       <div class="hours">22</div>
       <div class="minutes">33</div>
       <div class="seconds">54</div>
     </div>
     <div class="title">
       <span>Days</span>
       <span>Hours</span>
       <span>Minutes</span>
       <span>Seconds</span>
     </div>
   </div>

Answer №1

Initially, your .container class is fixed at a width of 800px.

.container {
    max-width: 800px;
    width: 90%;
    height: 350px;
    margin:  auto;
    text-align: center
}

If you adjust this setting, the timer squares will no longer collapse underneath. To ensure responsiveness, consider using media queries and percentage values instead of hard-coding pixel sizes like 800px.

It may be helpful to reorganize your HTML structure so that time squares and titles are grouped together.

<div class="time-square">
    <div class="time-square-time">88</div>
    <div class="time-square-title">Days</div>
</div>

This restructuring will allow for cleaner HTML organization and address any mismatch issues between titles and times in the current setup.

Answer №2

If you want to improve your markup, consider wrapping the number and the text ('day', 'hour', etc) in the same parent element. This will ensure they remain together when content is wrapped.

In regards to the CSS, it might be beneficial to change width: 800px to max-width so that the content can resize on screens smaller than 800px.

You could also utilize CSS Grid for laying out the boxes and streamline the code further.

Codepen link

$(function() {

  function countdown() {

    var now = new Date();
    var eventDate = new Date(2019, 0, 1);
    var currentTime = now.getTime();
    var evenTime = eventDate.getTime();

    var remTime = evenTime - currentTime;

    var sec = Math.floor(remTime / 1000);
    var min = Math.floor(sec / 60);
    var hur = Math.floor(min / 60);
    var day = Math.floor(hur / 24);

    hur %= 24;
    min %= 60;
    sec %= 60;

    hur = (hur < 10) ? "0" + hur : hur;
    min = (min < 10) ? "0" + min : min;
    sec = (sec < 10) ? "0" + sec : sec;

    $('.seconds').text(sec);
    $('.minutes').text(min);
    $('.hours').text(hur);
    $('.days').text(day);

    setTimeout(countdown, 1000);
  }

  countdown();
});
body {
  background: #333;
}

.container {
  max-width: 800px;
  height: 350px;
  margin: auto;
  text-align: center;
}

.container h2 {
  color: #fff;
  font-size: 30px;
  font-family: Exo, Arial, Sans-serif;
  padding: 50px 0 20px;
  font-weight: normal;
}

.content {
  display: grid;
  grid-template-columns: repeat(auto-fit, 120px);
  /* use grid gap instead of margin around boxes */
  grid-gap: 10px;
  justify-content: center;
}

.box>div {
  height: 130px;
  background: rgb(146, 163, 191, 0.6);
  border-radius: 8px;
  border: 1px solid #fff;
  color: #fff;
  font-family: Exo, arial, sans-serif;
  font-size: 55px;
  margin-bottom: 20px;
  /* use flexbox instead of lineheight for vertical centering */
  display: flex;
  align-items: center;
  justify-content: center;
}

.box span {
  display: inline-block;
  font-size: 20px;
  font-family: "Exo", arial, sans-serif;
  color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <h2>Apartments Coming Soon!</h2>
  <div class="content">

    <div class="box">
      <div class="days">85</div>
      <span>Days</span>
    </div>
    <div class="box">
      <div class="hours">22</div>
      <span>Hours</span>
    </div>
    <div class="box">
      <div class="minutes">33</div>
      <span>Minutes</span>
    </div>
    <div class="box">
      <div class="seconds">54</div>
      <span>Seconds</span>
    </div>
  </div>
</div>

Answer №3

It's better to split this div into two parts, it will look more organized.

If you have any further questions or if I misunderstood your query, please feel free to let me know.

$(function (){

function countdown() {

var now = new Date();
var eventDate = new Date(2019, 0, 1);
var currentTime = now.getTime();
var evenTime = eventDate.getTime();

var remTime = evenTime - currentTime;

var sec = Math.floor(remTime / 1000);
var min = Math.floor(sec / 60);
var hur = Math.floor(min / 60);
var day = Math.floor(hur / 24);

 hur %= 24;
 min %= 60;
 sec %= 60;

hur = (hur < 10) ? "0" + hur : hur;
min = (min < 10) ? "0" + min : min;
sec = (sec < 10) ? "0" + sec : sec;

$('.seconds').text(sec);
$('.minutes').text(min);
$('.hours').text(hur);
$('.days').text(day);

setTimeout(countdown, 1000);
}

countdown();
});
body {
    background-color: #333;
}
    .container {
    width: 800px;
    height: 350px;
    margin:  auto;
    text-align: center
}

    .container h2 {
    color: #fff;
    font-size: 30px;
    font-family: Exo, Arial, Sans-serif;
    padding: 50px 0 20px;
    font-weight: normal
}

    .container .content {
    width: 100%;
}

    .container .content > div {
    display: inline-block;
    margin: 35px 10px 0;
    width: 120px;
    height: 130px;
    background: rgb(146, 163, 191, .6);
    border-radius: 8px;
    border: 1px solid #fff;
    color: #fff;
    line-height: 138px;
    font-family: Exo, arial, sans-serif;
    font-size: 55px;
}

    .container .title {
    width: ;
    height: 50px;
    position: relative
}

    .container .title span {
    display: inline-block;
    width: 140px;
    font-size: 20px;
    font-family: 'Exo', arial, sans-serif;
    color: #fff;
    line-height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
     <h2>Apartments Coming Soon!</h2>
     <div class="content">
       <div class="days">85</div>
       <div class="hours">22</div>
     </div>
     <div class="title">
       <span>Days</span>
       <span>Hours</span>
     </div>
     <div class="content">
       <div class="minutes">33</div>
       <div class="seconds">54</div>
     </div>
     <div class="title">
       <span>Minutes</span>
       <span>Seconds</span>
     </div>
   </div>

Answer №4

To implement responsive design, you can utilize CSS Media Queries as shown below:

@media (max-width: 992px) {
 .container .content > div, .container .title span {
  width: 20%;
 }
}
@media (max-width: 768px) {
 .container .content > div, .container .title span {
  width: 50%;
 }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with sticky positioning not functioning properly with overlapping scrolling effect

When the user scrolls, I want to create an overlapping effect using the 'sticky' position and assign a new background color to each div (section). However, despite setting 'top' to 0 for the 'sticky' position, the divs still s ...

Tips for effectively implementing React.usecallback

Looking for a way to rewrite the handleClick method using React.useCallback in a function called Parent, which is triggered by a button click event in React and TypeScript. function Parent () { const [isOpen, setIsOpen] = React.useState(false); ...

How can I apply a jquery method to a variable when JavaScript already has a method with the same name?

Is it possible to call the .which function on a character without needing to differentiate between browser types by using the jQuery .which method, which supposedly normalizes for browser discrepancies? I know that the inherent javascript method is also ...

Adding elements in an asynchronous manner

I'm facing a challenge in generating elements based on query results and placing them inside the correct p containers. The problem is that all the elements are ending up in the last container instead of their respective positions. app.Controller.prot ...

Utilizing CSS for displaying and hiding content based on its unique identifier

Is it possible to show/hide a div using only CSS based on its ID? Showcasing this functionality in jQuery or vanilla JavaScript is straightforward, but can the same effect be achieved with pure CSS? The checkbox hack requires a specific structure to func ...

Can you please provide instructions on how to expand the view in the title bar for a JavaScript/CSS/HTML UPW project?

Struggling to integrate the title bar in a UWP project using JavaScript/CSS/HTML and having trouble accessing the necessary APIs. Came across a custom helper class written in c++ in UWP samples on Github, but unable to reference it in my javascript code. H ...

Purge the cache in Highchart before loading data from a JSON file

My current task involves: Using Python Django to generate a json file with specific logic The generated json file is utilized by highchart js code to display a pie chart The code snippet for the highchart js implementation is as follows: // Implementin ...

Ensure that the child div is anchored to the bottom of the parent div container

I am looking for a way to ensure that the subfooter div stays at the bottom of the childbox div, similar to a footer. You can view the code on this jsfiddle link <div class="parentbox"> <div class="childbox"> <div id="subfooter" ...

Error in Java: org.apache.jasper.JasperException - Class compilation error in JSP:

I'm looking to create a website for uploading photos to MySQL using JSP code, but I'm encountering an error that I'm struggling to resolve in the code. First, I found an example "upload.html" <title>Select your File to upload</tit ...

Navigate through the elements of an Ext.form.CheckboxGroup using Ext JS

Currently, I am working with an Ext.form.CheckboxGroup that contains multiple items of Ext.form.Checkbox. I am wondering if there is a way to iterate through each item within the Ext.form.CheckboxGroup? I attempted the code below without success: for ( ...

What is causing my conditional operator to malfunction?

What is the reason for the output being undefined instead of "old" in this scenario? function test(age) { return 12 < age ? "old" : "young"; } test(15); ...

Oops! An uncaught exception error occurred because the primordials were not defined

I used npm to install the package called aws-s3-zipper, but now I am encountering an error. This is the code snippet causing the issue: AWS = require("aws-sdk"); var S3Zipper = require("aws-s3-zipper"); function zipFolderOnS3() { var zipper = new S3 ...

The alignment issue arises when the browser is resized

Something seems off with my images. They appear correctly when I first open the browser, but if I resize it, they go all wonky. Refreshing the page fixes it, but if I open a larger browser window and then make it smaller, it messes up again. It's puzz ...

When using <body onload=foo()>, the function foo will not be executed

Having trouble with this code - it seems like initialize() is not being called. Check out the code here Any insight into why this might be happening? ...

Tips for setting the page size while adjusting the browser window dimensions

Is there a way to make a web page size adjust based on the client's monitor resolution? Currently, my webpage looks good when viewed at 1680x1050 resolution. However, if I change the monitor resolution to something smaller, everything on the page gets ...

Create responsive sizing utility with Bootstrap 5

After exploring the Bootstrap documentation, I gained a better understanding of how to utilize the sizing utility. For instance: <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8 ...

Selection dropdown not being populated by ng-options

After trying numerous examples to implement the changes, I am still facing issues. Even though I have an ng-model and clearly defined the object property I want to receive, it is not functioning as expected. Any assistance would be appreciated. Here is th ...

Exploring how to set dropdown menu width for Angular2 mat-select options

Currently, I am using the angular2 mat-select control and facing an issue with the width and position of its dropdown list menu. By default, it is wider and overflows the element on both sides by a few pixels. I have not found any option for adjusting the ...

Nested React Components in React Router Components

class AppRoutes extends Component { render () { return ( <Suspense fallback={<Spinner/>}> <Switch> <Route exact path="/" component={ HomePage } /> <Route exact path="/acti ...

Styling a clock with rounded corners using CSS: Border-radius trick

Attempting to craft a analog 12-hour clock using basic CSS properties, I initiated the process by forming a square div of the size 500px. Applying a border-radius of 250px resulted in an aesthetically pleasing circle design. Following this step, I incorpor ...