loading...

Bootstrap 4 – The grid system

Bootstrap’s grid system is arguably its most impressive and most commonly used feature, as it solves the important task of horizontal and vertical positioning of a page’s contents, allowing the contents to be structured across multiple display widths. Therefore, mastering this core functionality is essential for any Bootstrap developer.

As already noted in Chapter 1, Revving Up Bootstrap, Bootstrap 4 is mobile-first. As such, it should come as no surprise that the grid system is optimized for smaller viewports, and it scales up to suit larger viewports (as opposed to scaling down to smaller viewports).

What is a viewport?
A viewport is the available display size to render the contents of a page, that is, it refers to your browser window, minus the toolbars and scrollbars. The viewport should not be confused with the viewport meta tag, which is used to define the viewport’s actual display size. To elaborate, as already noted in Chapter 1, Revving Up Bootstrap, mobile devices may indicate their viewport to be larger than it actually is in order to allow for the display of websites that have not been optimized for display on mobile devices. As a consequence, websites that take mobile viewports into consideration may often not render as intended. As a remedy, the viewport meta tag was introduced by Apple on iOS (and has since been uniformly adopted by all other major browsers) in order to allow websites to circumvent this problem by allowing developers to explicitly define the intended display size.

The grid composing the grid system is a structure that consists of three distinct, but fundamentally linked, parts: an all—encapsulating container split into horizontal rows that are themselves split into 12 equal columns (refer to Figure 2.1). In the following subsections, we will take an in-depth look at the three building blocks of Bootstrap’s grid system:

Figure 2.1: The Bootstrap grid structure: a container (outermost box) containing a table-like structure consisting of rows and 12 columns. It is important to note that rows must be contained inside the container. Likewise, columns can only exist within the context of rows. While grids can be used to construct tables, they are not tables in themselves. Unlike tables, independent rows may consist of a different number of columns. So, for example, row 1 may consist of 12 columns, while row 2 may contain only three columns.

Containers

Containers are at the core of Bootstrap’s grid system, and they typically form the root of all Bootstrap pages. A container is exactly what it sounds like—an element for holding all other content within a section of a page. By remaining toward the top of the element hierarchy, a container provides the base for how the section contained within it is rendered. You can think of a container as representing a canvas in a browser window for your content. All this content will be displayed on this canvas, which in turn can transform based on its environment. Unless explicitly specified, your content will never creep outside of this canvas, regardless of the viewport. A container can apply to the entire contents of a page, where you would have one root container element, or to different sections of a page, where you would have numerous container elements on the page.

There are two types of container classes provided by Bootstrap: container and container-fluid.

Container

The container class renders the contents of the page to a fixed width. This width is typically based upon the width of the viewport, leveraging CSS media queries to determine which width is most suitable. These media queries are expressions that resolve to a boolean (true or false) value. By using these queries, one can apply different style rules—known as media rules—based on different viewport properties. In the case of the grid system, Bootstrap uses these media queries and the viewport’s width to determine the fixed width to apply to a container’s content. In order to achieve this adjustment of width, the media rules triggered by the media queries work in conjunction with breakpoints. Breakpoints in relation to web development layouts are predefined vertical and horizontal dimensions at which the style rules change. As these rules break, they trigger another set of rules optimized for those dimensions. These rules are triggered by media queries, querying the dimensions of the viewport. For example, @media (min-width: 768px) will trigger a set of rules when the viewport is more than 768 px wide.

The grid system has five such core breakpoints:

  • extra-small (xs): Typically refers to the extra small screens encountered on mobile devices (for example, portrait mobile phone screens)
  • small (sm): Refers to your average mobile device screen (for example, landscape mobile phone screens)
  • medium (md): Refers to medium screen sizes, such as those encountered with tablets
  • large (lg): Refers to large screens, such as those encountered on laptop devices and desktops
  • extra-large (xl): Refers to extra-large screens, such as those on wide-screen desktop monitors

The breakpoints are defined in _variables.scss:

$grid-breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
) !default;

In other words, inside _variables.scss, Bootstrap is defining the five breakpoints’ width variables. Bootstrap will reference these variables throughout its Sass code, and the breakpoints can now be accessed as properties of $grid-breakpoints.

Inside _variables.scss, we can also see the variables for the various container sizes associated with the appropriate breakpoints. Consider the given example:

