icon-search

Grid-based layout development II: Bootstrap and beyond

Luis Belmonte Diaz 06.10.2016

In the previous post, we discussed what a grid is and got to know the basics of one of the most used tools to implement a grid-based layout: Bootstrap.

Now is time to check how we can put Bootstrap into use. For this, we will implement a very basic design using different approaches, all of them based in Bootstrap and check what do their use imply and what are their advantages and disadvantages.

Implementing a grid-based layout

The layout to be implemented is a simple design with a header, main section, right and left asides and a footer in bigger browser screens.

In a middle sized browser window the layout changes: the right aside wraps below both the left aside and main section, while the footer width doesn’t change. For smaller screen sizes, all the sections take 100% of the window size stacking one under the other.

Note: We are not going to be dealing here with same height elements in a row as it is something that can be done with the Bootstrap native tools. So the height of all the sections are set in CSS as well as the colours and are not related to the grid implementation.

Responsive Layout

Bootstrap is much more than Bootstrap

Bootstrap is much more than Bootstrap. Yes, really. Bootstrap is a very complete solution with lots of ready-out-of-the-box tools to develop responsive layouts, but still, there is a place to play around, configure it to some extend, and use it in significantly different ways.

Using Bootstrap

In this article, we are going to use Bootstrap in 3 different ways and see how they influence our code. We will:

  • Link to BootstrapCDN to get the CSS
  • Self-host the customized download of Bootstrap grid
  • Get SASS/LESS Bootstrap, import it with our styles and compile it
  • Get SASS/LESS Bootstrap, use its mixins to get a more semantic markup

Linking to Bootstrap CDN

This is the easiest option. Bootstrap hosts the files you need – the CSS in this case- and you just have to link to it. So, just grab the BootstarpCDN link, put it in your html and you are ready to go.

Here’s how the markup will look like to implement our design when linking to the Bootstrap CDN:


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />

        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <link href="./styles/min/style.css" rel="stylesheet" >

        <title>Bootstrap CDN hosted</title>
    </head>
    <body class="container-fluid">


<header class="row">


<nav class="col-md-9 col-md-offset-3 col-lg-8 col-lg-offset-2 navigation-content">
                This is the navigation
            </nav>


        </header>


        <main class="row">


<aside class="col-md-3 col-lg-2 left-aside">
                This is an aside
            </aside>




<section class="col-md-9 col-lg-8 section-content">
                This is a section
            </section>




<aside class="col-md-12 col-lg-2 right-aside">


<div class="aside-content">
                    This is an aside
                </div>


            </aside>


        </main>


<footer class="row">


<div class="col-md-9 col-md-offset-3 col-lg-8 col-lg-offset-2 footer-content">
                This is a footer
            </div>


        </footer>


    </body>
</html>

If we take a closer look at our markup, in lines 13-15 we have the code for the header with the navigation inside.

‘What? No class for the smaller window browser sizes?’

Do you remember what we said in the first part of this series? Bootstrap is a mobile first framework and that means that its grid classes work from a starting breakpoint and up.

‘Well, but no classes at all!?’

Yep. No classes for narrower sizes as our layout starts with 100% width and that’s the way block elements behave by default anyway.

Still, in line 14 we have a class defining a 9 columns span for medium width window sizes and another one to tell the browser to push this element the width of 3 columns to the right.

And then, for larger browser windows widths a class defining the 8 columns width span of the element and that it has to be pushed 2 columns to the right.

And finally, a class I gave to this element to style it to my convenience.

To sum up: 5 classes for one element. That’s lots of ugly non semantic bloat our grandmas wouldn’t be proud of. And we don’t like that

Self-hosting Bootstrap CSS

The only difference in the markup if you are self-hosting Bootstrap CSS is in line 8:

       <link href="./styles/min/bootstrap.min.css" rel="stylesheet">

But there is much more to self-hosting. This option allows us to choose what are we hosting because we can customize the Bootstrap CSS file to download which will be compiled on the fly. BootstrapCDN just offers a link to the minified version of the whole framework CSS -and that’s a lot of CSS.

Using Bootstrap Sass to be imported and compiled with our own styles

This is an option that may not seem to apport that much, but we will use it in a follow-up article.

Using Bootstrap-Sass/Less is not the faster option. It means setting up at least a minimal development environment as the source code has to be compiled. We will see in this article how it influences our code, and the performance of our site in a follow-up article. As an aside, Bootstrap up to v.3 has been written in LESS – although they are moving to SASS with  Bootstrap 4.

Customizing Bootstrap

In this case, the customization is going to be minimal as we will just create a style.scss file where we import our styles and the Bootstrap blob with all its imports. You’ll notice that all the imports are pointing in this case to node_modules as I installed Bootstrap-Sass with npm. But that is the only customization done.

style.scss

@import 'custom-bootsrap';
@import 'custom-style';

custom-bootstrap.scss

