How to Make a Pure CSS Alert Bar

How to Make a Pure CSS Alert Bar

Demo

This post will take 4 minutes to read.

What we will be making:

I have slowly noticed more and more sites using pop from the top style noti­fic­a­tions. They can be very effect­ive if used cor­rectly. Today I am going to run through the cre­ation of such an alert bar using only CSS; no images and no JavaScript. To make things even more inter­est­ing, the bar will per­sist until clicked.

I won’t be using browser pre­fixes in this tutori­al, make sure that you do. If you need help determ­in­ing which pre­fixes to use for what prop­er­ties then check out this handy site: When can I use…

Before you read on click here to load jsFiddle in a new tab.

The Plan:

  1. Markup
  2. Form
  3. Animation
  4. Behaviour
  5. Instruction
  6. Design

Want to see the fin­ished code? Click here.

Step 1: Markup

The markup is pretty straight­for­ward: an anchor wrapped in a div. We will be doing a neat little trick with the anchor and div later on.

<div id="alert">
    <a class="alert" href="#alert">This is a slide down alert!</a>
</div>

Step 2: Form

Now let’s give the alert some basic form. To do that we need to con­sider what it is we want:

  • 100% width
  • Centered text
  • Attached to the top of the view­port
  • Above all oth­er con­tent
  • Bright col­or

The fol­low­ing CSS pro­duces an alert that matches our require­ments nicely:

.alert {
    background-color: #c4453c;
    color: #f6f6f6;
    display: block;
    font: bold 16px/40px sans-serif;
    height: 40px;
    position: absolute;
    text-align: center;
    text-decoration: none;
    top: -45px;
    width: 100%;
}

Those with a keen eye may have noticed that I used top: -45px; instead of top: 0;. This is in pre­par­a­tion for the next step…

Step 3: Animation

By default, the alert is hid­den off the top of the screen, we are going to use an anim­a­tion to slide it down. That way, browsers that don’t sup­port anim­a­tions (and prob­ably some of the oth­er advanced tech­niques we will be using) won’t see the alert at all. Here is a simple entrance anim­a­tion for our noti­fic­a­tion:

@keyframes alert {
    0% { opacity: 0; }
    50% { opacity: 1; }
    100% { top: 0; }
}

Now all we need to do is run the anim­a­tion on the anchor.

.alert {
    animation: alert 1s ease forwards;
}

Step 4: Behaviour

Now we have our alert show­ing, but wouldn’t it be great if there was a way to get rid of it when we had fin­ished read­ing it? That’s where our wrap­per div comes in. We are going to use the :target pseudo-class to style the wrap­per when it becomes the tar­get (the URL’s hash is the value of its ID). If you are unsure what I am talk­ing about look back at the markup, see that the ‘href‘ matches the ID of the wrap­per div?

Here is the rel­ev­ant CSS:

#alert:target {
    display: none;
}

Step 5: Instruction

Great, now we can close the alert. There is a slight prob­lem though; how will users know that click­ing closes the alert? Well let’s add a tool­tip to inform them!

We can use pseudo-ele­ments to avoid extra markup. We will use both the :before and :after pseudo-ele­ments, one for the body of the tool­tip, and one for the arrow.

#alert {
    position: relative;
}
#alert:hover:after {
    background: hsla(0,0%,0%,.8);
    border-radius: 3px;
    color: #f6f6f6;
    content: 'Click to dismiss';
    font: bold 12px/30px sans-serif;
    height: 30px;
    left: 50%;
    margin-left: -60px;
    position: absolute;
    text-align: center;
    top: 50px;
    width: 120px;
}
#alert:hover:before {
    border-bottom: 10px solid hsla(0,0%,0%,.8);
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    content: '';
    height: 0;
    left: 50%;
    margin-left: -10px;
    position: absolute;
    top: 40px;
    width: 0;
}

Notice that I have used pseudo-ele­ments with the :hover pseudo-class. This is fine to do as long as you order it as I have (pseudo-class before pseudo-ele­ment).

Step 6: Design

We now have ourselves a beau­ti­fully work­ing alert. It looks a bit plain though. How about using a lin­ear gradi­ent to give an effect sim­il­ar to warn­ing tape?

.alert {
    background-image: linear-gradient(135deg, transparent,
                      transparent 25%, hsla(0,0%,0%,.1) 25%,
                      hsla(0,0%,0%,.1) 50%, transparent 50%,
                      transparent 75%, hsla(0,0%,0%,.1) 75%,
                      hsla(0,0%,0%,.1));
    background-size: 20px 20px;
}

Finally, we can add a subtle bor­der to the bot­tom to help sep­ar­ate the alert from the con­tent below it. To do this I am going to use a simple box-shadow:

.alert {
    box-shadow: 0 5px 0 hsla(0,0%,0%,.1);
}

And that is it! Pretty simple wasn’t it?

Final Product:

<div id="alert">
    <a class="alert" href="#alert">This is a slide down alert!</a>
</div>

#alert {
    position: relative;
}
#alert:hover:after {
    background: hsla(0,0%,0%,.8);
    border-radius: 3px;
    color: #f6f6f6;
    content: 'Click to dismiss';
    font: bold 12px/30px sans-serif;
    height: 30px;
    left: 50%;
    margin-left: -60px;
    position: absolute;
    text-align: center;
    top: 50px;
    width: 120px;
}
#alert:hover:before {
    border-bottom: 10px solid hsla(0,0%,0%,.8);
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    content: '';
    height: 0;
    left: 50%;
    margin-left: -10px;
    position: absolute;
    top: 40px;
    width: 0;
}
#alert:target {
    display: none;
}
.alert {
    animation: alert 1s ease forwards;
    background-color: #c4453c;
    background-image: linear-gradient(135deg, transparent,
                      transparent 25%, hsla(0,0%,0%,.1) 25%,
                      hsla(0,0%,0%,.1) 50%, transparent 50%,
                      transparent 75%, hsla(0,0%,0%,.1) 75%,
                      hsla(0,0%,0%,.1));
    background-size: 20px 20px;
    box-shadow: 0 5px 0 hsla(0,0%,0%,.1);
    color: #f6f6f6;
    display: block;
    font: bold 16px/40px sans-serif;
    height: 40px;
    position: absolute;
    text-align: center;
    text-decoration: none;
    top: -45px;
    width: 100%;
}

@keyframes alert {
    0% { opacity: 0; }
    50% { opacity: 1; }
    100% { top: 0; }
}

I have attemp­ted to keep this tutori­al as short as pos­sible so if you would like me to go into any more detail just let me know.

Tweet this