// Grid containers
//
// Define the maximum width of `.container` for different screen sizes.
$container-max-widths: (
  sm: 540px,
  md: 720px,
  lg: 960px,
  xl: 1140px
) !default;
@include _assert-ascending($container-max-widths, "$container-max-widths");
// Grid columns
//
// Set the number of columns and specify the width of the gutters.
$grid-columns: 12 !default;
$grid-gutter-width: 30px !default;

For example, container-max-widths is set to 750 px: 720 px plus the value of grid-gutter- width, which is 30 px. These sizes are leveraged via media queries in _grid.scss to set the desired width of the container. Let’s take a look inside _grid.scss at the .container class:

.container {
    @include make-container();
    @include make-container-max-widths();
}

The preceding make-container() and make-container-max-widths() are mixins with rules to center the container within the viewport and set max-width rules, respectively.

What is a mixin?
A mixin in this context is a set of predefined style rules encapsulated in a variable, which can be used within another rule’s definition. This is great for code maintenance and don’t repeat yourself (DRY) principles.

You will also find make-container and make-container-max-widths within _grid.scss. The make-container mixin centralizes the alignment of the container using margin and padding rules. Take a look at the following code:

@mixin make-container() {
  width: 100%;
  padding-right: ($grid-gutter-width / 2);
  padding-left: ($grid-gutter-width / 2);
  margin-right: auto;
  margin-left: auto;
}
Media queries as Sass mixins?
All Bootstrap media queries are available as Sass mixins, allowing you to reuse them at will:

     @include media-breakpoint-only(sm) { ... }
     @include media-breakpoint-only(md) { ... }
     @include media-breakpoint-only(lg) { ... }
     @include media-breakpoint-only(xl) { ... }

The make-container-max-widths mixin is more complex. It loops through the global $breakpoint variable, synonymous with $grid-breakpoints, and sets a max-width rule for each breakpoint using media queries. Take a look at the following code:

// For each breakpoint, define the maximum width of the container in a media query
@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
    @each $breakpoint, $container-max-width in $max-widths {
        @include media-breakpoint-up($breakpoint, $breakpoints) {
            max-width: $container-max-width;
        }
    }
}

The completed code then looks like the following:

@media (min-width: 576px) {
    .container {
        max-width: 540px;
    }
}
@media (min-width: 768px) {
    .container {
        max-width: 720px;
    }
}
@media (min-width: 992px) {
    .container {
        max-width: 960px;
    }
}
@media (min-width: 1200px) {
    .container {
        max-width: 1140px;
    }
}

There are four media queries defining the horizontal breakpoint to trigger a width style rule. For example, @media (min-width: 768px) instructs the browser to only set the width property to the max-width of the container to 720 px for viewports wider than or equal to 768 px. This property is then superseded by the @media (min-width: 992px) rule when the viewport is wider than or equal to 992 px.

In a vast majority of cases, the width of the contents of the page is fixed to the width of the container. There are cases where the width of the container is ignored. One such case is Bootstrap’s navbar class, in which the navbar element is allowed to fill the entire horizontal width of the viewport. We will come across this scenario in a later chapter.

Now that we have seen how the container is constructed and the theory behind the container, let’s see it in practice. A container is generally a div with a container class in the body of the markup wrapping around the page’s main content. Consider this example:

<body>
    <div >
      <h1>Help, I'm trapped in a container!</h1>
    </div>
    <div>
      <h1>I'm free!</h1>
    </div>
</body>

Take a look at Figure 2.2 here:

Figure 2.2: Using the container class (example01.html)

Container-fluid

Earlier on in this chapter, we noted that there exist two types of containers. In the previous subsection, we covered the first type—container. The second type of container, container-fluid, differs from container in two distinct ways:

  • It takes up the full width of the viewport, except for 15 pixels padding left and right
  • It doesn’t concern itself with breakpoints

The container-fluid allows the page to be fully responsive to all widths, providing smoother transitions. When responding to breakpoints, container snaps the layout to the appropriate width, while container-fluid progressively alters the layout.

The only difference in the markup is that instead of applying the container class to the container div, the container-fluid class is applied instead. Consider the following code snippet:

<body>
    <div >
        <h1>Help, I'm trapped in a container!</h1>
    </div>
    <div>
        <h1>I'm free!</h1>
    </div>
</body>

The preceding snippet produces the result illustrated in figure 2.3:

Figure 2.3: Using the container-fluid class (example02.html)

