Advertisement

CSS3 vs. Photoshop: Rounded Corners and Box Shadows

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →
This post is part of a series called CSS3 vs. Photoshop.
CSS3 vs. Photoshop: Complex Backgrounds
CSS3 vs Photoshop: Opacity and Transparency

This tutorial will demonstrate how to create a nice, simple navigation bar using several combined CSS3 styles. We're aiming for a look and feel that in the past could only be created by combining several images, JavaScript and several divs. Let's get it started…

Note: all the following examples were tested on Mozilla Firefox, Safari and Chrome. If you want to get something similar in IE or any other browser leave a comment and I will be glad to help you.


Before We Get Started

A good looking and well designed navigation bar has been, from the very beginning of the web design, one of the more powerful elements to keep websites organized and well structured. In the past creating a nice design using shadows, gradients, rounded corners and hover effects required a series of tricks that increased the size of our code and the number of images.

For this tutorial we will dig into two very important CSS3 effects; Rounded Corners and Box Shadows, plus we will use the linear gradients previously shown in the CSS3 vs Photoshop - Complex Backgrounds Tutorial.


Step 1: Rounded Corners

Everyone has heard of them, it will be redundant to talk about how to create them, so in the following examples I will focus on the differences of creating a Rounded Corner effect using images and the advantages and disadvantages of using CSS3 instead.

Creating a rounded corner effect is pretty simple in any graphic software, but in Photoshop we have some problems:

Accuracy: Even if you can set the rounded corner radius, Photoshop's built in anti-aliasing engine often adds one or two extra pixels in the graphic. Most of us in the past had to manually reduce pixels of inexact image based rounded corners to create a clean join with, for instance, color backgrounds.

Editing: This is one of the biggest problems of creating a image-based rounded corner. If you create a graphic for a 10px radius corner in Photoshop, and for some reason you need to increase the radius to 20px there is no other way to do it than redrawing the shape, or manually editing all its corners, loosing time and accuracy. Resizing is another huge problem, if you want to stretch or enlarge the shape you must use the Point Selection Tool in Photoshop, because using the Transform Controls may cause undesired distortions in the corner shape. I needn't even mention that slicing the corners takes a bunch of valuable minutes.

Fills and Borders: Creating a gradient fill inside an image based rounded corner box has always been a big task, wuthout even covering borders, surgical precision is required to slice the images involved. You need to create at least 3 images for each box, one for the top corners, another for the bottom corners and the horizontal or vertical gradient and then write the code for it. Another problem with image fill is that often the container has to increase its height or width, obtaining an undesirable effect with the gradient (see screenshot below).

Mix Corner Styles: In Photoshop, creating mixed corner styles takes a while, there are no options to combine corner styles. You must manually reduce/increase radius or combine shapes... and then slice each corner.


Now in CSS3

Using CSS3 to replace the classic image-based rounded corners is a great idea. Here are a couple of pros:

  • It reduces the number of images and HTTP requests to the server
  • It works on all the modern browsers (except IE 6,7,8) including most of the popular mobile browsers.
  • You just need a couple of lines in the CSS file to make them work
  • Increasing/decreasing radius, resizing, changing fill and borders take only a few seconds, but in Photoshop take several minutes

Let's see the code to create rounded corners on an HTML element:

