A center-aligned logo placed over navigation is a fairly common site feature that is rarely done well: attempts are usually either semantically confusing (producing content like home about logo contact), inaccessible, or both. As it is usually transparent, it’s also common for the logo to come in at a large file size (due to lossless compression in alpha-masked PNG’s) and/or for the logo to obscure navigational links, placing them out of reach of users.

Some of my have indicated that they’d like to attempt such a design for their first site this semester, so I thought I’d take the opportunity to show the best way I know to create one, addressing and nullifying every one of the common problems I’ve described.

Keeping Things Semantic

The basic issue is to keep elements in logical reading order:


In this case, the logo is a JPEG with an SVG mask for transparency, a derivation of a technique put forward by Peter Hrynkow last year. This takes advantage of the low file sizes afforded by JPEG, while retaining the alpha-mask transparency option that is usually assumed to be exclusive to PNG. With a few changes, my version is also responsive; I’ll go into more detail about how the total effect was achieved in the next article.

	<svg preserveAspectRatio="xMinYMin" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
		<desc>A chrome logo for the "Cars" movie</desc>
			<mask id="carsLogoMask">
				<image width="100%" height="100%" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/cars-logo-mask.png"></image>
		<image mask="url(#carsLogoMask)" width="100%" height="100%"  xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/cars-logo.jpg"></image>

Note the <title> and <desc> tags, which make the SVG accessible; I’ll also talk about those elements more in a future article.

Initial CSS

The logo is provided with a CSS drop-shadow filter, and made responsive using a technique I have written about in depth before:

* {
	box-sizing: border-box;
body {
	font-family: Avenir, Helvetica, sans-serif; 
	margin: 0;
header {
	width: 50%;
	position: relative;
	padding-top: 30%; 
	margin: 0 auto;
	-webkit-filter: drop-shadow(0px 12px 5px rgba(0,0,0,0.3));
	filter: drop-shadow(0px 12px 5px rgba(0,0,0,0.3));
header svg { 
	position: absolute;
	top: 0;
	width: 100%;
	height: 100%;

Adding & Fixing Navigation

The navigation is fairly straightforward. On viewports that are wide enough, I want to divide the navigation either side of the logo, so I’ll wrap each pair of links in a <span> tag to control them:

		<a href="#">Home</a>
		<a href="#">About</a>
		<a href="#">Contact</a>
		<a href="#">Retro</a>

The navigation is pushed upwards using a negative margin-top. sets the pairs of <span> elements as far apart as possible:

nav { 
	margin-top: -10%; 
	display: flex; 
	justify-content: space-between; 
	background-image: url(red-paint-texture.jpg); 
	background-size: cover; 

Each link inside the <span> elements is given similar treatment, to distribute them maximally in their containers:

nav span { 
	width: 40%;
	display: flex;
	justify-content: space-around;
nav a { 
	color: white; 
	text-decoration: none; 
	text-transform: uppercase; 
	display: inline-block; 
	padding: .5rem 1.5rem; 
	font-size: 1.2rem; 
	text-shadow: 0px 3px 4px rgba(0,0,0,0.5); 
	transition: .4s; 
nav a:hover { 
	background: rgba(0,0,0,0.2);

Fixing Click-Capturing

The one problem is that the logo will block any clicks on the links. This is due to the fact that, despite its appearance, the area of the logo is rectangular: its shape will “capture” any clicks in the total area it occupies, blocking the navigation. We can fix this by applying pointer-events to the element:

header {
pointer-events: none;

This causes interaction to “pass through” the header and its content, allowing clicks to be captured by the navigation bar underneath.

Acting Responsively

Finally, some adjustments to the navigation to account for smaller screen sizes:

@media all and (max-width: 500px) {
	nav a {
		font-size: 1rem;
@media all and (max-width: 450px) {
	nav a {
		font-size: .8rem;
@media all and (max-width: 400px) {
	nav {
		padding: 8% 0 0;
	nav, nav span, nav span a {  
		display: block;
		font-size: 1rem;
		text-align: center;
		width: 100%;

The result is semantic, accessible, and responsive.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/vEWVdd