Video icon 64
Want to be a web designer? Skill up fast with video courses from Tuts+. Start your free trial.
Advertisement

Menu Notification Badges Using HTML5 Data-Attributes

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →
This post is part of a series called Bringing Premium Pixels to Life.
Skin Orman Clark's Video Interface Using jPlayer and CSS
Build a Popup Modal Window Using the jQuery Reveal Plugin

Today we're going to take Orman Clark's Menu Notification Badges design and build it using HTML and CSS. We'll look at a couple of ways to achieve the effect, including the use of HTML5 data attributes which you may be unfamiliar with. Let's dive in!


Step 1: HTML5 Base Markup

Let's start off by throwing in some basic markup. We'll be using the HTML5 doctype throughout the tutorial. We'll create the menu itself by first adding a main div followed by list items which will create each menu link. We've also included the HTML5 shiv (or shim) script in the head of our document. This is called into play with older versions of Internet Explorer, allowing them to recognize and style HTML5 elements.

<!DOCTYPE html>
<html>
	<head>

		<!--Meta tags-->
		<meta charset="utf-8">

		<!--Title-->
		<title>Menu Notification Badges</title>
		
		<!--Stylesheets-->
		<link rel="stylesheet" href="styles.css">

		<!--HTML5 Shiv-->
		<!--[if lt IE 9]>
			<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
		<![endif]-->

</head>
<body>







</body>
</html>


Step 2: Menu Markup

To create the structure of our menu we'll use an un-ordered list with 4 list items and an anchor tag inside. You may also want to nest the list within a <nav> tag for deployment.

For the sake of this demonstration, we'll create a div around the menu with a class of wrapper. This will just be used to move the menu to the middle of the page.

Your markup should look something like this;

<!DOCTYPE html>
<html>
	<head>

		<!--Meta tags-->
		<meta charset="utf-8">

		<!--Title-->
		<title>Menu Notification Badges</title>
		
		<!--Stylesheets-->
		<link rel="stylesheet" href="styles.css">

		<!--HTML5 Shiv-->
		<!--[if lt IE 9]>
			<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
		<![endif]-->

</head>
<body>



<div class="wrapper">
	<ul class="menu">
		<li><a href="#">Profile</a></li>
		<li><a href="#">Setting</a></li>
		<li><a href="#">Notifications</a></li>
		<li><a href="#">Logout</a></li>
	</ul>	
</div>



</body>
</html>

Step 3: Some Basic CSS

Before we start styling the menu, we'll add some resets and some page styling. We'll first throw in a reset to remove any margins, padding etc from browser default stylesheet. Next we'll apply a background color to the body and a font-size of 16px. This fixed font size ensures the base size for our demo, but you may prefer to set it to 100% thus allowing the user to define their browser font size. We'll apply a width of 70% to the wrapper and center it with a margin-top of 200px.

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; backound: transparent; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } :focus { outline: 0; } ins { text-decoration: none; } del { text-decoration: line-through; } table { border-collapse: collapse; border-spacing: 0; } a { text-decoration: none; }

