Let's revisit the mockup of how our client would like the pricing tables to look on desktop-sized screens:
Let's see how close we can get to the desired result, and what we can work out for other viewport sizes.
As shown in the preceding screenshot, there are a few tables in this design. We can begin by adjusting a few fundamental variables for all tables. These are found in _variables.less
. Search for the tables section and adjust the variables for background, accented rows, and borders as desired. I've made these adjustments as shown in the following lines of code:
// Tables // ------------------------- ... @table-bg: transparent; // overall background-color @table-bg-accent: hsla(0,0,1%,.1); // for striping @table-bg-hover: hsla(0,0,1%,.2); @table-bg-active: @table-bg-hover; @table-border-color: #ccc; // table and cell border
Save the file, compile it to CSS, and refresh to see the result as shown in the following screenshot:
That's a start. Now we need to write the more specific styles.
The _page-contents.less
file is now growing long, and the task before us is extensive and highly focused on table styles. To carry the custom styles, let's create a new LESS file for these pricing tables:
_pricing-tables.less
in the main less
folder.__main.less
just after _page-contents.less
as shown in the following line:@import "_pricing-tables.less";
_pricing-tables.less
in your editor and begin writing your new styles.But before we begin writing styles, let's review the markup that we'll be working with.
Thus, for the first table, you'll see the following markup on its parent div
:
<div class="package package-basic col-lg-4">
<table class="table table-striped">
...
Similarly, we'll use package package-premium
and package package-pro
for the second and third table, respectively.
These parent containers obviously also provide basic layout instructions using the col-md-4
class to set up a three-column layout in medium viewports.
Next, we will observe the markup for each table. We see that the basic table
and table-striped
classes have been applied:
<table class="table table-striped">
The table uses the <thead>
element for its top-most block. Within this, there is <th>
spanning two columns, with an <h2>
heading for the package name and <div class="price">
to markup the dollar amount:
<thead> <tr> <th colspan="2"> <h2>Basic Plan</h2> <div class="price">$19</div> </th> </tr> </thead>
Next is the tfoot
tag with the Sign up Now! button:
<tfoot> <tr><td colspan="2"><a href="#" class="btn">Sign up now!</a></td></tr> </tfoot>
Then is the tbody
tag with the list of features laid out in a straightforward manner in rows with two columns:
<tbody> <tr><td>Feature</td><td>Name</td></tr> <tr><td>Feature</td><td>Name</td></tr> <tr><td>Feature</td><td>Name</td></tr> <tr><td>Feature</td><td>Name</td></tr> <tr><td>Feature</td><td>Name</td></tr> </tbody>
And finally, of course, the closing tags for the table
and parent div
tags:
</table> </div><!-- /.package .package-basic -->
Each table repeats this basic structure.
This gives us what we need to start work!
To beautify the thead
element of all of our tables, we'll do the following:
h2
heading to uppercaseWe can apply many of these touches with the following lines of code. We'll specify the #signup
section as the context for these special table styles:
#signup { table { border: 1px solid @table-border-color; thead th { text-align: center; background-color: @gray-light; color: #fff; padding-top: 12px; padding-bottom: 32px; h2 { text-transform: uppercase; } } } }
In short, we've accomplished everything except increasing the size of the price tables. We can get started on this by adding the following lines of code, which are still nested within our #signup table
selector:
.price { font-size: 7em; line-height: 1; }
This yields the following result:
This is close to our desired result, but we need to decrease the size of the dollar sign. To give ourselves control over that character, let's go to the markup and wrap a span
tag around it:
<em class="price"><span>$</span>19</em>
Remember to do the same for the other two tables.
With this new bit of markup in place, we can nest this within our styles for .price
:
.price { ... span { font-size: .5em; vertical-align: super; }
These lines reduce the dollar sign to half its size and align it at the top.
Now to recenter the result, we need to add a bit of negative margin to the parent .price
selector:
.price { margin-left: -0.25em; ...
The following screenshot shows the result:
By continuing to focus on the styles that apply to all three pricing tables, let's make the following adjustments:
We can accomplish this by adding the following rules:
#signup { table { ... tbody { td { padding-left: 16px; padding-right: 16px; } } a.btn { .btn-lg; display: block; width: 100%; background-color: @gray-light; color: #fff; } } }
Save the file, compile it to CSS, and refresh the browser. You should see the following result:
We're now ready to add styles to differentiate our three packages.
Let's begin by giving each package the desired color for the table head and the Sign up now! button. Our provided mockup uses blue for the Basic, green for the Premium, and red for the Pro packages. Let's prepare our color scheme by using the chosen color values in new variables for primary, secondary, and tertiary brand colors, as shown in the following lines of code:
@brand-primary: #428bca; @brand-secondary: #5cb85c; @brand-tertiary: #d9534f;
Having set up these colors, we can efficiently apply them to the appropriate thead
and button
elements. We'll use the distinctive class that we applied earlier to each table's parent element, that is, package-basic
, package-premium
, and package-pro
:
less/_pricing-tables.less
file, begin a new section with a comment:// Pricing Table Colors
.package-basic
table using the @brand-primary
variable; we'll try it first on the thead th
element:#signup .package-basic table { thead th { background-color: @brand-primary; }
thead th
element's button. Here, we'll use the .button-variant()
mixin from the bootstrap/mixins.less
file to efficiently apply styles to :hover
and :active
states. The mixin takes three parameters: color, background color, and border color. We'll define them as follows:... .btn { .button-variant(#fff; @brand-primary; darken(@brand-primary, 5%)); } }
.package-premium
table, this time, however, using the @brand-secondary
variable:#signup .package-premium table { thead th { background-color: @brand-secondary; } .btn { .button-variant(#fff; @brand-secondary; darken(@brand-secondary, 5%)); } }
.package-pro
table using the @brand-tertiary
variable:#signup .package-pro table { thead th { background-color: @brand-tertiary; } .btn { .button-variant(#fff; @brand-tertiary; darken(@brand-tertiary, 5%)); } }
Nice!
Now, let's check how our tables respond to various viewport widths.
Thanks to the attention Bootstrap 3 gives to responsive design, our tables perform quite well across viewport breakpoints. We've already seen the way our tables fair in the medium breakpoint range. In large screens, the tables expand wider, as shown in the following screenshot:
In narrow viewports, the tables stack up vertically, as shown in the following screenshot, quite nicely:
However, there is an awkward range of width approximately between 480px and 992px where the tables expand to fill the full width of the screen. Clearly, they become too wide, as shown in the following screenshot:
Because we have three tables, there is no benefit involved in having a two-column layout at this dimension. Instead, let's constrain the width of our tables and align them at the center with auto
left and right margins. We'll use a media query with max-width
of @screen-sm-max
set to 400px
as our maximum width, and use the .center-block()
mixin to keep our tables at the center in the window:
// // Constrain width for small screens and under // ------------------------------------------ @media (max-width: @screen-sm-max) { #signup .package { max-width: 400px; .center-block(); } }
Save the file, compile it to CSS, and refresh your browser. You should see nicely constrained tables aligned at the center within the window! The following screenshot shows our result:
At this point, our tables are differentiated by color and are responsive. However, one last step remains. In the medium and large viewport widths, we want the premium plan to stand out.
If we look back at the mockup, we see that the design—at least for desktop-sized viewports—calls for visual emphasis upon the central premium plan by increasing its size and bringing it visually into the foreground, as shown in the following screenshot:
This can be accomplished with some adjustments to padding, margins, and font sizes.
We'll do this within a media query for medium viewports and up:
// // Visually enhance the premium plan // ------------------------------------------ @media (min-width: @screen-md-min) { }
Nested within this media query, we can first reduce the widths of our basic and pro tables (the first and third) and add a little margin to the top to push them down a bit:
// Size down the basic and pro #signup .package-basic table, #signup .package-pro table { width: 90%; margin-top: 36px; }
Next, let's enhance the font size of our premium table and add padding to its button:
// Size up the premium #signup .package-premium table { thead th { font-size: 1.5em; h2 { font-size: 1.5em; } } a.btn { font-size: 2em; padding-top: 24px; padding-bottom: 24px; } }
This already brings us very close to our desired result, as shown in the following screenshot:
Our next aim is to bring the tables closer in proximity to one another. This can be done with some margin adjustment and a bit of z-index
work:
// Squeeze tables together #signup .package-basic { margin-right: -58px; margin-left: 58px; z-index: 1; } #signup .package-premium { z-index: 1000; } #signup .package-pro { margin-left: -30px; z-index: 1; }
Here, we have performed the following steps:
margin-right
and compensating this by nudging the equivalent margin to the left to keep everything positioned as it was originally (else all three tables will start sliding to the left)z-index
values for all tables so that the basic and pro tables appear to line up behind our premium tableFor a refresher on how z-index
works, see http://css-tricks.com/almanac/properties/z/z-index/.
The following screenshot is the result in a medium viewport:
Our work is almost done. We only need to adjust the margins for the basic table when we cross the next larger breakpoint. After closing the previous media query, begin a new one and add these margin adjustments:
@media (min-width: @screen-lg-min) { #signup .package-basic { margin-right: -65px; margin-left: 65px; } }
Save the file, compile it to CSS, and refresh the browser. You should see the following result in large viewports of 1200px and above:
That's it! We've accomplished the last major challenge in our client's design.
Now, tidy things up by applying the touches that hold it all together.