Note that the container element now sits 15 pixels from the edge of the browser. When we use container, the container already has a hard-coded width defined. This width is based on the viewport. For example, at a resolution of 1200 px wide, the container will be 1140 px wide. At a resolution of 1280 pixels, the container will remain at 1170 px wide, because the container only responds to certain breakpoints. When we use container-fluid, the container width is dynamic, because container-fluid responds to every horizontal change and bases the width solely on the padding values from the make-container mixin; container, on the other hand, responds only at specific widths; container-fluid is the approach to take when building a page that needs to work across all display sizes and forms, especially when building mobile-first applications.

The boxed (.container) class results in jumpy resizing. The wide layout (.container-fluid) results in continuous resizing. Both are valid even for mobile-first apps.

The container ensures that our contents will always display within a defined area on the page. But what about positioning content within the container? This is where rows come into play.

Box-sizing

In CSS, every element is represented as a rectangle or box. Each box has a number of properties associated with it to define how the element is rendered. This is the CSS Box Model. The box-sizing property of an element defines how the Box Model should calculate the width and height of elements.

The default value for box-sizing in the CSS box model is content-box. The content-box property only includes the content of an element when calculating the size of that element.

Bootstrap 4 defaults the value of box-sizing to the border-box. The border-box property includes the padding and border as well as the content of the element in the calculation of the height and width of the element. Note that the margin is not included in the calculation. The third possible value for box-sizing is padding-box. The padding-box property, as the name suggests, only uses the content and the padding in calculating the size of an element.

Rows

A row is used to define a selection of elements that should be dealt with as a horizontal group. As such, rows reside within a container element. The power of the row lies in being able to stack content vertically, almost like containers within a container, or defining a section of the page. Creating a row is as simple as applying the row class to the desired element:

<body>
    <div class="container">
        <h1>Help, I'm trapped in a container!</h1>
        <div class="row">
            <div>Section 1</div>
        </div>
        <div class="row">
            <div>Section 2</div>
        </div>
        <div >
            <div>Section 3</div>
        </div>
    </div>
    <div>
        <h1>I'm free!</h1>
    </div>
</body>

Take a look at Figure 2.4, as follows:

Figure 2.4: Using rows (example03.html)

The true power of rows only becomes apparent when they are used with columns.

Flexbox is now on by default, so support for IE9 was dropped from Bootstrap 4.

Columns

Arguably, columns are the most important piece of the grid system. Rows exist within containers, and those rows are split up into 12 equal columns. Before we get into the nitty-gritty details, let’s take a look at an example by taking the first step to create the print sizes section of MyPhoto. There will be 12 print sizes offered. Let’s list those sizes horizontally:

<div class="container">
    <h1>Our Print Sizes</h1>
    <div class="row">
        <div class="col-sm-1">6x5</div>
        <div class="col-sm-1">8x10</div>
        <div class="col-sm-1">11x17</div>
        <div class="col-sm-1">12x18</div>
        <div class="col-sm-1">16x20</div>
        <div class="col-sm-1">18x24</div>
        <div class="col-sm-1">19x27</div>
        <div class="col-sm-1">20x30</div>
        <div class="col-sm-1">22x28</div>
        <div class="col-sm-1">24x36</div>
        <div class="col-sm-1">27x39</div>
        <div >27x40</div>
    </div>
</div>

As usual, we first define our container. Within that container, we created a row, and within that row, we created 12 individual elements with col-sm-1. This produces a very neat list of evenly spaced elements in a single row on the page. take a look at the screenshot in Figure 2.5:

Figure 2.5: Using columns to display print sizes (example04.html)

Let’s break down col-sm-1 and explain each part individually:

  • col: This means that we want this element to act as a column
  • sm: This is a reference to all viewports above or equal to 576 px. This class means we apply this rule for all viewports equal to or larger than 576 px
  • 1: This means that the element takes up one column width of the row (1/12 of the row width)

As col-sm-1 references viewports larger than 576 px, smaller viewports (such as phones) revert to a stacked view. Take a look at the screenshot in Figure 2.6:

Figure 2.6: Viewports smaller than 544 px revert to a stacked view when using col-sm-1 (example04.html)

Columns are split up into five distinct breakpoints:

  • col-: This is for viewports below 576 px (extra-small)
  • col-sm-: This is for viewports of 576 px or greater (small)
  • col-md-: This is for viewports of 768 px or greater (medium)
  • col-lg-: This is for viewports of 992 px or greater (large)
  • col-xl-: This is for viewports of 1200 px or greater (extra-large)