/*Rounded Corner Boxes*/
.box{
	background-image:-moz-linear-gradient(top, #FAD502, #E89502);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#FAD502), to(#E89502), color-stop(1,#E89502));
}

.fourcorners{
	-moz-border-radius: 20px;
	-webkit-border-radius: 20px;
	-khtml-border-radius: 20px;	
	border-radius: 20px;
}

.topleft{
	-moz-border-radius-topleft: 20px;
	-webkit-border-top-left-radius: 20px;
	-khtml-border-radius-topleft: 20px;	
	border-top-left-radius: 20px;
}

.bottomleft{
	-moz-border-radius-bottomleft: 20px;
	-webkit-border-bottom-left-radius: 20px;
	-khtml-border-radius-bottomleft: 20px;	
	border-bottom-left-radius: 20px;
}

.topright{
	-moz-border-radius-topright: 20px;
	-webkit-border-top-right-radius: 20px;
	-khtml-border-radius-topright: 20px;	
	border-top-right-radius: 20px;
}

.bottomright{
	-moz-border-radius-bottomright: 20px;
	-webkit-border-bottom-right-radius: 20px;
	-khtml-border-radius-bottomright: 20px;	
	border-bottom-right-radius: 20px;
}

.asymmetrical1{	
	-webkit-border-top-left-radius: 160px;
	-khtml-border-radius-topleft: 160px;	
	-moz-border-radius-topleft: 160px;
	border-top-left-radius: 160px;
	
	-webkit-border-top-right-radius: 20px;
	-khtml-border-radius-topright: 20px;
	-moz-border-radius-topright: 20px;
	border-top-right-radius: 20px;

	-webkit-border-bottom-left-radius: 10px;
	-khtml-border-radius-bottomleft: 10px;
	-moz-border-radius-bottomleft: 10px;
	border-bottom-left-radius: 10px;
	
	-webkit-border-bottom-right-radius: 0px;
	-khtml-border-radius-bottomright: 0px;
	-moz-border-radius-bottomright: 0px;
	border-bottom-right-radius: 0px;
}

.asymmetrical2{
	-webkit-border-top-left-radius: 0px;
	-khtml-border-radius-topleft: 0px;	
	-moz-border-radius-topleft: 0px;
	border-top-left-radius: 0px;
	
	-webkit-border-top-right-radius: 90px;
	-khtml-border-radius-topright: 90px;
	-moz-border-radius-topright: 90px;
	border-top-right-radius: 90px;

	-webkit-border-bottom-left-radius: 0px;
	-khtml-border-radius-bottomleft: 0px;
	-moz-border-radius-bottomleft: 0px; border-bottom-left-radius: 0px;
	
	-webkit-border-bottom-right-radius: 90px;
	-khtml-border-radius-bottomright: 90px;
	-moz-border-radius-bottomright: 90px;
	border-bottom-right-radius: 90px;
}

.circle{
	width:170px;
	height:170px;
	
	padding:15px; 
	font-family:Arial, Helvetica, sans-serif; 
	color:#FFF; 
	font-size:12px; 
	font-weight:bold;
	float:left;
	
	background-image:-moz-linear-gradient(top, #FAD502, #E89502);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#FAD502), to(#E89502), color-stop(1,#E89502));
	
		
	-webkit-border-top-left-radius: 100px;
	-khtml-border-radius-topleft: 100px;	
	-moz-border-radius-topleft: 100px;
	border-top-left-radius: 100px;
	
	-webkit-border-top-right-radius: 100px;
	-khtml-border-radius-topright: 100px;
	-moz-border-radius-topright: 100px;
	border-top-right-radius: 100px;

	-webkit-border-bottom-left-radius: 100px;
	-khtml-border-radius-bottomleft: 100px;
	-moz-border-radius-bottomleft: 100px;
	border-bottom-left-radius: 100px;
	
	-webkit-border-bottom-right-radius: 100px;
	-khtml-border-radius-bottomright: 100px;
	-moz-border-radius-bottomright: 100px;
	border-bottom-right-radius: 100px;	
}

View Demo


Step 2: Box Shadows

Some of the coolest effects that you can achieve with Photoshop are through Drop Shadows and Inner Shadows. Using them in the proper way can result in outstanding 3D effects. Of course, using a drop shadow or an inner shadow in the wrong way can quickly become a cheesy effect.

Below you'll find a couple of examples of good practices:


Now in CSS3

CSS3 allows us to create shadows with only a couple of lines of code, the style in charge is "box-shadow".

To create a Photoshop-like Drop Shadow you can use the following syntax:

box-shadow: <xpos> <ypos> <size> <color>;

To create a Photoshop-like Inner Shadow you can use the following syntax:

box-shadow: inset <style> <xpos> <ypos> <size> <color>;

Now here's the code to create several variants of Box Shadows:

/*Box shadows*/
.dropshadow{
	background-image:-moz-linear-gradient(top, #F3F4F5, #C8C9CA);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#F3F4F5), to(#C8C9CA), color-stop(1,#C8C9CA));
	
	border:2px solid #F2F2F2;
	
	box-shadow: 10px 10px 10px rgba(0,0,0,0.25);
	-moz-box-shadow: 10px 10px 10px rgba(0,0,0,0.25);
	-webkit-box-shadow: 10px 10px 10px rgba(0,0,0,0.25);
}

.innershadow{
	background-image:-moz-linear-gradient(top, #E2E2E2, #CCCCCC);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#E2E2E2), to(#CCCCCC), color-stop(1,#CCCCCC));
	
	border:2px solid #FEFEFE;
	
	box-shadow: inset 5px 5px 5px rgba(0,0,0,0.25);
	-moz-box-shadow: inset 5px 5px 5px rgba(0,0,0,0.25);
	-webkit-box-shadow: inset 5px 5px 5px rgba(0,0,0,0.25);
}

.intenseshadow{
	background-color:#FFF;
	border:1px solid #F00;
	
	box-shadow: 10px 10px 0px #F00;
	-moz-box-shadow: 10px 10px 0px #F00;
	-webkit-box-shadow: 10px 10px 0px #F00;
}

.bevel{
	background-color:#CCC;
	
	box-shadow: 10px 10px 0px #F00;
	-moz-box-shadow:inset 0px 0px 120px rgba(0,0,0,.60);
	-webkit-box-shadow: 10px 10px 0px #F00;
}

View Demo


Step 3: Navigation Menu

We're going to combine rounded corners, gradient fills and box shadows to create a navigation menu. You can always start with Photoshop to create the graphic; grab the source download from the top of the page if you wish to jump right in.

The fun part of this is trying to get the same result with CSS3 - here we go!

First the HTML mockup (yes I'm using the "nav" tag of HTML5, because it's pretty cool and semantically appropriate - but you can use a div instead)

<nav class="horizontal">
  <ul>
    <li><a href="#">Lorem Ipsum</a></li>
    <li><a href="#">Dolor Sit Amet</a></li>
    <li><a href="#">Sed do Eiusmod</a></li>
    <li><a href="#">Consectetur Adipisicing</a></li>
    <li><a href="#">Lipsum amet</a></li>
    <li><a href="#">Lorem Ipsum</a></li>
  </ul>
</nav>

Step 4: CSS

Now, let's jump to the CSS. First set the positions and height.

/*Sample Navigation Bar*/
nav.horizontal{
}

nav.horizontal h3{
	padding-bottom:20px;
}

nav.horizontal ul{
	height:50px;
}

nav.horizontal ul li{
	list-style:none;
	display:inline;
	float:left;
}

nav.horizontal ul li a{
	display:block;
	height:28px;
	margin:2px 6px 2px 6px;
	padding:15px 20px 0px 20px;
}

nav.horizontal ul li a:hover{
}

Then add the Gradient Fills:

  nav.horizontal{
  }
  
  nav.horizontal h3{
  padding-bottom:20px;
  }
  
  nav.horizontal ul{
  height:50px;
  
  background-image:-moz-linear-gradient(top, #93C204, #608009);
  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#93C204), to(#608009), color-stop(1,#608009));
  
  border:1px solid #608009;
  }
  
  nav.horizontal ul li{
  list-style:none;
  display:inline;
  float:left;
  }
  
  nav.horizontal ul li a{
  display:block;
  height:28px;
  margin:2px 6px 2px 6px;
  padding:15px 20px 0px 20px;
  
  font-size:12px;
  font-weight:bold;
  color:#FFF;
  text-transform:uppercase;
  text-decoration:none;
  
  border:1px solid transparent;
  background-image:none;
  }
  
  nav.horizontal ul li a:hover{
  background-image:-moz-linear-gradient(top, #161616, #2B3615);
  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#161616), to(#2B3615), color-stop(1,#2B3615));
  
  border:1px solid #A3D804;
  }

Next, the Rounded Corners:

  nav.horizontal{
  }
  
  nav.horizontal h3{
  padding-bottom:20px;
  }
  
  nav.horizontal ul{
  height:50px;
  
  background-image:-moz-linear-gradient(top, #93C204, #608009);
  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#93C204), to(#608009), color-stop(1,#608009));
  
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  -khtml-border-radius: 8px;	
  border-radius: 8px;
  
  border:1px solid #608009;
  }
  
  nav.horizontal ul li{
  list-style:none;
  display:inline;
  float:left;
  }
  
  nav.horizontal ul li a{
  display:block;
  height:28px;
  margin:2px 6px 2px 6px;
  padding:15px 20px 0px 20px;
  
  font-size:12px;
  font-weight:bold;
  color:#FFF;
  text-transform:uppercase;
  text-decoration:none;
  
  border:1px solid transparent;
  background-image:none;
  
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  -khtml-border-radius: 10px;	
  border-radius: 10px;
  }
  
  nav.horizontal ul li a:hover{
  background-image:-moz-linear-gradient(top, #161616, #2B3615);
  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#161616), to(#2B3615), color-stop(1,#2B3615));
  
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  -khtml-border-radius: 10px;	
  border-radius: 10px;
  
  border:1px solid #A3D804;
  }

And finally the Box Shadows:

nav.horizontal{
}

nav.horizontal h3{
	padding-bottom:20px;
}

nav.horizontal ul{
	height:50px;
	
	background-image:-moz-linear-gradient(top, #93C204, #608009);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#93C204), to(#608009), color-stop(1,#608009));
	
	-moz-border-radius: 8px;
	-webkit-border-radius: 8px;
	-khtml-border-radius: 8px;	
	border-radius: 8px;
	
	border:1px solid #608009;
	
	box-shadow: 5px 5px 5px rgba(0,0,0,0.25);
	-moz-box-shadow: 5px 5px 5px rgba(0,0,0,0.25);
	-webkit-box-shadow: 5px 5px 5px rgba(0,0,0,0.25);
}

nav.horizontal ul li{
	list-style:none;
	display:inline;
	float:left;
}

nav.horizontal ul li a{
	display:block;
	height:28px;
	margin:2px 6px 2px 6px;
	padding:15px 20px 0px 20px;
	
	font-size:12px;
	font-weight:bold;
	color:#FFF;
	text-transform:uppercase;
	text-decoration:none;
	
	border:1px solid transparent;
	background-image:none;
	
	-moz-border-radius: 10px;
	-webkit-border-radius: 10px;
	-khtml-border-radius: 10px;	
	border-radius: 10px;
}

nav.horizontal ul li a:hover{
	background-image:-moz-linear-gradient(top, #161616, #2B3615);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#161616), to(#2B3615), color-stop(1,#2B3615));
	
	-moz-border-radius: 10px;
	-webkit-border-radius: 10px;
	-khtml-border-radius: 10px;	
	border-radius: 10px;
	
	border:1px solid #A3D804;
	
	box-shadow: inset 4px 4px 4px rgba(0,0,0,0.25);
	-moz-box-shadow: inset 4px 4px 4px rgba(0,0,0,0.25);
	-webkit-box-shadow: inset 4px 4px 4px rgba(0,0,0,0.25);
}

View Demo


Step 5: Fixing the Bleed

One final note with regard to rounded corners with a fill and a border: they bleed. You'll notice it on the hover state of our navigation buttons:


Fill color bleeding out beyond the borders.

We can address this by using the background-clip property, which determines whether the background of a given element extends into the border. By default (border-box) it does, which gives us this messy bleeding, but we can alter it to padding-box which stops it short of the borders.

Let's add the following css to our button:

nav.horizontal ul li a{
	display:block;
	height:28px;
	margin:2px 6px 2px 6px;
	padding:15px 20px 0px 20px;
	
	font-size:12px;
	font-weight:bold;
	color:#FFF;
	text-transform:uppercase;
	text-decoration:none;
	
	border:1px solid transparent;
	background-image:none;
	
	-moz-border-radius: 10px;
	-webkit-border-radius: 10px;
	-khtml-border-radius: 10px;	
	border-radius: 10px;
	
	-moz-background-clip: padding; 
	-webkit-background-clip: padding-box; 
	background-clip: padding-box; 
}

..which gives us a far more desirable result when hovered over:


Fill color nicely contained within the boundaries of our element.

View Demo

You can read more about the background-clip property on CSS3 info.


Conclusion

Creating a nice and good-looking simple navigation bar with CSS3 is easier and quicker than ever, so why don't you try with your next design? Thanks for reading!

Advertisement