Let's imagine we've emerged from client meetings with a plan to organize the home page content in three tiers, ranked by importance.
In medium and wide viewports, this content will be laid out in three columns as seen in the following screenshot:
In a narrow viewport, these will be laid out one after another, in a single vertical column:
And in a small, tablet-width
viewport, we'll arrange the content in two side-by-side columns, with the third tier of content laid out beneath it as a horizontal row as seen in the following screenshot:
To get us started, I've provided the basic markup for three equal columns. Let's review what we have and then adapt it to the needs of this design. We'll begin with the three-column layout for medium and wide viewports.
Currently, in medium and wide viewports, our three columns are equal in width, font size, and button size and color. As a result, the presentation lacks visual hierarchy, as seen in the following screenshot:
We can take significant strides by adjusting column width, font size, and button size and color to establish a clearer hierarchy between these tiers of content. Let's do that. We'll start by adjusting column widths:
index.html
, search for the section
tag for the primary content:<section class="content-primary col-sm-4">
Note that the class col-sm-4
sets the width of this column to one-third of the width of the parent element, beginning at the small viewport width (764px and up).
We want to save the three-column layout for the medium and large viewports (992px and up), and we want this first column to be wider than the others.
col-sm-4
to read col-md-5
, as follows:<section class="content-primary col-md-5">
This will set this column to 5/12 width beginning at the medium viewport and up.
section
tags for the next two columns and adjust the column classes to col-md-4
and col-md-3
respectively:<section class="content-secondary col-md-4"> ... <section class="content-tertiary col-md-3">
Save, refresh, and you'll see the desired visual hierarchy in the width of our columns:
You might have noticed that the headings in the middle of the secondary and tertiary columns are not clearing the buttons above them. Let's adjust these, as well as our buttons and font sizes.
Let's begin by adjusting our headings so that they consistently clear the buttons above them, which have been floated to the right. For this purpose, we'll use the file we previously created to manage the details of the page contents: _page-contents.less
.
Here's how to do it:
_page-contents.less
, let's write a selector to select headings h1
through h4
when they're nested inside a Bootstrap column class. We'll use the CSS2 attribute selector and cover our bases by targeting any element whose classes include the string col-
.Within this context, we'll select all heading tags we might potentially use and set them to clear floated elements, with some added padding for separation.
main { ... [class*="col-"] { h1, h2, h3, h4 { clear: both; padding-top: 20px; } } }
This gives the necessary separation between our headings and floated buttons. But it also creates unneeded padding at the top of the secondary and tertiary columns.
In the following image, the lower arrows highlight the improvement accomplished now that our headings clear the floated buttons. The top arrows highlight the ragged top edge of our columns, where padding causes a problem.
:first-child
selector for this, nesting these lines within our heading selectors. We'll use the &
combinator, which in this formulation, allows us to select any first-child instance of these headings:h1, h2, h3, h4 { ... &:first-child { margin-top: 0; padding-top: 0; } }
Thus, we need to nest what we've just done within a media query for small viewports and up:
@media (min-width: @screen-sm-min) {
&:first-child {
margin-top: 0;
padding-top: 0;
}
}
With the preceding media query, we've retained the padding we need between elements in the single-column layout for narrow viewports, as seen in the following screenshot:
With this accomplished, we can move on to adjust buttons and font sizes to reflect the informational hierarchy of our content. Let's begin by enlarging the font size and button size and color in our primary content area.
First, let's increase the font size of our primary column content:
_variables.less
, search for the @font-size-large
variable and update its value to the following:ceil(@font-size-base * 1.15);
_page-contents.less
, add these lines to use this font size for the content of our primary content:.content-primary { font-size: @font-size-large; }
Save these changes, compile the file, and refresh your browser. You should see the font size increase accordingly!
Now, let's adjust the color of our button to utilize the red @brand-feature
color. We'll utilize the @brand-feature
variable we set up in _variables.less
.
@brand-feature: #c60004;
We'll also utilize an excellent mixin provided in the Bootstrap mixins.less
file. You may want to take a moment to check it out. Open bootstrap/mixins.less
and search for // Button
variants. You'll find a mixin that begins as follows:
.button-variant(@color; @background; @border) {
The mixin does the following:
If you'd like to, you can see how Bootstrap uses this mixin in bootstrap/buttons.less
under the comment // Alternate buttons
. Here are the lines generating styles for the default and primary buttons:
// Alternate buttons // -------------------------------------------------- .btn-default { .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); } .btn-primary { .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); }
Following this pattern, we can generate our custom feature button in four simple steps:
_variables.less
, under // Buttons
, make a copy of the three @btn-primary-
variables, and customize them, replacing -primary-
with -feature-
and using @brand-feature
as the background color:@btn-feature-color: #fff; @btn-feature-bg: @brand-feature; @btn-feature-border: darken(@btn-feature-bg, 5%);
_buttons-custom.less
and write a mixin based on the .btn-primary
mixin from bootstrap/buttons.less
as follows:.btn-feature { .button-variant(@btn-feature-color; @btn-feature-bg; @btn-feature-border); }
__main.less
as follows:@import "bootstrap/buttons.less";
@import "_buttons-custom.less"; // added
index.html
, change the button class from btn-primary
to btn-feature
. While we're at it, we want to make the button large, so add the class btn-lg
:<a class="btn btn-feature btn-lg pull-right" href="#">Learn more
Save. Refresh the browser, and you should see the following result. The primary column to the left now has a larger font size and a large button with our brand-feature
color.
Meanwhile, the font size and button colors of the secondary (center) column are exactly what we want. What needs to happen next is this: we need to de-emphasize the tertiary column content so that it takes its appropriate place in the informational hierarchy.
Our task for the tertiary content is fairly straightforward. We have to reduce the font size and de-emphasize the buttons. This can be accomplished as follows:
_variables.less
, adjust the @font-size-small
variable:@font-size-small: ceil(@font-size-base * 0.90);
_page-contents.less
:.content-tertiary { font-size: @font-size-small; }
index.html
, we need to edit our button classes. We'll change them from btn-primary
to btn-default
, and we'll reduce their size using the class btn-xs
:<a class="btn btn-default btn-xs pull-right" href="#">Read more ...
This will reduce the button size and turn the button background white.
_variables.less
, adjust the values for the three @btn-default-
variables as follows:@btn-default-color: @gray; @btn-default-bg: @gray-lightest; @btn-default-border: darken(@btn-default-bg, 5%);
Save the changes, compile the file, and refresh your browser.
We now have a clear visual hierarchy, from the primary content (on the left), to the secondary (center) and tertiary (right).
Now, take a moment to notice that our adjustments work reasonably well in the narrow single-column layout as well:
In narrow viewports, our three columns stretch out vertically, one after the other, with primary content first, followed by secondary and tertiary.
All that remains is some fine-tuning to make our content even more user friendly across devices and viewports.
It's always good to give our content—and our viewers' eyes—some room to breathe. Visual indicators of section boundaries are good as well. Let's fold these in:
main
element itself. This padding will serve us well in all viewports, so we won't need a media query.main { padding-top: 20px; padding-bottom: 40px; }
// Make columns clear floats in narrow viewport single-column layout @media (max-width: @screen-sm-min) { [class*="col-"] { clear: both; } }
That's it. Our main content layout is ready. Now for the complex footer area.