Advertisement

Build a Responsive Pricing Table with Neat Hover States

by

During this tutorial we'll be creating a sleek pricing table with some striking hover effects. We'll use Lea Verou's Prefixfree script to keep our CSS clean, plus we'll make the whole thing responsive, shifting the layout at a couple of breakpoints.


The Markup

The image below displays a visual skeleton of the markup we will be creating. As you can see, it's not built using tables; we're using unordered lists for maximum flexibility and responsiveness.

css3-pricing-table-markup

HTML Markup

Before anything else, we need to begin with an empty document. Very important here is the viewport meta tag which will allows all devices to properly interpret our responsive layout.

<!DOCTYPE html>
<html lang="en" >
<head>
	<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

</body>
</html>

Now we can begin with the meat of our table markup (or rather list markup):

<ul class="pricing_table">
	<li>...</li>
	
	<li class="price_block">
		<h3>Basic</h3>
		<div class="price">
			<div class="price_figure">
				<span class="price_number">$9.99</span>
				<span class="price_tenure">per month</span>
			</div>
		</div>
		<ul class="features">
			<li>2GB Storage</li>
			<li>5 Clients</li>
			<li>10 Active Projects</li>
			<li>10 Colors</li>
			<li>Free Goodies</li>
			<li>24/7 Email support</li>
		</ul>
		<div class="footer">
			<a href="#" class="action_button">Buy Now</a>
		</div>
	</li>
	
	<li>...</li>
	<li>...</li>
</ul>

<script src="prefixfree.min.js" type="text/javascript"></script>

At the very bottom we've included prefixfree (before the closing </body> tag), which allows us to use unprefixed CSS properties everywhere. It works behind the scenes, adding the current browser's prefix to any CSS code, only when it's needed.


Styles

Having sorted out our markup, let's look at adding some styles. I'll be doing so within <style> tags in the document head, but you can use a separate stylesheet if you'd rather.

1. Basic Styles