/*!
 * Bootstrap v3.3.6 (http://getbootstrap.com)
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

// Core variables and mixins
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins";

// // Reset and dependencies
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/normalize";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/print";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/glyphicons";

// Core CSS
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/scaffolding";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/type";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/code";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/grid";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/tables";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/forms";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/buttons";

// Components
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/component-animations";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/dropdowns";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/button-groups";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/input-groups";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/navs";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/navbar";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/breadcrumbs";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/pagination";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/pager";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/labels";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/badges";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/jumbotron";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/thumbnails";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/alerts";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/progress-bars";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/media";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/list-group";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/panels";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/responsive-embed";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/wells";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/close";

// Components w/ JavaScript
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/modals";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/tooltip";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/popovers";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/carousel";

// Utility classes
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/utilities";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/responsive-utilities";

Our markup changes slightly from the previous version. Now there is just one link to a stylesheet.

   <link href="./styles/min/style.css" rel="stylesheet" >

Yep, we are saving a line in our html, but actually, we are doing much more, as we are saving also a server request. More on this on an upcoming article about performance.

Using Bootstrap mixins

This option in the most flexible one as we can customize the CSS and get rid of all the bloat grid classes Bootstrap forces to introduce in our markup.

For this, we are going to access directly the mixins Bootstrap uses to create its own classes and will generate just the code we need.

STYLE.SCSS

There are no changes here.

CUSTOM-BOOTSTRAP.SCSS

Here a lot of interesting happens. I made a copy of the original _bootstrap.scss file, as in the previous example and I commented out everything but 2 files: mixins and variables. Just these two will be used while compiling the final CSS.

Actually, you can just get rid of those commented lines. I left them so you could have a visual idea of everything we are not compiling with this option.

/*!
 * Bootstrap v3.3.6 (http://getbootstrap.com)
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

// Core variables and mixins
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables";
@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins";

// // Reset and dependencies
// @import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/normalize";
// @import "bootstrap/print";
// @import "bootstrap/glyphicons";
//
// // Core CSS
// @import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/scaffolding";
// @import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/type";
// @import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/code";
// @import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/grid";
// @import "bootstrap/tables";
// @import "bootstrap/forms";
// @import "bootstrap/buttons";

// Components
// @import "bootstrap/component-animations";
// @import "bootstrap/dropdowns";
// @import "bootstrap/button-groups";
// @import "bootstrap/input-groups";
// @import "bootstrap/navs";
// @import "bootstrap/navbar";
// @import "bootstrap/breadcrumbs";
// @import "bootstrap/pagination";
// @import "bootstrap/pager";
// @import "bootstrap/labels";
// @import "bootstrap/badges";
// @import "bootstrap/jumbotron";
// @import "bootstrap/thumbnails";
// @import "bootstrap/alerts";
// @import "bootstrap/progress-bars";
// @import "bootstrap/media";
// @import "bootstrap/list-group";
// @import "bootstrap/panels";
// @import "bootstrap/responsive-embed";
// @import "bootstrap/wells";
// @import "bootstrap/close";

// Components w/ JavaScript
// @import "bootstrap/modals";
// @import "bootstrap/tooltip";
// @import "bootstrap/popovers";
// @import "bootstrap/carousel";

// Utility classes
// @import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/utilities";
// @import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/responsive-utilities";

CUSTOM-STYLE.SCSS

This is the file where there are my styles to give color and height to the layout. Until now it was not relevant at all, but in this important things happen for our layout.

Because I commented out the grid.scss file in custom-bootstrap.scss -among others- we are not going to generate all the predefined grid classes available in Bootstrap when compiling but just the ones we are using.

What we are doing now is calling the mixins responsible for creating the layout behavior we want to achieve by using @include from each of the classes/element tags and passing as an argument  to those mixins the number of columns we want the element to span to or to be pushed to the right. And this all just stays in the CSS/SASS side.

body {
    @include container-fixed;
}

header,
main,
footer {
    @include make-row;
}

nav,
.section-content,
.footer-content {
    @include make-md-column(9);
    @include make-lg-column(8);
}

nav,
.footer-content {
    @include make-md-column-push(3);
    @include make-lg-column-push(2);
}

.left-aside {
    @include make-md-column(3);
}

.right-aside {
    @include make-md-column(12);
}

.left-aside,
.right-aside {
    @include make-lg-column(2);
}

I wrote above that the markup resulting from the use of Bootstrap classes was bloated and not semantic. And actually, there was something I didn’t mention, the fact that if we write all that code that actually defines the layout, we are not separating matters.

It is not recommended and not a good practice to include style/layout elements in the HTML and until now we have been actually shaping the layout in the markup.

THE NEW SHINNING AND SEMANTIC MARKUP

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />

        <link rel="stylesheet" href="./styles/min/style.css">
        <title>Bootstrap grid mixins</title>
    </head>
    <body>


<header>


<nav class="navigation-content">
                This is the navigation
            </nav>


        </header>


        <main>


<aside class="left-aside">
                This is an aside
            </aside>




<section class="section-content">
                This is a section
            </section>




<aside class="right-aside">
                This is an aside
            </aside>


        </main>


<footer>


<div class="footer-content">
                This is a footer
            </div>


        </footer>


    </body>
</html>

As we have already discussed, the markup should be free of styling logic and this is a usual complaint about Bootstrap from those who don´t like it. But as you can see now, by customizing Bootstrap the markup is prettier and more semantic -please forgive me for the class names –  than it was before and the layout can be modified just by editing the CSS.

What we learnt in this tutorial:

  • How to built a layout based in Bootstrap classes
  • How the use customized versions of Bootstrap
  • How to use Bootstrap mixins to have a more semantic markup
  • How the different options influence our code

comments: 0


Notice: Theme without comments.php is deprecated since version 3.0.0 with no alternative available. Please include a comments.php template in your theme. in /var/www/html/www_en/wp-includes/functions.php on line 4597

Leave a Reply

Your email address will not be published. Required fields are marked *