The Bootstrap 3 column breakpoints

Bootstrap 3 did not have col-xl. Furthermore, its four distinct breakpoints were as listed:

  • col-xs-: This was for viewports below 768px (extra-small)
  • col-sm-: This was for viewports of 768px or greater (small)
  • col-md-: This was for viewports of 992px or greater (medium)
  • col-lg-: This was for viewports of 1200px or greater (large)

These classes are then appended with the number of columns an element should cover.

Redefining your grid

As previously noted, the number of grid columns as well as the individual breakpoints can be changed globally by modifying the $grid-columns and $grid-breakpoints variables defined in _variables.scss. If modifying the $grid-columns variable, one will also need to update the $grid-gutter-width variable.
As noted in the official Bootstrap 4 documentation, $grid-columns is used to generate the width (in percent) of each individual column, while $grid-gutter-width allows breakpoint-specific widths that are divided evenly across padding-left and padding-right for the column gutters.
(Source: http://getbootstrap.com/docs/4.0/layout/grid/.) Note that we do not advise this, however, as modifying these variables may result in an unintended side.

Now that we understand the column notation, let’s go ahead and split the print sizes into five separate categories, namely, Extra SmallSmall, Medium, Large, and Extra Large. As we know, a row is split into 12 columns. We have four print size categories, so we divide the number of columns by the number of elements, and that is the number of columns we want the element to cover. So, we append the number 3 to the col-sm-* class name:

<div class="container">
    <h1>Our Print Sizes</h1>
    <div class="row">
        <div class="col-sm-3">Small</div>
        <div class="col-sm-3">Medium</div>
        <div class="col-sm-3">Large</div>
        <div >Extra Large</div>
    </div>
</div>

This markup will render the page as shown in the screenshot in figure 2.7:

Figure 2.7: Print Categories split it into even columns across the grid system (example05.html)

Again, on an extra-small viewport, we will see the elements stacked, that is, the elements will appear one on top of the other. However, what if we do not want this to happen? What if we would like the elements to take up a different number of columns as the viewport size changes? Well, luckily, Bootstrap allows you to define the column widths for all breakpoints, and it will decide which rule to apply. Let’s try the following:

<div class="container">
    <h1>Our Print Sizes</h1>
    <div class="row">
        <div class="col-sm-6 col-md-3">Small</div>
        <div class="col-sm-6 col-md-3">Medium</div>
        <div class="col-sm-6 col-md-3">Large</div>
        <div >Extra Large</div>
    </div>
</div>

We have retained col-md-3, but now we have included col-sm-6. This means that for viewports below 768 px in width, we want each element to take up six columns. This will result in the first two elements displaying on one line and the last two below that.

On a viewport 768 px or wider, the categories appear in one horizontal row (as previously suggested, this is a drastic change from Bootstrap 3; with the previous version of Bootstrap, using the code, categories would appear in a horizontal row for viewports of 768 px or wider). Look at the screenshot in Figure 2.8:

Figure 2.8: The print sizes at a resolution above 768 px (example06.html)

On a viewport of less than 768 px wide, the categories are split across two rows, as shown in figure 2.9:

Figure 2.9: The print sizes at a resolution below 768 px (example06.html)

Nesting

Not only does the grid system split rows horizontally into columns, it also allows you to split the columns vertically, by supporting nested rows. These nested rows themselves are split into 12 columns within the space provided by the parent column. There is nothing special needed in terms of markup to achieve row inception. All that is needed to achieve this is to nest the elements appropriately and apply the row and column classes.

Let’s organize our print sizes into the relevant categories. We want 12 size options split equally into four size categories. Each category will contain one row element, with each print size taking up one column in the grid. Let’s try the following:

<div class="container">
   <h1>Our Print Sizes</h1>
   <div class="row">
      <div class="col-6 col-sm-3">
         <h5>Small</h5>
         <div class="row">
            <div class="col-sm-4">6x5</div>
            <div class="col-sm-4">8x10</div>
            <div class="col-sm-4">11x17</div>
         </div>
      </div>
      <div class="col-6 col-sm-3">
         <h5>Medium</h5>
         <div class="row">
            <div class="col-sm-4">12x18</div>
            <div class="col-sm-4">16x20</div>
            <div class="col-sm-4">18x24</div>
         </div>
      </div>
      <div class="col-6 col-sm-3">
         <h5>Large</h5>
         <div class="row">
            <div class="col-sm-4">19x27</div>
            <div class="col-sm-4">20x30</div>
            <div class="col-sm-4">22x28</div>
         </div>
      </div>
      <div class="col-6 col-sm-3">
         <h5>Extra Large</h5>
         <div class="row">
            <div class="col-sm-4">24x36</div>
            <div class="col-sm-4">27x39</div>
            <div >27x40</div>
         </div>
      </div>
   </div>
</div>

This produces a set of nested print sizes, as illustrated in figure 2.10:

Figure 2.10: The print sizes using nesting (example07.html)

Within our category columns, we have nested a row. We split each row into three equal columns for viewports larger than or equal to 576 px wide, using col-sm-4, to display the print sizes. Typically, it is good practice to ensure that the sum total of columns defined within the nested rows doesn’t exceed the 12 columns allocated, as Bootstrap applies widths based on the assumption of 12 columns. Exceeding the 12 columns may result in unequal or unexpected column widths. However, on some occasions, you may want to force a column onto another line at certain resolutions, where, for example, the text content of columns may slightly overlap at certain resolutions.

In that case, we would like to force certain columns onto another line at a small resolution. To do this, we add col-md-* classes and give the columns requiring a new line at 576 px the col-sm-12 class. Let’s force the third size in the Large category onto its own line and force all Extra Large sizes onto separate lines. Let’s try the following:

<div class="col-6 col-sm-3">
   <h5>Large</h5>
   <div class="row">
      <div class="col-sm-12">19x27</div>
      <div class="col-sm-12">20x30</div>
      <div class="col-sm-12 col-md-4">22x28</div>
   </div>
</div>
<div class="col-6 col-sm-3">
   <h5>Extra Large</h5>
   <div class="row">
      <div class="col-sm-12 col-md-4">24x36</div>
      <div class="col-sm-12 col-md-4">27x39</div>
      <div >27x40</div>
   </div>
</div>

Take a look at figure 2.11:

Figure 2.11: The print sizes with the “Extra Large” category forced onto a separate line for viewports equal to or above 576 px (example08.html)

That’s nice and neat. If you have been paying attention, then you will have noted that we do not actually need to define the resolutions below Medium if we want the elements to have separate lines, as this is the default behavior. We will only need to define it if we wanted a resolution below that (such as xs) to have a different behavior. So, this does the trick:

<div class="col-6 col-sm-3">
   <h5>Large</h5>
   <div class="row">
      <div class="col-sm-4">19x27</div>
      <div class="col-sm-4">20x30</div>
      <div class="col-md-4">22x28</div>
   </div>
</div>
<div class="col-6 col-sm-3">
   <h5>Extra Large</h5>
   <div class="row">
      <div class="col-md-4">24x36</div>
      <div class="col-md-4">27x39</div>
      <div >27x40</div>
   </div>
</div>
Flexbox

Flexbox is a CSS box model that is, in a way, similar to the Bootstrap grid system in that it allows for the simple implementation of complex layouts. As opposed to the CSS2 layout modules, such as block, inline, table, and positioned, flexbox is designed to allow a layout to make the most use of the available space through a set of simple rules. 

Auto-layout of columns

If you are not concerned about viewport-dependent column sizes, then you can use the non-breakpoint-specific column classes: col-*. Using these classes, you can both set equal-width columns and specify your exact column sizes. Using equal-width columns, our aforementioned nested print sizes example will translate into the following (note the use of the unnumbered col class):

<div class="col-6 col-sm-3">
   <h5>Extra Large</h5>
   <div class="row">
      <div class="col">24x36</div>
      <div class="col">27x39</div>
      <div >27x40</div>
   </div>
</div>

Since this feature also relies on Flexbox, it is important to note the following observation taken from the Bootstrap 4 documentation:

“Equal-width columns can be broken into multiple lines, but there is a Safari flexbox bug that prevents this from working without an explicit flex-basis or border. Our example works thanks to the border being set; you can do the same with .col { border: 1 px solid transparent; }. Alternatively, you can set the flex-basis to the width of the column (for example, .col { flex: 1 0 50%; }).” (http://getbootstrap.com/docs/4.0/layout/grid/#flex-order)
Behind the scenes, Bootstrap defines col using 6 simple rules:

.col {
  -ms-flex-preferred-size: 0;
  flex-basis: 0;
  -webkit-box-flex: 1;
  -ms-flex-positive: 1;
  flex-grow: 1;
  max-width: 100%;
}

The first two rules basically set the element’s size to 0, hence giving us a clean slate to work with. It should be noted that the second rule—flex-basis—should not be confused with flex-width: the former works along both axes, while the latter only sets the horizontal width of an element. The flex-grow property defines the factor of the amount of space that the element can take up. Last, but not least, Bootstrap explicitly defines the maximum width of the element to be 100%, that is, the element can take up all the available space.

If we do not wish our columns to take on an equal width but wish to specify a viewport size independent width, we simply prepend the col class with a number ranging from 1 to 12 (just as is the case with the viewport-sensitive col classes). Let’s assume that we wish to make the last resolution in our nested column wider than the previous two. In this case, we will replace the col class for the div containing the 27x40 text with col-6. To allow us to visualize this change better, we will also change the column’s background color to light blue (refer to figure 2.12):

<div class="col-6 col-sm-3">
   <h5>Extra Large</h5>
    <div class="row">
    <div class="col">24x36</div>
    <div class="col">27x39</div>
    <div  style="background: lightblue;">27x40</div>
    </div>
</div>

The col-* classes are defined by Bootstrap using a combination of the flex element’s growth factor property and its maximum width property. For example, col-1 is defined as follows:

.col-1 {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 8.333333%;
  flex: 0 0 8.333333%;
  max-width: 8.333333%;
}
Note that flex is a “shorthand property that sets flex-grow, flex-shrink, and flex-basis” (source: https://developer.mozilla.org/en-US/docs/Web/CSS/flex).
Figure 2.12: Using Bootstrap’s col-* to create viewport size independent columns (example10.html)

Another common use case requiring auto sizing is when one wants to adjust the size of a column based on the column’s content (and not based off of some fixed dimension). For this instance, Bootstrap provides us with the col-*-auto class, where * within this context refers to the breakpoint (sm, md, lg, and xl). Consider this example:

<div class="col-6 col-sm-3">
  <h5>Extra Large</h5>
  <div class="row">
  <div class="col">24x36</div>
  <div class="col">27x39</div>
  <div  style="background: lightblue;">Other            dimensions</div>
  </div>
</div>
Figure 2.12.1: Using Bootstrap’s col-*-auto to automatically adjust the size of a column based on its content (example10.1.html)

Last, but not least,  columns can be forced onto new lines by inserting an element with the w-100 class:

<div class="col-sm-3">
      <h5>Extra Large</h5>
      <div class="row">
          <div class="col">24x36</div>
          <div class="col">27x39</div>
          <div class="w-100"></div>
          <div >27x40</div>
      </div>
</div>

The w-100 class simply sets the width of the element to 100%, forcing it to take up all the available horizontal space. Bootstrap offers a range of classes at a 25% interval: w-25, w-50, w-75, and w-100. Their vertical equivalents are h-25, h-50, h-75, and h-100.

Alignment

The alignment of each row can be customized, irrespective of the alignment of the previous or succeeding rows, that is, using the justify-content-start, justify-content-center, and justify-content-end classes, columns can be left-, right-, and center-aligned. For example, let’s revert to our simple, unnested grid and arrange the grid in such a way that the columns on the first row are center-aligned and align the columns on the second and third row to the right and to the left, respectively. To do so, we simply add the justify-content-start class alongside the row to the first element, and the justify-content-start and justify-content-end classes to the following rows:

<div class="container">
    <h1>Our Print Sizes</h1>
    <div class="row justify-content-center">
      <div class="col-sm-6 col-md-3">Small</div>
      <div class="col-sm-6 col-md-3">Medium</div>
    </div>
    <div class="row justify-content-start">
      <div class="col-sm-6 col-md-3">Large</div>
      <div class="col-sm-6 col-md-3">Extra Large</div>
    </div>
    <div class="row justify-content-end">
      <div class="col-sm-6 col-md-3">Enormous</div>
      <div >Extra Enormous</div>
    </div>
</div>
Columns without margin and padding

You will have noted that columns are padded. To remove the padding, you can simply apply the no-gutters class to any row. The class removes the negative margin from the default row and then the horizontal padding from all immediate children columns to prevent runaway style inheritance.         

Flex Order

To allow you to manually control the order of your elements, Bootstrap provides you with the order-* classes. Using these classes, one can move columns horizontally along their parent row. For instance, perhaps you wanted the Extra Large category to appear before the Large category in certain resolutions. You would simply dynamically apply a specific instance of the order-* class to the appropriate columns. Take this example into consideration:

<div class="container">
     <h1>Our Print Sizes</h1>
     <div class="row">
       <div class="col">Small</div>
       <div class="col">Medium</div>
       <div class="col order-md-2">Large</div>
       <div >Extra Large</div>
     </div>
</div>

As with the col-* classes, the ordering classes consist of responsive and non-responsive versions. The non-responsive equivalent of order-*-* is simply order-* (for example, order-1, order-2, order-3, and so on).

What are wrappers?

In computer programming, wrappers refer to pieces of code that encapsulate or contain another piece of code without, modifying this original code’s function. Exposing this code. For example, given two functions, fn1 and fn2, fn2 is said to wrap fn1 if fn2 immediately calls fn1: fn2() => { fn1() };.
The purpose of wrappers is to either allow the original code to be used in some different way, to add some small auxiliary functionality, or to simply prevent the original code from being exposed.
Bootstrap provides many wrappers for different CSS properties. This allows the original functionality provided by these properties to correctly work across different browsers and different versions of the same browser.

It is important to note that the order classes are merely wrappers for the CSS3 order property (the order property simply specifies the order of an element relative to the other elements that share its container). In the case of the responsive order classes, they are simply accompanied by breakpoints. For example, Bootstrap 4 defines order-1 simply as follows:

.order-1 {
  -webkit-box-ordinal-group: 2;
  -ms-flex-order: 1;
  order: 1;
}

Offsetting

One neat feature of the grid system is how it allows you to create empty space within your row using columns. If you wanted to list the categories and sizes but, for some reason, you wanted to leave the space for Medium empty, in other grid systems you may need to add the empty elements to the markup to get the desired effect. Consider the given example:

<div class="container">
<h1>Our Print Sizes</h1>
<div class="row">
   <div class="col-6 col-sm-3">
      <h5>Small</h5>
      <div class="row">
         <div class="col-sm-4">6x5</div>
         <div class="col-sm-4">8x10</div>
         <div class="col-sm-4">11x17</div>
         &lt;/div>
      </div>
      <div class="col-6 col-sm-3"></div>
      <div class="col-6 col-sm-3">
         <h5>Large</h5>
         <div class="row">
            <div class="col-sm-4">19x27</div>
            <div class="col-sm-4">20x30</div>
            <div class="col-md-4">22x28</div>
         </div>
      </div>
      <div class="col-6 col-sm-3">
         <h5>Extra Large</h5>
         <div class="row">
            <div class="col-md-4">24x36</div>
            <div class="col-md-4">27x39</div>
            <div >27x40</div>
         </div>
      </div>
   </div>
</div>

Observe the following screenshot:

Figure 2.13: Adding spacing between columns (example11.html)

While it has the desired effect, it is adding markup simply for the sake of layout, which isn’t really what we want to do if we can avoid it. Bootstrap allows us to avoid it via the offset classes. The offset classes follow the same convention as the rest of the column classes, offset-*-*. Now, we can remove the empty layout elements and simply add the offset classes to the Large columns. Take a look at the following code:

<div class="col-6 col-sm-3">
   <h5>Small</h5>
   <div class="row">
      <div class="col-sm-4">6x5</div>
      <div class="col-sm-4">8x10</div>
      <div class="col-sm-4">11x17</div>
   </div>
</div>
<div class="col-6 col-offset-6 col-sm-3 offset-sm-3">
   <h5>Large</h5>
   <div class="row">
      <div class="col-sm-4">19x27</div>
      <div class="col-sm-4">20x30</div>
      <div class="col-md-4">22x28</div>
   </div>
</div>
<div class="col-6 col-sm-3">
   <h5>Extra Large</h5>
   <div class="row">
      <div class="col-md-4">24x36</div>
      <div class="col-md-4">27x39</div>
      <div >27x40</div>
   </div>
</div>

Voila! We have the same result with less code, the goal we all aim to achieve.

With containers, rows, and columns, we can now think about our layout more easily. By splitting a viewport into understandable chunks and concepts, the grid system gives us a structure to apply our content.

Comments are closed.

loading...