Integrating Gridpak>
Flexibility of Twitter's Bootstrap grid system is improved in Version 3, but we will use a grid created with another grid-generation script; Gridpak (available at http://gridpak.com/) from Erskine Design is an amazing tool that allows us to create any grid for any media query stop with an intuitive interface. Its main features are as follows:
- Interactive creation of percent-based grids with variable column count
- Creating media query stops of any screen width
When you create a grid, you can download the following files:
.png
design templates for all the necessary steps.js
script that draws the grid (the grid visibility can be turned on or off with the g key).css
file with media queries and grid columns (with column spans defined asspan_x
classes).less
and.scss
files
With Gridpak (available at www.gridpak.com), you can create grids with variable column count based on any screen size steps you define.
Sample I created with Grider has the following parameters:
- >320: Two columns
- 320< and <799: Four columns
- 800<: 12 columns
The grid CSS from Gridpak is very lightweight and clear. It only has 3 KB and it is a nonminified version (a minified CSS or JS file is a version with comments, unnecessary spaces, and line breaks removed to reduce bandwidth). To create a sample RWD page, I will use both Bootstrap and Gridpak.
Twitter's Bootstrap, besides grids and reset styles, features a rich JavaScript component library. For this project, I need a responsive toolbar.
The Bootstrap version without the grid system we created in the beginning of this chapter is the version we need now. The compile script is improved in this version and thanks to this, we had easily compiled a 27 KB version of boostrap.css
.
As a base for the HTML template, we can use the Gridpak sample file. The following code helps us link the updated CSS files in the header. site.css
is an empty stylesheet for website-specific CSS.
<link rel="stylesheet" media="all" type="text/css" href="assets/css/gridpak.css" /> <link rel="stylesheet" href="assets/css/bootstrap.css"> <link rel="stylesheet" href="assets/css/site.css">
I added a local copy of jQuery to speed up testing using the following code:
<script src="assets/js/jquery-1.10.2.min.js"></script>
Just before the end of the <body>
element, we can inject the gridpack.js
and bootstrap js
files. Gridpack.js
is used to generate a grid overlay on the page and is just a testing helper.
With the help of .png
grid templates, I created a simple layout as shown in the following screenshot:
Implementing responsive design
To start the implementation process, I exported image files in their largest size (maximum assumed page width will be 2500px) and started to create the document structure, shown as follows:
<div class="page"> <!-- here we need navigation --> <div class="row"> <div class="front_main_photo_wrapper col"></div> </div> <div class="row"> <div class="photo_block4 item1 col"> <img src="assets/img/img_front1_big.jpg"></div> <div class="photo_block4 item2 col"> <img src="assets/img/img_front2_big.jpg"></div> <div class="photo_block4 item3 col"> <img src="assets/img/img_front3_big.jpg"></div> <div class="photo_block4 item4 col"> <img src="assets/img/img_front4_big.jpg"></div> </div> <div class="row"> <div class="footer col"></div> </div> </div>
Note that images inside these blocks became fluid without any action from our side. This happens because of H5BP CSS defaults, shown as follows:
img { max-width: 100%; [...] }
Classes .row
and .col
are Gridpak classes that set columns, margins, and padding according to the settings we created on www.gridpak.com. The class .page
is the main content wrapper that can be used to define margins around content if we need them. An alternative way to define such margins may be by setting up padding on body elements. Bootstrap uses the following way for screens below 767px:
@media (max-width: 767px) { body { padding-right: 20px; padding-left: 20px; }
I'd like to set the left and right margins at five percent. Setting up padding on the body is the simplest way but it's not really a reliable or flexible way for this purpose (explaining this in detail is beyond the scope of this book). Instead I would try to control the content width with the following statement:
.page,bodydiv#gridpak{ width:90%; margin:0px auto; padding:0 5% 0 5%; }
Of course, to make the preceding code work as expected, it is necessary to comment out or override the Bootstrap <body>
padding.
Classes .photo_block4
, .footer
, and.front_main_photo_wrapper
are custom semantic names, and we have to define them within the respective media queries. This means that for each of the defined media query steps, we should decide how many columns wide the particular page block element should be. In our example, the class photo_block4
will take the following size:
- 3 columns in resolution 800px to infinity
- 2 columns in resolution 320px to 800px
- 2 columns in resolution 320px and lower
Its translation to code is shown as follows:
inside: (min-width: 0px) and (max-width: 319px) .photo_block4{width:48.5%;} /*same as .span_2 */ inside: @media screen and (min-width: 320px) and (max-width: 799px) .photo_block4{width:23.5%;} /*same as .span_2 */ inside: @media screen and (min-width: 800px) .photo_block4{width:24.25%;} /*same as .span_3 */
It works fine when the width is greater than 800px, where we have images in a row. There is however a problem when our four images are broken down into two or more rows. Gridpak uses the following CSS instruction to remove the left margin from the column class .col
:
.row .col:first-child {margin-left:0;}
We have to take care of this ourselves in each media query where we see the problem, shown as follows:
@media screen and (min-width: 320px) and (max-width: 799px) { .row .col:first-child, .photo_block4.item3.col{ margin-left:0; }
On this screen size, we start a new row from item three. For max-width: 319px
, we can just merge .photo_block4
definition with .span_2
, as shown in the following code:
.span_2, .photo_block4 { margin-left:0; width:100%; }
Now our blocks flow nicely across all resolutions. It's time to add some content using the following code:
<div class="main_photo"> <img src="assets/img/photo_big.jpg"> </div>
The preceding HTML code is for the main photo. Please note that there is no .col
class on the main photo div. In the original design, this photo extends to the full width of a container, <div class="page">
. To avoid column padding, I just don't use the .col class. Actually, using Gridpak CSS for column padding is not very helpful in my design. But that is a good starting point and a reference when creating and coding design. At the end of the day, the code needs a cleanup, so I treat it as a part of the iterative process of building the page code. Most of the code in the bootstrap reduced.css
can and should be removed before turning this example into a production code. Nonetheless, as we will use the Carousel
component from this package, I leave it as is.
The following is the code for one of the blocks with a small photo:
<div class="photo_block4 item1 col"> <img src="assets/img/img_front1_big.jpg"> <h3>Rustical interiors</h3> <p>Loremipsum dolor sitamet, [...]. </p> </div>
I don't describe CSS formatting for this block as it'd make this chapter unnecessarily long and complex. An issue related to CSS frameworks which is worth mentioning is the column padding problem. I needed the images above block headers to take full width using the .col
class here, but this was an issue. To solve it, I override its default padding (coming from Grider stylesheet) in site.css
by forcing all instances of photo_block4
div
to have padding:0px
. It is easier to add your own padding or margins to other elements of this block rather than trying to mess with negative margins. I just added the following code:
.photo_block4 p{ padding:0px 5%; } .photo_block4 h3{ padding:0px 3%; }
Our page needs a top responsive navigation bar, which is obtained using the following code:
<div class="navbar navbar-inverse navbar-fixed-top"> <div class="navbar-inner"> <div class="page"> <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="brand" href="#">Chatazapiecek</a> <div class="nav-collapse collapse"> <ul class="nav"> <li class="active"><a href="#">Home</a></li> <li><a href="#about">About</a></li> <li><a href="#contact">Contact</a></li> </ul> </div> </div> </div> </div>
The preceding code is based on a sample from http://twitter.github.com/bootstrap/examples/starter-template.html. The Class .navbar-fixed-top
causes the navigation bar to stay attached to the top of the window on wide screens. <div class="page">
is the wrapper that constrains the navigation bar width to the same width as that of the page contents. The contents of <div class="nav-collapse collapse">
are collapsed on small screens while <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
is shown to allow expanding this section.
An issue related to the navigation bar formatting is that fixed positioning on wide screens results in hiding a part of the page below it. To compensate for this effect, we can simply add the following code:
@media screen and (min-width: 979px){ body{ padding-top:70px; } }
In this way we added the body element's top padding within the same media query as the navigation bar position
changes to fixed
.
For the final touch, I slightly adjusted the header font size to improve the page look in some resolutions using the following code:
@media screen and (max-width: 1200px) { .photo_block4 h3{ font-size:18px; line-height:22px; padding-bottom:8px; padding-top:8px; } }
To see the final document, please refer to the current chapter's resources directory. The page has a grid overlay on top. To hide it, just press G on the keyboard.