Search code examples
htmlcssanimationbackground-colorkeyframe

CSS animation not fully working?


with Christmas coming up, I thought that it would be the perfect time to code a Christmas countdown. I was able to get through the JavaScript and HTML fine, but started to have some trouble with the CSS. Here is all of my code:

//Gets the HTML Elements
var head = document.getElementById('head');
var subhead = document.getElementById('subhead');
var counter = document.getElementById('counter');
//finds Christmas
var christmas = new Date('December 25, 2016 00:00:00');

//Updates Timer
function updateTimer(christmas) {
    
    var time = christmas - new Date();
    //Gives what to find on update
    return {
        'days': Math.floor(time / (1000 * 60 * 60 * 24)),
        'hours': Math.floor((time/(1000 * 60 * 60)) % 24),
        'minutes': Math.floor((time / 1000 / 60) % 60),
        'seconds': Math.floor((time / 1000) % 60),
        'total': time
    };
};

//Starts the timer
function startTimer(counter, christmas) {
    
    var timerInterval = setInterval(function() {
        var timer = updateTimer(christmas);
        
        //Changes the text of the 'counter'
        counter.innerHTML = '<span>' + timer.days + '</span>'
                       + '<span>' + timer.hours + '</span>'
                        + '<span>' + timer.minutes + '</span>'
                        + '<span>' + timer.seconds + '</span>';
        
        //if christmas
        if(timer.total < 1) {
            clearInterval(timerInterval);
            counter.innerHTML = '<span>0</span><span>0</span><span>0</span><span>0</span>';
            
            head.innerHTML = "It's Christmas!!!";
            subhead.innerHTML = "Merry Christmas to all!!!";
        }
        
        //if christmas eve
        else if (timer.days < 1){
            subhead.innerHTML = "It is currently Christmas Eve! How much longer until Christmas Day???";
        }
   
    }, 1000); //timer updates every second
};

window.onload = function() {
    
    startTimer(counter, christmas);
};  
*:focus {
    outline: none;
}

body {
  background-color: #991f00;
  text-shadow: 2px 2px 8px #000000;
}

header {
    color: white;
    text-align: center;
    font-family: 'Cinzel Decorative', sans-serif;
}

#clock span {
    float: left;
    text-align: center;
    margin: 0 2.5%;
    padding: 20px;
    width: 20%;
    box-sizing: border-box;
    color: white;
    font-family: 'Mountains of Christmas', sans-serif;
    font-size: 40px;
}

#counter span {
    background-color: #000000;
    border-radius: 100%;
    animation-name: colorChange;
    animation-duration: 6s;
    animation-fill-mode: both;
    animation-iteration-count: infinite;
    
}

@keyframes colorChange {
    0%, 100% {
        background-color: #42f471;
    }
    50% {
        background-color: #ea524f;
    }
}
<!DOCTYPE html>
<html>
    <head>
        <title>Christmas Countdown</title>
        <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>!-->
        <script type="text/javascript" src="scripts/script.js" async></script>
        <!--<script type="text/javascript" src="scripts/color.js" async></script>!-->
        <link rel="stylesheet" type="text/css" href="style.css">
        <link href="https://fonts.googleapis.com/css?family=Cinzel+Decorative|Mountains+of+Christmas" rel="stylesheet">
    </head>
    <body>
        <div id="wrapper">
            <div id="clock">
                <header>
                    <h1 id="head">Christmas Countdown!</h1>
                    <h4 id="subhead">How much longer until Christmas? Check the clock to find out!</h4>
                </header>
                <div id="count-container">
                    <div id="counter"></div>
                    <div id="labels">
                        <span>Days</span>
                        <span>Hours</span>
                        <span>Minutes</span>
                        <span>Seconds</span>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

If you look at the code, then you will see that I tried to insert a CSS animation using @keyframes and all. I was trying to get the effect found here: https://kahoot.it/#/ , however only using 2 colors (#42f471 and #ea524f). My thoughts were that I would make #42f471 as the starting color, which would then fade to #ea524f which would also fade back to #42f471. I started by trying set the duration of the animation to 6s but when I loaded up the page, I found that the animation didn't even seem to go halfway, before suddenly flashing back to the first color. Trying an even longer duration, only makes it go through less before flashing back to that original color. Interestingly, though, shorter duration makes it go through more of the animation. At 1s or less, it will go through the animation properly, but that speed is way too fast (I don't want to end up giving anyone a seizure :)). I've searched and searched the internet, but nothing I've tried has helped. I do not have much experience with animations, so almost all the stuff I used to make the animation I got from research on the internet.

