Bootstrap 4 Objects, Components, Flexbox, and Layout

In this article by Ajdin Imsirovic author of the book Bootstrap 4 Cookbook, we have three recipes from the book, in which we will be looking at using CSS to override Bootstrap 4 styling and create customized blockquotes. Next. we will look at how to utilize SCSS to control the number of card columns at different screen sizes. We will wrap it up with the third recipe, in which we will look at classes that Bootstrap 4 uses to implement flex-based layouts. Specifically, we will switch the flex direction of card components, based on the screen size.

(For more resources related to this topic, see here.)

Customizing the blockquote element with CSS

In this recipe, we will examine how to use and modify Bootstrap's blockquote element. The technique we'll employ is using the :before and :after CSS pseudo-classes. We will add HTML entities to the CSS content property, and then style their position, size, and color.

Getting ready

Navigate to the recipe4 page of the chapter 3 website, and preview the final result that we are trying to achieve (its preview is available in chapter3-complete/app, after running harp server in the said folder). To get this look, we are using all the regular Bootstrap 4 CSS classes, with the addition of .bg-white, added in the preceding recipe. In this recipe, we will add custom styles to .blockquote.

How to do it...

  1. In the empty chapter3/start/app/recipe4.ejs file, add the following code:
    <div class="container mt-5">
    <h1>Chapter 3, Recipe 4:</h1>
    <p class="lead">Customize the Blockquote Element with CSS</p>
    </div>
    <!-- Customizing the blockquote element -->
    <div class="container">
    <div class="row mt-5 pt-5">
    <div class="col-lg-12">
    <blockquote class="blockquote">
    <p>Blockquotes can go left-to-right. Lorem ipsum dolor sit amet,
    consectetur adipisicing elit. Repellat dolor pariatur,
    distinctio doloribus aliquid recusandae soluta tempore. Vero a,
    eum.</p>
    <footer class="blockquote-footer">Some Guy,
    <cite>A famous publication</cite>
    </footer>
    </blockquote>
    </div>
    <div class="col-lg-12">
    <blockquote class="blockquote blockquote-reverse bg-white">
    <p>Blockquotes can go right-to-left. Lorem ipsum dolor sit amet,
    consectetur adipisicing elit. Quisquam repellendus sequi officia
    nulla quaerat quo.</p>
    <footer class="blockquote-footer">Another Guy,
    <cite>A famous movie quote</cite>
    </footer>
    </blockquote>
    </div>
    <div class="col-lg-12">
    <blockquote class="blockquote card-blockquote">
    <p>You can use the <code>.card-blockquote</code> class. Lorem
    ipsum dolor sit amet, consectetur adipisicing elit. Aliquid
    accusamus veritatis quasi.</p>
    <footer class="blockquote-footer">Some Guy,
    <cite>A reliable source</cite>
    </footer>
    </blockquote>
    </div>
    <div class="col-12">
    <blockquote class="blockquote bg-info">
    <p>Blockquotes can go left-to-right. Lorem ipsum dolor sit amet.
    </p>
    <footer class="blockquote-footer">Some Guy,
    <cite>A famous publication</cite>
    </footer>
    </blockquote>
    </div>
    </div>
    </div>      
  2. In main-03-04.scss, add the following code:
    blockquote.blockquote {
    padding: 2rem 2rem 2rem 4rem;
    margin: 2rem;
    quotes: "\201C" "\201D";
    position: relative;
    }
    blockquote:before {
    content: open-quote;
    font-family: Georgia, serif;
    font-size: 12rem;
    opacity: .04;
    font-weight: bold;
    position:absolute;
    top:-6rem;
    left: 0;
    }
    blockquote:after {
    content: close-quote;
    font-size: 12rem;
    opacity: .04;
    font-family: Georgia, serif;
    font-weight: bold;
    position:absolute;
    bottom:-11.3rem;
    right: 0;
    }     
  3. In main.scss, uncomment @include for main-03-04.scss.
  4. Run grunt sass and harp server.

How it works...

In this recipe, we are using the regular blockquote HTML element and Bootstrap's classes for styling it. To make it look different, we primarily use the following tweaks:

  • Setting the blockquote.blockquote position to relative
  • Setting the :before and :after pseudo-classes, position to absolute
  • In blockquote.blockquote, setting the padding and margin. Also, assigning the values for opening and closing quotes, using CSS (ISO) encoding for the two HTML entities
  • Using Georgia font to style the content property in pseudo-classes
  • Setting the font-size of pseudo-classes to a very high value and giving the font a very high opacity, so as to make it become more background-like
  • With absolute positioning in place, it is easy to place the quotes in the exact location, using negative rem values

Controlling the number of card columns on different breakpoints with SCSS

