Friday, September 21, 2012

Timed notifications with CSS animations

notifications

A quick tip on how to create some simple timed notifications with CSS animations. The idea is to show a notification with a progress bar for a specific duration and then make it disappear.

You definitely saw it already somewhere, I discovered it on buysellads.com where timed notifications are shown i.e. after saving some settings.

For the markup we'll simply have a division with a message inside and with an additional division for the little progress bar:

<div class="tn-box tn-box-color-1">
    <p>Your settings have been saved successfully!</p>
    <div class="tn-progress"></div>
</div>

The notification box is going to have the classes tn-box and tn-box-color-1 which will be used for defining different colors.
Then we define the style of the box:

.tn-box {
    width: 360px;
    position: relative;
    margin: 0 auto 20px auto;
    padding: 25px 15px;
    text-align: left;
    border-radius: 5px;
    box-shadow: 
        0 1px 1px rgba(0,0,0,0.1), 
        inset 0 1px 0 rgba(255,255,255,0.6);  
    opacity: 0;
    cursor: default;
    display: none;
}

.tn-box-color-1{
    background: #ffe691;
    border: 1px solid #f6db7b;
}

We'll set the box to display: none and give it 0 opacity.
The progress bar will have the following style:

.tn-progress {
    width: 0;
    height: 4px;
    background: rgba(255,255,255,0.3);
    position: absolute;
    bottom: 5px;
    left: 2%;
    border-radius: 3px;
    box-shadow: 
        inset 0 1px 1px rgba(0,0,0,0.05), 
        0 -1px 0 rgba(255,255,255,0.6);
}

Initially, the bar will have 0 width.
In this example, I’m using a button with a checkbox that will start the animations once it’s checked:

input.fire-check:checked ~ section .tn-box {
    display: block;
    animation: fadeOut 5s linear forwards;
}

input.fire-check:checked ~ section .tn-box .tn-progress {
    animation: runProgress 4s linear forwards 0.5s;
}

The button precedes the section with the notification boxes and so I can use the general sibling combinator.
If you maybe want to add a class with JavaScript instead, you could define something like this:

.tn-box.tn-box-active {
    display: block;
    animation: fadeOut 5s linear forwards;
}

.tn-box.tn-box-active .tn-progress {
    animation: runProgress 4s linear forwards 0.5s;
}

where tn-box-active is the class you add to the tn-box div.

The animation for the box itself is the following:

@keyframes fadeOut {
    0%  { opacity: 0; }
    10% { opacity: 1; }
    90% { opacity: 1; transform: translateY(0px);}
    99% { opacity: 0; transform: translateY(-30px);}
    100% { opacity: 0; }
}

I called it "fadeOut" but it actually fades the box in first and then it makes it fade out and move up a bit.
The animation for the progress bar looks like this:

@keyframes runProgress {
    0%  { width: 0%; background: rgba(255,255,255,0.3); }
    100% { width: 96%; background: rgba(255,255,255,1); }
}

We animate the width to 96% (left was 2% so we want it to stop 2% from the right as well) and the opacity of the RGBA value.
The duration of the progress bar animation will be a bit less than the duration of the box animation, since we will start it later (the box needs to fade in first).

Note: What I thought would be nice, is a pausing of the animation on hover. This makes sense if the user wants to take more time to read what the notification says. But unfortunately, there seems to be some issues with WebKit browsers. In Chrome (19.0.1084.56 on Win) the animation breaks while in Safari (5.1.5 Win) I get a crash report on WebKit2WebProcess.exe... It works perfectly fine in Firefox > 12.0.

Anyway, here is how you could do it:

.tn-box.tn-box-hoverpause:hover, 
.tn-box.tn-box-hoverpause:hover .tn-progress{
    animation-play-state: paused;
}

Needless to say, this will only work in browsers that support CSS animations! You'll need some kind of JS fallback for other browsers.

View Demo

via Codrops - by