Any answers are appreciated. I am also open to answers using JavaScript or Jquery, if necessary.


Solution

  • Notice that the animation is restarting every time the timer updates - this is because those DOM elements are being recreated by your JavaScript, thus the animation is starting over with them. Target your spans by giving them each IDs like this, and you'll see the animation keeps:

    //Gets the HTML Elements
    var head = document.getElementById('head');
    var subhead = document.getElementById('subhead');
    var counterDays = document.getElementById('days');
    var counterHours = document.getElementById('hours');
    var counterMinutes = document.getElementById('minutes');
    var counterSeconds = document.getElementById('seconds');
    //finds Christmas
    var christmas = new Date('December 25, 2016 00:00:00');
    
    //Updates Timer
    function updateTimer(christmas) {
        
        var time = christmas - new Date();
        //Gives what to find on update
        return {
            'days': Math.floor(time / (1000 * 60 * 60 * 24)),
            'hours': Math.floor((time/(1000 * 60 * 60)) % 24),
            'minutes': Math.floor((time / 1000 / 60) % 60),
            'seconds': Math.floor((time / 1000) % 60),
            'total': time
        };
    };
    
    //Starts the timer
    function startTimer(counterDays, counterHours, counterMinutes, counterSeconds, christmas) {
        
        var timerInterval = setInterval(function() {
            var timer = updateTimer(christmas);
            
            //Changes the text of the 'counter'
            counterDays.innerHTML = timer.days;
            counterHours.innerHTML = timer.hours;
            counterMinutes.innerHTML = timer.minutes;
            counterSeconds.innerHTML = timer.seconds;
            
            //if christmas
            if(timer.total < 1) {
                clearInterval(timerInterval);
                counterDays.innerHTML = 0;
                counterHours.innerHTML = 0;
                counterMinutes.innerHTML = 0;
                counterSeconds.innerHTML = 0;
                
                head.innerHTML = "It's Christmas!!!";
                subhead.innerHTML = "Merry Christmas to all!!!";
            }
            
            //if christmas eve
            else if (timer.days < 1){
                subhead.innerHTML = "It is currently Christmas Eve! How much longer until Christmas Day???";
            }
       
        }, 1000); //timer updates every second
    };
    
    window.onload = function() {
        
        startTimer(counterDays, counterHours, counterMinutes, counterSeconds, christmas);
    };
    *:focus {
        outline: none;
    }
    
    body {
      background-color: #991f00;
      text-shadow: 2px 2px 8px #000000;
    }
    
    header {
        color: white;
        text-align: center;
        font-family: 'Cinzel Decorative', sans-serif;
    }
    
    #clock span {
        float: left;
        text-align: center;
        margin: 0 2.5%;
        padding: 20px;
        width: 20%;
        box-sizing: border-box;
        color: white;
        font-family: 'Mountains of Christmas', sans-serif;
        font-size: 40px;
    }
    
    #counter span {
        background-color: #000000;
        border-radius: 100%;
        animation-name: colorChange;
        animation-duration: 6s;
        animation-fill-mode: both;
        animation-iteration-count: infinite;
        
    }
    
    @keyframes colorChange {
        0%, 100% {
            background-color: #42f471;
        }
        50% {
            background-color: #ea524f;
        }
    }
    <!DOCTYPE html>
    <html>
        <head>
            <title>Christmas Countdown</title>
            <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>!-->
            <script type="text/javascript" src="scripts/script.js" async></script>
            <!--<script type="text/javascript" src="scripts/color.js" async></script>!-->
            <link rel="stylesheet" type="text/css" href="style.css">
            <link href="https://fonts.googleapis.com/css?family=Cinzel+Decorative|Mountains+of+Christmas" rel="stylesheet">
        </head>
        <body>
            <div id="wrapper">
                <div id="clock">
                    <header>
                        <h1 id="head">Christmas Countdown!</h1>
                        <h4 id="subhead">How much longer until Christmas? Check the clock to find out!</h4>
                    </header>
                    <div id="count-container">
                        <div id="counter">
                            <span id="days">&nbsp;</span>
                            <span id="hours">&nbsp;</span>
                            <span id="minutes">&nbsp;</span>
                            <span id="seconds">&nbsp;</span>
                        </div>
                        <div id="labels">
                            <span>Days</span>
                            <span>Hours</span>
                            <span>Minutes</span>
                            <span>Seconds</span>
                        </div>
                    </div>
                </div>
            </div>
        </body>
    </html>