This recipe will involve some SCSS mixins, which will alter the behavior of the card-columns component. To be able to showcase the desired effect, we will have to have a few hundred lines of compiled HTML code.

This poses an issue; how do we show all that code inside a recipe? Here, Harp partials come to the rescue! Since most of the code in this recipe is repetitive, we will make a separate file. The file will contain the code needed to make a single card. Then, we will have a div with the class of card-columns, and this div will hold 20 cards, which will, in fact, be 20 calls to the single card file in our source code before compilation. This will make it easy for us to showcase how the number of cards in this card-columns div will change, based on screen width.

To see the final result, open the chapter4/complete code's app folder, and run the console (that is, bash) on it. Follow it up with the harp server command, and navigate to localhost:9000 in your browser to see the result we will achieve in this recipe. 

Upon opening the web page as explained in the preceding paragraph, you should see 20 cards in a varying number of columns, depending on your screen size.

Getting ready

To get acquainted with how card-columns work, navigate to the card-columns section of the Bootstrap documentation at https://v4-alpha.getbootstrap.com/components/card/#card-columns.

How to do it…

  1. Open the currently empty file located at chapter4start/app/recipe04-07.ejs, and add the following code:
    <div class="container-fluid">
    <div class="mt-5">
    <h1><%- title %></h1>
    <p><a
    href="https://v4-alpha.getbootstrap.com/components/card/#card-columns"
    target="_blank">Link to bootstrap card-columns docs</a></p>
    </div><!-- /.container-fluid -->
    <div class="container-fluid mt-5 mb-5">
    <div class="card-columns">
    <!-- cards 1 to 5 -->
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <!-- cards 6 to 10 -->
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <!-- cards 11 to 15 -->
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <!-- cards 16 to 20 -->
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    <%- partial("partial/_recipe04-07-samplecard.ejs") %>
    </div>
    </div>
  2. Open the main.scss file, and comment out all the other imports since some of them clash with this recipe:
    @import "recipe04-04.scss";
    @import "./bower_components/bootstrap/scss/bootstrap.scss";
    @import "./bower_components/bootstrap/scss/_mixins.scss";
    @import "./bower_components/font-awesome/scss/font-awesome.scss";
    @import "./bower_components/hover/scss/hover.scss";
    // @import "recipe04-01.scss";
    // @import "recipe04-02.scss";
    // @import "recipe04-03.scss";
    // @import "recipe04-05.scss";
    // @import "recipe04-06.scss";
    @import "recipe04-07.scss";
    // @import "recipe04-08.scss";
    // @import "recipe04-09.scss";
    // @import "recipe04-10.scss";
    // @import "recipe04-11.scss";
    // @import "recipe04-12.scss";
  3. Next, we will add the partial file with the single card code in app/partial/_recipe04-07-samplecard.ejs:
    <div class="card">
    <img class="card-img-top img-fluid"
    src="http://placehold.it/300x250"
    alt="Card image description">
    <div class="card-block">
    <h4 class="card-title">Lorem ipsum dolor sit amet.</h4>
    <p class="card-text">Lorem ipsum dolor sit amet, consectetur
    adipisicing elit. Officia autem, placeat dolorem sed praesentium
    aliquid suscipit tenetur iure perspiciatis sint?</p>
    </div>
    </div>
    If you are serving the files on Cloud9 IDE, then reference the placehold.it images from HTTPS so you don't have the warnings appearing in the console.
  4. Open this recipe's SCSS file, titled recipe04-07.scss, and paste the following code:
    .card-columns {
    @include media-breakpoint-only(sm) {
    column-count: 2;
    }
    @include media-breakpoint-only(md) {
    column-count: 3;
    }
    @include media-breakpoint-only(lg) {
    column-count: 5;
    }
    @include media-breakpoint-only(xl) {
    column-count: 7;
    }
    }
  5. Recompile Sass and start the harp server command to view the result.

How it works…

In step 1, we added our recipe's structure in recipe04-07.ejs. The focus in this file is the div with the class of card-columns, which holds 20 calls to the sample card partial file.

In step 2, we included the SCSS file for this recipe, and to make sure that it works, we comment out the imports for all the other recipes' SCSS files.

In step 3, we made our single card, as per the Bootstrap documentation.

Finally, we customized the .card-columns class in our SCSS by changing the value of the card-columns property using the media-breakpoint-only mixin. The media-breakpoint-only mixin takes the sm, md, lg, and xl values as its parameter. This allows us to easily change the value of the column-count property in our layouts. 

Breakpoint-dependent switching of flex direction on card components

In this recipe, we will ease into using the flexbox grid in Bootstrap 4 with a simple example of switching the flex-direction property. To achieve this effect, we will use a few helper classes to enable the use of Flexbox in our recipe. To get acquainted with the way Flexbox works in Bootstrap, check out the official documentation at https://v4-alpha.getbootstrap.com/utilities/flexbox/ .

