Setting up major structural elements
We're almost ready for page content. Specifically, we'll create the following:
- A banner space with our logo and navigation
- A main content space for page content
- A footer area for copyright information and social links
We'll set this up using current HTML5 best practices with the support of major Accessible Rich Internet Applications (ARIA) role attributes (with roles such as banner
, navigation
, main
, and contentinfo
).
Run the bootstrap watch
command, and your browser should open automatically on http://localhost:8080/
. Then start editing the html/pages/index.html
file; you can use your favorite text editor, and write down the following HTML code into it:
--- layout: default title: Home --- <header role="banner"> <nav role="navigation"> </nav> </header> <main role="main"> <h1>Main Heading</h1> <p>Content specific to this page goes here.</p> </main> <footer role="contentinfo"> <p><small>Copyright © Company Name</small></p> </footer>
This gives us some basic page structure and content. Let's keep rolling. Notice that the content you have added to the html/pages/index.html
file is compiled into the html/layout/default.html
layout template. The layout template contains the main HTML structure and links the compiled CSS and JavaScript code.
The JavaScript code has been linked at the end of the HTML code for faster performance. Notice that Gulp bundles jQuery, Tether, and the Bootstrap jQuery plugins into a single _site/js/app.jss
file. Loading jQuery on Tether from CDN is an alternative solution.
Providing a navbar markup
The compiled CSS code is already linked to the compiled HTML code and can be found in the _site/css
folder. We'll learn how to customize the CSS with Sass shortly. But first, let's put at least one Bootstrap-specific element in place, that is, the navbar.
Initially, we want only Bootstrap's basic navbar (we'll add other details later). I've used the markup taken from Bootstrap's documentation. This leads to the following result, nested within our header
element:
<header role="banner"> <nav class="navbar navbar-light bg-faded" role="navigation"> <a class="navbar-brand" href="index.html">Navbar</a> <ul class="nav navbar-nav"> <li class="nav-item"> <a class="nav-link active" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Features</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Pricing</a> </li> <li class="nav-item"> <a class="nav-link" href="#">About</a> </li> </ul> <form class="form-inline pull-xs-right"> <input class="form-control" type="text" placeholder="Search"> <button class="btn btn-success-outline" type="submit">Search</button> </form> </nav> </header>
Save your results, and the browser will automatically refresh. You should now see Bootstrap's default navigation styles, and you'll also see some typographic enhancements as shown in the following screenshot. This is Bootstrap CSS at work. Congratulations!
We now have the default Bootstrap styles in place.
The CSS classes of the navbar
As you can see in the preceding navbar example, you can construct the navbar with standard HTML elements, such as the <nav>
, <a>
and <ul>
, and Bootstrap's CSS classes.
First inspect the classes added to the <nav>
element in the following snippet:
<nav class="navbar navbar-light bg-faded" role="navigation"></nav> The .nav class sets the basic styles for the navbar.
The .navbar-light
and .navbar-dark
classes set the color of the texts and links in the navbar. You should use the .navbar-light
classes when the background color of the navbar has a light color and the .navbar-dark class for dark colored navbars.
Finally, the .bg-*
classes set the background color of the navbar; you can use one of the following classes to do this: .bg-inverse
, .bg-faded
, .bg-primary
, .bg-success
, .bg-info
, .bg-warning
and .bg-danger
. These classes are part of Bootstrap's contextual backgrounds and can also be used for other elements and components.
The title or heading of the navbar can be an <a>
or <span>
element with the .navbar-brand
class.
The navbar items are built with an unnumbered list (<url>
), wherein each list item (<li>
) gets the .nav-item
tag and contains an anchor (<a>
) tag with the .navbar-link
class. Active items not only have the .navbar-link
class but also the .active
class.
Finally, notice the .sr-only
class in the following snippet of the navbar HTML code:
<span class="sr-only">(current)</span>
HTML elements with the .sr-only
class are only available for screen readers.
Note
More information about this can be found at http://a11yproject.com/posts/how-to-hide-content/.
Placement of the navbars
By default, navbars have rounded corners and are statically placed on the page. Special CSS classes can be used to fix the navbar at the top (.navbar-fixed-top
) or bottom (.navbar-fixed-bottom
) of the page or remove the rounded corners and set the z-index of the navbar (.nav bar-full
). Now, let's complete our navbar by making it responsive. As a bonus, this will test to ensure that Bootstrap's JavaScript plugins are working as they should.
Adding collapsible content to the navbar
Bootstrap's collapsible plugin allows you to create collapsible content by simply using a <a>
and <button>
tag to toggle hidden content. You can add the toggle button to your navbar too.
First create your collapsible content and wrap it in a <div class="collapse">
with a unique id as follows:
<div class="collapse" id="collapsiblecontent"> Collapsible content </div>
Then create the button with .navbar-toggler
class and data-toggle
and data-target
attributes like that shown in the HTML code shown as follows:
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsiblecontent"> ☰; ; </button>
In the above code snippet, the data-toggle
attribute should be set to collapse
to trigger the collapse plugin, and the data-target
attribute should refer to the unique ID set for your collapsible content. Notice that the ☰
HTML code defines the so-called hamburger sign which looks like this:
Now you can bring the preceding codes together and place the button in the navbar. Write down the following HTML in the html/pages/index.html
file and inspect the results in your browser:
<header> <div class="collapse" id="collapsiblecontent"> Collapsible content </div> <nav class="navbar navbar-light bg-faded" role="navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsiblecontent"> ☰ </button> </nav> </header>
If you are still running the bootstrap watch command, your browser should automatically reload. The result should look like that shown in the following screenshot:
Click the hamburger and you should find that the collapsible content becomes visible. Now you can be sure that the collapse plugin works as expected. The collapse plugin is also used for a responsive navbar as discussed in the next section.
Content wrapped in the .collapse
is hidden by default. By clicking the toggle button, the plugin adds the .in
class which sets the display to visible. The plugin starts with adding a temporary .collapsing
class which sets a CSS animation that ensures the transition goes ahead smoothly.
Responsive features and breakpoints
Bootstrap has got four breakpoints at 544
, 768
, 992
and 1200
pixels by default. At these breakpoints your design may adapt to and target specific devices and viewport sizes. Bootstrap's mobile-first and responsive grid(s) also use these breakpoints. You can read more about the grids later on.
You can use these breakpoints to specify and name the viewport ranges as follows; the extra small (xs
) range for portrait phones with a viewport smaller than 544
pixels, the small (sm
) range for landscape phones with viewports smaller than 768
pixels, the medium (md
) range for tablets with viewports smaller than 992
pixels, the large (lg
) range for desktop with viewports wider than 992
pixels, and finally the extra large (xl
) range for desktops with a viewport wider than 1200
pixels. The break points are in pixel values as the viewport pixel size does not depend on the font size and modern browsers have already fixed some zooming bugs.
Some people claim em values should be preferred.
Note
To learn more about this, have a look at the following link: http://zellwk.com/blog/media-query-units/.
Those who still prefer em values over pixel values can simply change the $grid-breakpoints
variable declaration in the scss/includes/_variables.scss
file. To use em values for media queries, the SCSS code should look like the following:
$grid-breakpoints: ( // Extra small screen / phone xs: 0, // Small screen / phone sm: 34em, // 544px // Medium screen / tablet md: 48em, // 768px // Large screen / desktop lg: 62em, // 992px // Extra large screen / wide desktop xl: 75em //1200px );
Notice that you also have to change the $container-max-widths
variable declaration. You should change or modify Bootstrap's variables in the local scss/includes/_variables.scss
file, as explained at http://bassjobsen.weblogs.fm/preserve_settings_and_customizations_when_updating_bootstrap/. This will ensure that your changes are not overwritten when updating Bootstrap.
Responsive utility classes
Bootstrap contains some predefined utility classes for faster mobile-friendly development. You can use these classes to show or hide content by device and viewport via media query.
The .hidden-*-up
classes, where the asterisks can be replaced with one of the breakpoint shorthand names, hide everything for viewports wider than the given breakpoint. So for instance, the .hidden-md-up
class hides an element on medium, large, and extra-large viewports. On the other hand, the .hidden-md-down
classes go in the other direction and hide an element when the viewport is smaller than the breakpoint.
Bootstrap's media query ranges, or breakpoints are also available via Sass mixins. The media-breakpoint-up()
mixin with one of the breakpoint shorthands as an input parameter sets the min-width
value of the media query to hide content for viewports wider than the breakpoint. The max-width
of the media query to hide everything for viewports smaller than the breakpoint can be set with the media-breakpoint-down()
mixin.
Consider the following SCSS, which can be written down at the end of the scss/app.scss
file:
p { font-size: 1.2em; @include media-breakpoint-up(md) { font-size: 1em; } } The preceding SCSS code compiles into static CSS code as follows: p { font-size: 1.2em; } @media (min-width: 768px) { p { font-size: 1em; }
Completing the responsive navbar
To completely make our navbar take advantage of Bootstrap's responsive navbar solution, we need to add two new elements, with appropriate classes and data attributes.
We'll begin by adding the toggle button to the navbar code we have used before. The HTML code of your button should look like the following:
<button class="navbar-toggler hidden-md-up pull-xs-right" type="button" data-toggle="collapse" data-target="#collapsiblecontent"> ☰ </button>
As you can see in the preceding HTML code, the button has the same data attributes as before, from the collapsible content example, since the responsive navbar uses the collapse plugin too. The button has a .hidden-md-up
utility class, as described before, to hide the button for viewports wider than 768
px. The .pull-xs-right
class ensures that the button floats on the right side of the navbar.
Secondly, you have to add the classes of the element which should collapse. We collapse the <ul>
that holds the navigation links. Add the .navbar-toggleable-sm
that ensures that the elements do not collapse on viewports larger than the breakpoint, while the .collapse
class hides the element by default. Finally, set the unique ID specified on the data-target
attribute of the button before. Your HTML code should look like the following now:
<ul class="nav navbar-nav navbar-toggleable-sm collapse" id="collapsiblecontent"></ul>
The complete HTML code of your responsive navbar should look as follows. You can add it to the html/pages/index.html
file to test it in your browser:
<header role="banner"> <nav class="navbar navbar-light bg-faded" role="navigation"> <a class="navbar-brand" href="index.html">Navbar</a> <button class="navbar-toggler hidden-md-up pull-xs-right" type="button" data-toggle="collapse" data-target="#collapsiblecontent"> ☰ </button> <ul class="nav navbar-nav navbar-toggleable-sm collapse" id="collapsiblecontent"> <li class="nav-item"> <a class="nav-link active" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Features</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Pricing</a> </li> <li class="nav-item"> <a class="nav-link" href="#">About</a> </li> </ul> </nav> </header>
Note
The tag structure, class names, or data attributes may change with future versions of Bootstrap. If yours does not work as it should, be sure to check Bootstrap's own documentation. As a fallback option, you can start with the starting files provided with the sample code for this book.
The .navbar-brand
and .nav-link
classes have a float:left
set by default. So that your navigation links should not float for the collapsed version of your navbar, you should undo the float. You can use the following SCSS code to remove the float for smaller viewports, and write it down at the end of the scss/app.sccs
file:
.navbar { @include media-breakpoint-down(sm) { .navbar-brand, .nav-item { float: none; } } }
If you run the bootstrap watch command your browser should automatically reload after saving the HTML or Sass code, if not, run the command again. Your browser should show the results at http://localhost:8080/
. Click on and drag the edge of the browser window to make the window narrower than 768
pixels.
If all works as it should, you should see a collapsed version of the navbar, as shown in the following screenshot, with the site name or logo and a toggle button:
This is a good sign! Now click on the toggle button, and it should slide open, as shown in the following screenshot:
Success! Congratulations!
The new Reboot module and Normalize.css.
When talking about cascade in CSS, there will, no doubt, be a mention of the browser default settings getting a higher precedence than the author's preferred styling. In other words, anything that is not defined by the author will be assigned a default styling set by the browser. The default styling may differ for each browser and this behavior plays a major role in many cross-browser issues. To prevent these sorts of problems, you can perform a CSS reset CSS or HTML resets set a default author style for commonly used HTML elements to make sure that browser default styles do not mess up your pages or render your HTML elements to be different on other browsers.
Bootstrap uses Normalize.css written by Nicholas Galagher. Normalize.css is a modern, HTML5-ready alternative to CSS resets and can be downloaded from http://necolas.github.io/normalize.css/. It lets browsers render all elements more consistently and makes them adhere to modern standards. Together with some other styles, Normalize.css forms the new Reboot module of Bootstrap.
Box-sizing
The Reboot module also sets the global box-sizing value from content-box
to border-box
. The box-sizing property is the one that sets the CSS-box model used for calculating the dimensions of an element. In fact, box-sizing is not new in CSS, but nonetheless, switching your code to box-sizing: border-box
will make your work a lot easier. When using the border-box
settings, calculation of the width of an element includes border width and padding. So, changing the border width or padding of an element won't break your layouts.
Predefined CSS classes
Bootstrap ships with predefined CSS classes for everything. You can build a mobile first responsive grid for your project by only using div elements and the right grid classes. CSS classes for styling other elements and components are available too. Consider the styling of a button in the following HTML code:
<button class="btn btn-warning">Warning!</button>
Now your button will look like that shown in the preceding screenshot:
You should notice that Bootstrap uses two classes to style a single button. The first .btn
class gives the button the general button layout styles. The second .btn-warning
class sets the custom colors of the buttons.
Note
Partial attribute selectors in CSS give us the ability to make partial matches to attribute values. You can, for instance, match all elements having a class starting with btn-
, so you may wonder why Bootstrap does not use the [class^='btn-']
attribute selector instead of the .btn
class to set the general button styles. Firstly, Bootstrap avoids partial attribute selectors, since some people claimed these selectors are slow. Secondly, [class^='btn-']
does not match "not btn-"
.
You can also use these classes to style a hyperlink (<a>
) like a button as follows:
<a class="btn btn-primary" href="#" role="button">Link</a>
Sass variables and mixins
You can change Bootstrap's default styles by changing the Sass variables in the scss/_variabels.scss
file. Setting the $brand-primary
variable to a different color value will change the look of the buttons with the btn-primary class in the preceding example.
You can reuse Bootstrap's Sass mixins to extend Bootstrap with your own custom classes. Sass mixins and variables are available to build your own (semantic) grid, but you can also create a custom button class by using the following SCSS code:
.btn-tomato { @include button-variant(white, tomato, white); }
The preceding SCSS code compiles into the CSS code like the following:
.btn-tomato { color: white; background-color: tomato; border-color: white; } .btn-tomato:hover { color: white; background-color: #ff3814; border-color: #e0e0e0; } .btn-tomato:focus, .btn-tomato.focus { color: white; background-color: #ff3814; border-color: #e0e0e0; } .btn-tomato:active, .btn-tomato.active, .open > .btn-tomato.dropdown-toggle { color: white; background-color: #ff3814; border-color: #e0e0e0; background-image: none; } .btn-tomato:active:hover, .btn-tomato:active:focus, .btn-tomato:active.focus, .btn-tomato.active:hover, .btn-tomato.active:focus, .btn-tomato.active.focus, .open > .btn-tomato.dropdown-toggle:hover, .open > .btn-tomato.dropdown-toggle:focus, .open > .btn-tomato.dropdown-toggle.focus { color: white; background-color: #ef2400; border-color: #bfbfbf; } .btn-tomato.disabled:focus, .btn-tomato.disabled.focus, .btn-tomato:disabled:focus, .btn-tomato:disabled.focus { background-color: tomato; border-color: white; } .btn-tomato.disabled:hover, .btn-tomato:disabled:hover { background-color: tomato; border-color: white; }
Bootstrap's Sass code avoids element and nested selectors; a motivation can be found at http://markdotto.com/2015/07/20/css-nesting/.
Bootstrap itself also avoids the @extend
feature of Sass. The risk of using the @extend
feature is creating complex unused CSS code. See also Hugo Giraudel's article at https://www.sitepoint.com/avoid-sass-extend/.
Using selector placeholders may reduce this risk, however Bootstrap does not use placeholder selectors. This does not forbid you from customizing and extending Bootstrap by using the @extend
feature. You can, for instance, use the @extend
feature to make your images responsive by default.
Images are not responsive by default in Bootstrap. To make an image responsive, you'll have to add the .img-fluid
class to your <img>
element.
You can use the @extend
feature to make your images responsive by default by adding the following SCSS code at the end of the scss/app.scss
file:
img { @extend .img-fluid; }
Those who think using mixins is better than the @extend
feature, should realize that Bootstrap's Sass code does not contain a mixin for making fluid images at all.