@import url(http://fonts.googleapis.com/css?family=Ubuntu);

* {
	margin: 0; 
	padding: 0;
}
		
body {
	font-family: Ubuntu, arial, verdana;
}

To start with, we apply a basic CSS reset and use a custom font 'Ubuntu' which is being pulled in from Google Fonts.

2. Pricing Table and Price Blocks

.pricing_table {
	line-height: 150%; 
	font-size: 12px; 
	margin: 0 auto; 
	width: 75%; 
	max-width: 800px; 
	padding-top: 10px;
	margin-top: 100px;
}

.price_block {
	width: 100%; 
	color: #fff; 
	float: left; 
	list-style-type: none; 
	transition: all 0.25s; 
	position: relative; 
	box-sizing: border-box;
	
	margin-bottom: 10px; 
	border-bottom: 1px solid transparent; 
}

The .pricing_table is kept 75% wide, but limited to 800px so that it does not take a huge amount of space on wide screens.

We are approaching things mobile first, hence .price_block is 100% wide by default to cover the entire width available. Later we will use media queries to fit in more blocks horizontally on wider screens.

css3-pricing-table-1x4

The 10px bottom margin given to .pricing_block comes into play when users view the pricing table on smaller screens, particularly when some of the pricing blocks fall down and stack below one another. It goes towards compensating a negative 10px top margin applied to the .price_title of the pricing blocks stacked below. You will read more about the 10px negative margin in the next section.

The 1px transparent border for .pricing_block creates a gutter helping in separation of the different blocks of content.

.price_block is also set to have position: relative; so that when box shadows are applied for hover effects, z-index can be used on the hovered block to make its shadow appear above the nearby elements.

3. Price Heads

css3-pricing-table-header
.pricing_table h3 {
	text-transform: uppercase; 
	padding: 5px 0; 
	background: #333; 
	margin: -10px 0 1px 0;
}

The price heads have a -10px top margin. This causes the contents of the .price_block to move upwards so that they're displayed above the shadow, giving a top-light feel.

4. Price Tags

Now for the sections which actually display the pricing details.

css3-pricing-table-price-tags
.price {
	display: table; 
	background: #444; 
	width: 100%; 
	height: 70px; 
}
.price_figure {
	font-size: 24px; 
	text-transform: uppercase; 
	vertical-align: middle; 
	display: table-cell;
}
.price_number {
	font-weight: bold; 
	display: block;
}
.price_tenure {
	font-size: 11px; 
}

One point worth noting here is that the price tags are aligned vertically center. This is required for prices which may not have a tenure (eg. FREE).

.price is set to have display: table; and its immediate child .price_figure is set to have display: table-cell; and vertical-align: middle; to achieve the effect.

.price_figure acts as a container for .price_number and .price_tenure so that they can be vertically center-aligned as a single unit.

5. Features

.features {
	background: #DEF0F4; 
	color: #000;
}
.features li {
	padding: 8px 15px;
	border-bottom: 1px solid #ccc; 
	font-size: 11px; 
	list-style-type: none;
}

6. Footer and Action Button

.footer {
	padding: 15px; 
	background: #DEF0F4;
}
.action_button {
	text-decoration: none; 
	color: #fff; 
	font-weight: bold; 
	border-radius: 5px; 
	background: linear-gradient(#666, #333); 
	padding: 5px 20px; 
	font-size: 11px; 
	text-transform: uppercase;
}

7. Hover Effect

.price_block:hover {
	box-shadow: 0 0 0px 5px rgba(0, 0, 0, 0.5); 
	transform: scale(1.04) translateY(-5px); 
	z-index: 1; 
	border-bottom: 0 none;
}
.price_block:hover .price {
	background:linear-gradient(#DB7224, #F9B84A); 
	box-shadow: inset 0 0 45px 1px #DB7224;
}
.price_block:hover h3 {
	background: #222;
}
.price_block:hover .action_button {
	background: linear-gradient(#F9B84A, #DB7224); 
}

There will be three aspects to the hover effect:

  • Color change - The background color is changed from dark grey to an orange-yellow gradient for .price and .action_button. Additionally, .price also gets an inset orange shadow to enhance the color effect.
  • Shadow - a basic 5px translucent shadow.
  • Upward shift and scaling using CSS3 transforms - The .price_block hovered is scaled to 104% and moved upwards by 5px.

.price_table already has CSS3 transitions applied which makes the hover change a smooth animation.

You can also use these hover effects as an active state if you wish to highlight one of the prices by default. All you need to do is add an active class to one of the price blocks and move/copy the hover styles to it.


Adding Media Queries

We'll follow a simple approach to make the pricing table responsive. The sections are already fluid as they use % based widths, so all we need to do is control the number of horizontal blocks visible on different screen sizes.

  • < 480px - show 1 block (this is our default)
  • 480px - 768px - show 2 blocks
  • 768px+ - show all 4 blocks

These breakpoints are defined purely on what works visually with this design. Let's add our media queries underneath our other styles.

@media only screen and (min-width : 480px) and (max-width : 768px) {
	.price_block {width: 50%;}
	.price_block:nth-child(odd) {border-right: 1px solid transparent;}
	.price_block:nth-child(3) {clear: both;}
	
	.price_block:nth-child(odd):hover {border: 0 none;}
}
@media only screen and (min-width : 768px){
	.price_block {width: 25%;}
	.price_block {border-right: 1px solid transparent; border-bottom: 0 none;}
	.price_block:last-child {border-right: 0 none;}
	
	.price_block:hover {border: 0 none;}
}

For the viewport range of 480px - 768px we make each pricing block 50% wide. This will effectively stack them in rows of two. The .price_block:nth-child(3) {clear: both;} ensures that the third block clears the upper two blocks, even when hover states change the size of everything. We're also setting a 1px right border on .price_block(odd ones) to create a vertical gutter between the price blocks on the left and right hand sides.

css3-pricing-table-2x2

For 768px and above we set the width of each block to 25% giving us rows of four. We're also setting borders on the right side of all the price blocks, except the last one, to create the same vertical gutter as above.


Conclusion

With a fluid layout, some simple styling and a couple of breakpoints, we've built a neat CSS3 pricing table. I hope you find use for it!