body { background:#ededed; font-size:16px; }



.wrapper {
	width: 70%;
	margin: 200px auto;
}

Step 4: Menu Base Styles

To kick off styling the menu, we'll first focus on the base of it. Target the un-ordered list first, which was given a class of 'menu'. We'll give it a display of inline-block, allowing us to determine the width/height of it depending on its content like a block element.

Next we'll apply a gradient background with all the browser prefixes. Then add some border radius, but hey what are those ems?! We're using ems (instead of pixels) to size the border radius relative to the font size. Check out the demo; you'll see the radius grow proportionately along with the larger text.

To work out the size we need, we'll take 16px (our body font size) and divide it by 3 (our desired border radius size in px). So 16px/3px = 0.188 but we'll round that up to 0.2.

Next we'll apply a simple gray border, then a box shadow with a drop and inset shadow. Don't forget those browser prefixes too!

.menu {
	display: inline-block;

	background-image: -webkit-linear-gradient(top, rgb(249, 249, 249), rgb(240, 240, 240));
	background-image: -moz-linear-gradient(top, rgb(249, 249, 249), rgb(240, 240, 240));
	background-image: -o-linear-gradient(top, rgb(249, 249, 249), rgb(240, 240, 240));
	background-image: -ms-linear-gradient(top, rgb(249, 249, 249), rgb(240, 240, 240));
	background-image: linear-gradient(top, rgb(249, 249, 249), rgb(240, 240, 240));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f9f9f9', EndColorStr='#f0f0f0');

	-webkit-border-radius:0.2em;
	-moz-border-radius:0.2em;
	border-radius:0.2em;

	border:1px solid #cecece;

	-webkit-box-shadow:
		inset 0px 1px 0px #fff,
		0px 1px 2px rgba(0,0,0,.06);
	-moz-box-shadow:
		inset 0px 1px 0px #fff,
		0px 1px 2px rgba(0,0,0,.06);
	box-shadow:
		inset 0px 1px 0px #fff,
		0px 1px 2px rgba(0,0,0,.06);
}

Step 5: List Items

Moving on, let's improve the menu by styling the list items. First we'll float the list items to the left so they're all on one line and not listed. We'll then position them relatively, this will be needed later on when we create the badges. Next we'll add a border on the left and a border on the right.

Now we'll need to target the first list item and the last list item, so we'll do this by using the pseudo selectors; :first-child and :last-child (bear browser support in mind when using these. For the first one we'll remove the border left and we'll remove the right border from the last list item.

.menu li {
	float:left;
	position:relative;

	border-right:1px solid #d8d8d8;
	border-left:1px solid #ffffff;
}
.menu li:first-child { border-left:none; }
.menu li:last-child  { border-right:none;}

Step 6: Anchor Tags

Next thing we'll need to do is style the anchor tags. First we'll give them a font-family of Helvetica Neue with some font-stack fall backs for people who don't have the Helvetica font. Next we'll give them a font size of 0.75em (13px/16px=0.75). Then we'll apply a font weight of bold, followed by a color of #666666 and apply a text shadow.

We'll now apply some padding to the left and right of 1em (13px/13px=1) and some line-height to center the text vertically. We've based the line-height on 30px, interpreted into ems.

.menu li a {
	font-family:'Helvetica Neue', Helvetica, sans-serif;
	font-size:0.75em;
	font-weight:bold;
	color:#666666;
	text-shadow:0px 1px 0px #ffffff;

	display: block;
	padding:0 1em;
	line-height:2.5em;
}

Our menu is starting to look pretty good now!

Anchor Tag Styles

Step 7: Notification Bubbles Markup

Time to add the cool little notification bubbles. First you'll need to replace your menu HTML markup with the following. We'll create the bubbles using span tags, then for each color we'll apply an appropriate class. I've added pink, yellow and blue.

<div class="wrapper">
	<ul class="menu">
		<li><a href="#">Profile<span class="pink">2</span></a></li>
		<li><a href="#">Setting<span class="yellow">3</span></a></li>
		<li><a href="#">Notifications<span class="blue">6</span></a></li>
		<li><a href="#">Logout</a></li>
	</ul>
</div>

Step 8: Styling the Notification Bubbles

To create the notification bubbles we'll first style the span tags with everything except for the color and border color. This way we can change the colors easily by simply changing class names.

First we'll create some widths and heights, take 18px/12px=1.5em. Then we'll need to position them absolutely (0.5em from the right and -2em from the top). Next, a line height will be applied to center the number vertically and text-align center is used to center horizontally.

A font-family will be applied with Helvetica Neue, again with fallbacks for users without Helvetica. We'll make it bold, apply a color of white and then add a text-shadow. Next we'll add some box-shadows (we'll add two; one drop shadow and one inset shadow). Remember to create these while using browser prefixes. Now we'll add a border-radius of 4em (roughly 50px).

For the next stage in the process, we'll take advantage of some CSS3 techniques and get the hover effect working. We'll first hide the bubble using an opacity of 0. Next, to create our cool little animations we'll use some transitions. We'll target the top and opacity and tell it to ease-in over a period of 0.3 seconds (3 milliseconds). These will need the browser prefixes applied including -o- and -ms-.

span {
	position:absolute;
	top:-2em;
	right: 0.5em;

	width: 1.5em;
	height: 1.5em;

	line-height:1.5em;
	text-align:center;

	ont-family:'Helvetica Neue', Helvetica, sans-serif;
	font-weight:bold;
	color:#fff;
	text-shadow:0px 1px 0px rgba(0,0,0,.15);

	-webkit-box-shadow:
		inset 0px 1px 0px rgba(255,255,255,35),
		0px 1px 1px rgba(0,0,0,.2);
	-moz-box-shadow:
		inset 0px 1px 0px rgba(255,255,255,.35),
		0px 1px 1px rgba(0,0,0,.2);
	box-shadow:
		inset 0px 1px 0px rgba(255,255,255,.35),
		0px 1px 1px rgba(0,0,0,.2);

	-webkit-border-radius:4em;
	-moz-border-radius:4em;
	border-radius:4em;

	opacity:0;
filter: alpha(opacity=0);

	-webkit-transition: .3s top ease-in, .3s opacity ease-in;
	-moz-transition: .3s top ease-in, .3s opacity ease-in;
	-o-transition: .3s top ease-in, .3s opacity ease-in;
	-ms-transition: .3s top ease-in, .3s opacity ease-in;
	transition: .3s top ease-in, .3s opacity ease-in;
}

Step 9: Bubble Colors

Time for the final aesthetic touches on the bubbles; adding some CSS to style the colors. Remember the classes we added to the span tags? These will make things simple enough, we'll target each color, apply a gradient and a border color.

.pink {
	background-image: -webkit-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -moz-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -o-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -ms-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f78297', EndColorStr='#f46677');

	border:1px solid #ce4f5e;
}
.yellow {
	background-image: -webkit-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -moz-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -o-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -ms-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#feda71', EndColorStr='#feba48');

	border:1px solid #dea94f;
}
.blue {
	background-image: -webkit-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -moz-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -o-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -ms-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ace4f8', EndColorStr='#6ccdf3');

	border:1px solid #79b5cb;
}

Step 10: Hover Styles

Of course, our bubbles are beautifully styled, but completely invisible. We'll need to add some CSS to allow the bubbles to show on hover. First add some color to the anchor tags when they're hovered over, just a simple dark gray. Next we'll target the span when its parent list item is hovered over. We'll add an opacity of 1 to make it visible and change the top position value to make it appear as if it's sliding down.

.menu li:hover a {
	color: #343434;
}

.menu li:hover a span {
	top:-1em;
	opacity:1;
filter: alpha(opacity=100);
}
Hover Styles

So What About HTML5 Data Attributes?

Glad you asked..


Step 11: Change the Menu HTML Markup

To create our menu with HTML5 data attributes we'll first need to change our HTML Markup. We're going to use some custom attributes to create the bubbles. HTML5 introduced a new data- attribute where the attribute name can be anything as long as it's at least 1 character long and starts with 'data-'.

For this tutorial we'll use 'data-bubble'. These will allow us to store and access our notification values without adding unnecessary markup structure to our document. Notice we've also moved our color classes onto the anchor tags.

<div id="wrapper">
	<ul class="menu">
		<li><a href="#" class="pink" data-bubble="2">Profile</a></li>
		<li><a href="#" class="yellow" data-bubble="3">Setting</a></li>
		<li><a href="#" class="blue" data-bubble="6">Notifications</a></li>
		<li><a href="#">Logout</a></li>
	</ul>
</div>

Step 12: Removing Some CSS

As we're no longer going to be working with the span elements, you'll need to go back to your CSS and delete the following rules;

span {
	position:absolute;
	top:-2em;
	right: 0.5em;

	width: 1.5em;
	height: 1.5em;

	line-height:1.5em;
	text-align:center;

	font-family:"Helvetica Neue";
	font-weight:bold;
	color:#fff;
	text-shadow:0px 1px 0px rgba(0,0,0,.15);

	-webkit-box-shadow:
		inset 0px 1px 0px rgba(255,255,255,35),
		0px 1px 1px rgba(0,0,0,.2);
	-moz-box-shadow:
		inset 0px 1px 0px rgba(255,255,255,.35),
		0px 1px 1px rgba(0,0,0,.2);
	box-shadow:
		inset 0px 1px 0px rgba(255,255,255,.35),
		0px 1px 1px rgba(0,0,0,.2);

	-webkit-border-radius:4em;
	-moz-border-radius:4em;
	border-radius:4em;

	opacity:0;
filter: alpha(opacity=0);

	-webkit-transition: .3s top ease-in, .3s opacity ease-in;
	-moz-transition: .3s top ease-in, .3s opacity ease-in;
	-o-transition: .3s top ease-in, .3s opacity ease-in;
	-ms-transition: .3s top ease-in, .3s opacity ease-in;
	transition: .3s top ease-in, .3s opacity ease-in;
}

.pink {
	background-image: -webkit-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -moz-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -o-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -ms-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f78297', EndColorStr='#f46677');

	border:1px solid #ce4f5e;
}
.yellow {
	background-image: -webkit-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -moz-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -o-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -ms-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#feda71', EndColorStr='#feba48');

	border:1px solid #dea94f;
}
.blue {
	background-image: -webkit-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -moz-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -o-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -ms-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ace4f8', EndColorStr='#6ccdf3');

	border:1px solid #79b5cb;
}

.menu li:hover a span {
	top:-1em;
	opacity:1;
filter: alpha(opacity=100);
}

Step 13: Adding Some CSS

Now let's target our data-attributes instead, we'll need to add some rules to our CSS.

It will look very similar to what we used for our span elements. This time though, we'll target the the :after pseudo elements of anchor tags with an attribute of "data-bubble". To do so we're using CSS Attribute Selectors.

As we're using an :after pseudo (and thereby generating content) we'll need to define some meat within it with content:''. Once again we'll use our custom attribute we created in our HTML and insert that.

Again, to manage the visibility of our bubble, we'll give it an opacity of 1 when the link is hovered over. Unfortunately, due to limitations with attribute selectors we cannot animate them with CSS itself.

.menu li a[data-bubble]:after {
	content:attr(data-bubble);
	position:absolute;
	top:-1.25em;
	right: 0.5em;

	width: 1.5em;
	height: 1.5em;

	line-height:1.5em;
	text-align:center;

	font-family:"Helvetica Neue";
	font-weight:bold;
	color:#fff;
	text-shadow:0px 1px 0px rgba(0,0,0,.15);

	-webkit-box-shadow:
		inset 0px 1px 0px rgba(255,255,255,35),
		0px 1px 1px rgba(0,0,0,.2);
	-moz-box-shadow:
		inset 0px 1px 0px rgba(255,255,255,.35),
		0px 1px 1px rgba(0,0,0,.2);
	box-shadow:
		inset 0px 1px 0px rgba(255,255,255,.35),
		0px 1px 1px rgba(0,0,0,.2);

	-webkit-border-radius:4em;
	-moz-border-radius:4em;
	border-radius:4em;

	opacity:0;
filter: alpha(opacity=0);
}
.menu li:hover a[data-bubble]:after {
	opacity:1;
filter: alpha(opacity=100);
}

Step 14: Colors for Attributes

Finally, we need to style the generated content within the various classes so we can change the colors easily (exactly as we did with the span elements).


a.pink[data-bubble]:after {
	background-image: -webkit-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -moz-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -o-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: -ms-linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	background-image: linear-gradient(top, rgb(247, 130, 151), rgb(244, 102, 119));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f78297', EndColorStr='#f46677');

	border:1px solid #ce4f5e;
}
a.yellow[data-bubble]:after {
	background-image: -webkit-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -moz-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -o-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: -ms-linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	background-image: linear-gradient(top, rgb(254, 218, 113), rgb(254, 186, 72));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#feda71', EndColorStr='#feba48');

	border:1px solid #dea94f;
}
a.blue[data-bubble]:after {
	background-image: -webkit-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -moz-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -o-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: -ms-linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	background-image: linear-gradient(top, rgb(172, 228, 248), rgb(108, 205, 243));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ace4f8', EndColorStr='#6ccdf3');

	border:1px solid #79b5cb;
}

Conclusion

We've successfully created a menu along with some neat notification bubbles and animated them! We've even gone further and taken advantage of new techniques within HTML5.

Completed

I hope you enjoyed this tutorial, thanks for reading!

Advertisement