Getting ready

To get started with the recipe, let's first get an idea of what we will make. Navigate to chapter8complete/app/ and run harp server. Then, preview the completed recipe at localhost:9000/recipe08-01 . You should see a simple layout with four card components lined up horizontally.

Now, resize the browser, either by changing the browser's window width or by pressing F12 (which will open developer tools and allow you to narrow down the viewport by adjusting the size of developer tools). At a certain breakpoint (), you should see the cards stacked on top of one another. That is the effect that we will achieve in this recipe.

How to do it…

  1. Open the folder titled chapter8/start inside source code. Open the currently empty file titled recipe08-01.ejs inside the app folder; copy the below code a it into recipe08-01.ejs:
    <div class="container">
    <h2 class="mt-5">Recipe 08-01: Breakpoint-dependent Switching of Flex
    Direction on Card Components</h2>
    <p>In this recipe we'll switch DIRECTION, between a vertical (.flex-
    {breakpoint}column), and a horizontal (.flex-{breakpoint}-row) stacking of
    cards.</p>
    <p>This recipe will introduce us to the flexbox grid in Bootstrap 4.</p>
    </div><!-- /.container -->
    <div class="container">
    <%- partial("partial/_card0") %>
    <%- partial("partial/_card0") %>
    <%- partial("partial/_card0") %>
    <%- partial("partial/_card0") %>
    </div>
  2. While still in the same file, find the second div with the class of container and add more classes to it, as follows:
    <div class="container d-flex flex-column flex-lg-row">
  3. Now, open the app/partial folder and copy and paste the following code into the file titled _card0.ejs:
    <div class="p-3" id="card0">
    <div class="card">
    <div class="card-block">
    <h3 class="card-title">Special title treatment</h3>
    <p class="card-text">With supporting text below as a natural lead-in to
    additional content.</p>
    <a href="#" class="btn btn-primary">Go somewhere</a>
    </div>
    </div>
    </div>
  4. Now, run the harp server command and preview the result at localhost:9000/recipe08-01, inside the chapter8start folder. Resize the browser window to see the stacking of card components on smaller resolutions. 

How it works…

To start discussing how this recipe works, let's first do a little exercise. In the file titled recipe08-01, inside the chapter8start folder, locate the first div with the container class. Add the class of d-flex to s div, so that this section of code now looks like this:

<div class="container d-flex">

Save the file and refresh the page in your browser. You should see that adding the helper class of d-flex to our first container has completely changed the way that this container is displayed. What has happened is that our recipe's heading and the two paragraphs (which are all inside the first container div) are now sitting on the same flex row. The reason for this behavior is the addition of Bootstrap's utility class of d-flex, which sets our container to display: flex. With display: flex, the default behavior is to set the flex container to flex-direction: row. This flex direction is implicit, meaning that we don't have to specify it.

However, if we want to specify a different value to the flex-direction property, we can use another Bootstrap 4 helper class, for example, flex-row-reverse. So, let's add it to the first div, like this:

<div class="container d-flex flex-row-reverse">

Now, if we save and refresh our page, we will see that the heading and the two paragraphs still show on the flex row, but now the last paragraph comes first, on the left edge of the container. It is then followed by the first paragraph, and finally, by the heading itself.

There are four ways to specify flex-direction in Bootstrap, that is, by adding one of the following four classes to our wrapping HTML element: flex-row, flex-row-reverse, flex-column, and flex-column-reverse. The first two classes align our flex items horizontally, and the last two classes align our flex items vertically.

Back to our recipe, we can see that on the second container, we added the following three classes on the original div (that had only the class of container in step 1): d-flex, flex-column, and flex-lg-row

Now we can understand what each of these classes does. The d-flex class sets our second container to display: flex. The flex-column class stacks our flex items (the four card components) vertically, with each card taking up the width of the container. 

Since Bootstrap is a mobile first framework, the classes we provide also take effect mobile first. If we want to override a class, by convention, we need to provide a breakpoint at which the initial class behavior will be overridden. In this recipe, we want to specify a class, with a specific breakpoint, at which this class will make our cards line up horizontally, rather than stacking them vertically.

Because of the number of cards inside our second container, and because of the minimum width that each of these cards takes up, the most obvious solution was to have the cards line up horizontally on resolutions of lg and up. That is why we provide the third class of flex-lg-row to our second container. We could have used any other helper class, such as flex-row, flex-sm-row, flex-md-row, or flex-xl-row, but the one that was actually used made the most sense.

Summary

In this article, we have covered Customizing the blockquote element with css, Controlling the number of card columns on different breakpoints with SCSS, and Breakpoint-dependent switching of flex direction on card components. 

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Bootstrap 4 Cookbook

Explore Title