Advertisement
CSS

Responsive HTML 5 and CSS 3 Flexbox Dropdown Menu

Post image

HTML and CSS are evolving almost daily, with new features and standards being addopted by browsers. One of the most highly anticipated implementation is Flexbox. Until very recently this had been adopted by all but Firefox, this has now changed!

Flexbox has been described by some as CSS's next ground-breaking feature after CSS Media Queries - those little things that enable responsive layouts. Flexbox is essentially a layout module, similar to that of display: block. With the use of Flexbox we're now able to move more towards Responsive Web Design (RWD) 2.0 - the next faddy term.

This post aims to take you through a basic example of Flexbox, applying it to a HTML 5 navigation, using the latest CSS 3 styling. The navigation bar isn't only utilising Flexbox, essentially it's a responsive, HTML 5 and CSS 3 Flexbox navigation & dropdown menu... and breathe!

Here's what we'll be creating -

See the Pen Flexbox dropdown navigation menu by lawnch (@lawnch) on CodePen.

Resetting the CSS

I cover this in all my CSS posts, and here it is again. Before starting any project it's best to import some basic reset's to nullify default browser styling differences

* {margin: 0;padding: 0;outline: none;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
*:after, *:before { -webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section {  display: block;}
html {font-size: 100%;height: auto !important;height: 100%;-webkit-text-size-adjust: 100%;-ms-text-size-adjust: 100%;}
.clear {display: block;	}
.clear::after {clear: both;content: ".";display: block;height: 1px;visibility: hidden;}
	
/*GENERIC STYLES*/
body { background: #f2f2f2;color: #222;-webkit-font-smoothing: antialiased;font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size: 1.05em;font-weight: 400;height: auto !important;height: 100%;line-height: 1.6rem;min-height: 100%;}

I have also included some basic body styling in which I define body background colors, font styles and sizes, line heights, and margins. This style can be whatever you want and isn't directly important for the navigation bar to work.

Header

Within the header we're going to use two HTML 5 elements, <nav> and <header>. The "nav" element will be used to define the actual navigation list, whereas the heaader element will be our generic container, in which you may also decide to place a logo, search bar, and user bar.

To start we do -

<header role="banner">
	<nav role="navigation">
	
	</nav>
</header">

You may also notice the use of the "role" attribute. For more information on ARIA Landmark Roles, click here.

This code stands as our basic nav wrapper. Now let's look at styling it.

For our navigation wrapper style we can use an opaque gradient effect, perfect if you decide to use a "fixed" navigation bar.

header {
	background: linear-gradient(to left,rgba(54,194,182,0.96) 0,rgba(62,188,207,0.96) 100%);
	border-bottom: 1px solid rgba(0,0,0,.1);
	box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
	display: block;
	position: fixed;
	width: 100%;
	z-index: 1000;
}

Broken down that means -

  • background - using a left to right gradient, go from a light blue to a light green, both with 96% opacity
  • border-bottom - a 1px bottom border of 10% opacity black
  • box-shadow - a 1px vertical; 1px blur, box shadow of 10% opacity black
  • display - block element to span page width
  • position - fixed, stick the nav bar at the top of the page
  • width - 100%, full width of the page
  • z-index - place ontop of everything with a z-index lower than 1000

Navigation List

An almost unanomous decision with websites is that naivgation bars should consist of list's rather than tables. This has been the case since HTML 4 and will remain for the forseeable future.

There are two types of list, ordered and unordered. For our navigation we want to use an unordered list - <ul>.

<header role="banner">
	<nav role="navigation">
		<ul>
			<li>
				<a href="/">
					<div>
						Home
						<span>there's no place like it</span>
					</div>
			</a>
			</li>
		<ul>
	</nav>
</header">

This gives us our basic HTML 5 navigation menu layout.

Flexbox Styling

Next we need to add our Flexbox styling. This will allow us to maximise the space of our navigation bar, enabling a truely responsive design that can also fit around development.

header > nav > ul {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-start;
	list-style: none;
	margin: 0;
	padding: 0;
}

	header > nav > ul > li {
		flex: 0 1 auto;
		margin: 0;
		padding: 0;
		position: relative;
		transition: all linear 0.1s;	
	}
	
		header > nav > ul > li > a {
			align-items: flex-start;
			color: #fff;
			display: flex;
			font-size: 1.55rem;
			font-weight: 200;
			letter-spacing: 1px;
			max-width: 130px;
			padding: 1rem 1.5rem;
			text-decoration: none;
			text-shadow: 0 1px 1px rgba(0,0,0,.1);
			transition: all linear 0.1s;
		}

A breakdown of the CSS 3 styles -

  • display: flex; - Displays an element as a box-level flex container
  • flex-wrap: wrap; - Specifies whether the flex items should wrap or not
  • justify-content: flex-start; - See table below
  • flex: 0 1 auto; - Specifies the length of the item, relative to the rest of the flexible items
  • transition: all linear 0.1s; - CSS 3 animation, animate all styles, in a linear way, lasting 0.1 seconds
  • align-items: flex-start; - Default alignment inside flexible container

The justify-content styling options are detailed below -

CSS 3: justify-content
Value Description
flex-start Default value. Items are positioned at the beginning of the container
flex-end Items are positioned at the end of the container
center Items are positioned at the center of the container
space-between Items are positioned with space between the lines
space-around Items are positioned with space before, between, and after the lines

For this tutorial I've used flex-start, you can change this to suit your needs.

With our CSS in place we can finalise our HTML for the navigation -

<header role="banner">
	<nav role="navigation">
		<ul>
			<li>
				<a href="/">
					<div>
						Home
						<span>there's no place like it</span>
					</div>
				</a>
			</li>
			<li>
				<a href="/blog">
					<div>
						Blog
						<span>my thoughts rock</span>
					</div>
				</a>
			</li>
			<li>
				<a href="/contact">
					<div>
						Contact
						<span>drop me a line</span>
					</div>
				</a>
			</li>
			<li>
				<a href="/forum">
					<div>
						Forum
						<span>chat with others</span>
					</div>
				</a>
			</li>
		</ul>
	</nav>
</header>

CSS 3 Dropdown Menu

Next we can move onto adding a simple dropdown menu. For this example I'm only including a single tier, if you want to know how to add more then visit my previous navigation tutorial - Easy HTML 5 & CSS 3 Navigation Menu.

To add a dropdown menu we simply need to use a nested list inside our navigation list. By wrapping the nested list in a div we can give a nicer "box" effect, adding rounded corners and box shadows.

Our "blog" menu item should now look like this -

<li>
	<a href="/blog">
		<div>
			Blog
			<span>my thoughts rock</span>
		</div>
	</a>
	<div>
		<ul>
			<li><a href="#">Me</a></li>
			<li><a href="#">Gaming</a></li>
			<li><a href="#">Sport</a></li>
			<li><a href="#">Web Design</a></li>
			<li><a href="#">Web Development</a></li>
		</ul>
	</div>
</li>

As you can see, we have the normal link to the blog, followed by a nested list that is wrapped in a div.

To style this we need to use the preceded CSS 3 selector - "+". In theory, we need to say - "if the link is preceded by a div, hide it until it's hovered over, then display it". Now we can't do that all in 1 definition, but it explains what we're looking to achieve, and this is how it's done -

header > nav > ul > li a + div {
	background: linear-gradient(to bottom,rgba(58,162,173,1) 0,rgba(62,188,207,0.96) 100%);
	border-radius: 0 0 2px 2px;
	box-shadow: 0 3px 1px rgba(0,0,0,.05);
	display: none;
	font-size: 1rem;
	position: absolute;
	width: 195px;
}

	header > nav > ul > li:hover a + div {
		display: block;
	}

It's important to point out the use of position: absolute;, this must be used, and the container must be position: relative. These two positions allow us to give the menu the appearance of "dropping down", whilst not expanding the header.

The box styling also includes some other key CSS 3 styles -

  • background - the linear gradient is set to go vertically, giving the effect the gradient extends from the navigation bar
  • border-radius - this gives us the rounded corners - top-left (0), top-right (0), bottom-right (2px), bottom-left (2px).

Making it Responsive

For this example I've used a very basic responsive design element, making the text slightly larger on bigger screens.

To make the design responsive we need to use a "CSS Media Query". It sounds techincal, but it really isn't!

@media (min-width: 990px) {
  header > nav > ul > li > a {
    max-width: 500px;
    font-size: 1.7rem;
	line-height: 2rem;
  }
  
  header > nav > ul > li > a > div > span {
	  margin: 4px 0 0;  
  }
}

Wrapped inside our media query are the conditions - min-width of 990px. If the page is wider then the following enclosed styles will apply.

Summary

I hope you've enjoyed this tutorial. Feel free to post your own versions in the comments below.

Here's my full code:

HTML:

<header role="banner">
	<nav role="navigation">
		<ul>
			<li>
				<a href="/">
					<div>
						Home
						<span>there's no place like it</span>
					</div>
				</a>
			</li>
			<li>
				<a href="/blog">
					<div>
						Blog
						<span>my thoughts rock</span>
					</div>
				</a>
				<div>
					<ul>
						<li><a href="#">Me</a></li>
						<li><a href="#">Gaming</a></li>
						<li><a href="#">Sport</a></li>
						<li><a href="#">Web Design</a></li>
						<li><a href="#">Web Development</a></li>
					</ul>
				</div>
			</li>
			<li>
				<a href="/contact">
					<div>
						Contact
						<span>drop me a line</span>
					</div>
				</a>
			</li>
			<li>
				<a href="/forum">
					<div>
						Forum
						<span>chat with others</span>
					</div>
				</a>
			</li>
		</ul>
	</nav>
</header>

CSS:

* {margin: 0;padding: 0;outline: none;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
*:after, *:before { -webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section {  display: block;}
html {font-size: 100%;height: auto !important;height: 100%;-webkit-text-size-adjust: 100%;-ms-text-size-adjust: 100%;}
.clear {display: block;	}
.clear::after {clear: both;content: ".";display: block;height: 1px;visibility: hidden;}
	
/*GENERIC STYLES*/
body { background: #f2f2f2;color: #222;-webkit-font-smoothing: antialiased;font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size: 1.05em;font-weight: 400;height: auto !important;height: 100%;line-height: 1.6rem;min-height: 100%;}
/*NAV*/
	header {
		background: linear-gradient(to left,rgba(54,194,182,0.96) 0,rgba(62,188,207,0.96) 100%);
		border-bottom: 1px solid rgba(0,0,0,.1);
		box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
		display: block;
		position: fixed;
		width: 100%;
		z-index: 1000;
	}
	
	header > nav > ul {
		display: flex;
		flex-wrap: wrap;
		justify-content: flex-start;
		list-style: none;
		margin: 0;
		padding: 0;
	}
	
		header > nav > ul > li {
			flex: 0 1 auto;
			margin: 0;
			padding: 0;
			position: relative;
			transition: all linear 0.1s;	
		}
		
			header > nav > ul > li:hover {
				background: rgba(58,162,173,1);
			}
			
			header > nav > ul > li a + div {
				background: linear-gradient(to bottom,rgba(58,162,173,1) 0,rgba(62,188,207,0.96) 100%);
				border-radius: 0 0 2px 2px;
				box-shadow: 0 3px 1px rgba(0,0,0,.05);
				display: none;
				font-size: 1rem;
				position: absolute;
				width: 195px;
			}
			
				header > nav > ul > li:hover a + div {
					display: block;
				}
				
				header > nav > ul > li a + div > ul {
					list-style-type: none;	
				}
				
					header > nav > ul > li a + div > ul > li {
						margin: 0;
						padding: 0;
					}
					
						header > nav > ul > li a + div > ul > li > a {
							color: rgba(255,255,255,.9);
							display: block;	
							font-size: .75rem;
							letter-spacing: 1.5px;
							padding: .25rem 1.5rem;
							text-decoration: none;
							text-transform: uppercase;
						}
						
							header > nav > ul > li a + div > ul > li:hover > a {
								background-color: rgba(0,0,0,.15);	
							}
	
			header > nav > ul > li > a {
				align-items: flex-start;
				color: #fff;
				display: flex;
				font-size: 1.55rem;
				font-weight: 200;
				letter-spacing: 1px;
				max-width: 130px;
				padding: 1rem 1.5rem;
				text-decoration: none;
				text-shadow: 0 1px 1px rgba(0,0,0,.1);
				transition: all linear 0.1s;
			}
			
				header > nav > ul > li > a > div > span {
					color: rgba(255,255,255,.75);
					display: block;
					font-family: Georgia, "Times New Roman", Times, serif;
					font-size: .7rem;	
					font-style: italic;
					line-height: 1rem;
					max-width: 260px;
				}

@media (min-width: 990px) {
  header > nav > ul > li > a {
    max-width: 500px;
    font-size: 1.7rem;
	line-height: 2rem;
  }
  
  header > nav > ul > li > a > div > span {
	  margin: 4px 0 0;  
  }
}

Advertisement
You may also like:
comments powered by Disqus