Register to get access to free programming courses with interactive exercises

Creating a custom component Bootstrap 5: Layout basics

Once you understand how Bootstrap works, working with components is easy. Let us create our quotation component, whose final appearance will look like this:

Before creating styles, you should decide which elements we use in the component and where we need modifiers.

Structurally, we can break a component into the following parts:

  • Main Wrap. The component is called a citation. We choose the class accordingly. Quote blocks should have different design options, allowing you to change the background and color of the text. The values from the variable $theme-colors will be used for colors

  • Text Wrap. It is a block with a quote body. This wrapper may not be necessary for a single line of text, so it should have its wrapper with complex quotes. You can use the .citation-body as a class

  • Wrapping for the author. In addition to the name, it creates a border at the top to separate the parts of the component. This area can also have citation links, so we can call the block .citation-footer without being tied to the author

Let us create one basic markup for the component:

<blockquote class="citation citation-success">
  <div class="citation-body">The main goal is not to find errors, but to find the conditions under which the code continues to work</div>
  <div class="citation-footer">
    <cite>Kirill Mokevnin</cite>
  </div>
</blockquote>

Now we have a semantic layout for quotes, but the component should work with any structure. It means that we should not bind the styles to the tags.

The second step in constructing the component is to create the file structure. In Bootstrap, we store each component in a separate file.

You also need to create a separate file where we connect Bootstrap and the component. We will call this file custom.scss. Let us overview the file structure:

my-project/
├── scss/
│   ├── _citation.scss
│   └── custom.scss
├── style/
│   └── style.css
├── index.html

In the custom.scss file, we connect Bootstrap and the Citation component:

@import "../node_modules/bootstrap/scss/bootstrap";
@import "./citation";

Now you can move on to the layout of the quote block. Bootstrap has its styles for quotes. There are four variables for this in the \_variables.scss file. We can use it when developing a component. It will help maintain the continuity and standard quote styles:

$blockquote-margin-y:         $spacer !default;
$blockquote-font-size:        $font-size-base * 1.25 !default;
$blockquote-footer-color:     $gray-600 !default;
$blockquote-footer-font-size: $small-font-size !default;

To create indents, use the $spacers array, which has the following structure:

$spacer: 1rem !default;
$spacers: map-merge(
  (
    0: 0,
    1: ($spacer * .25),
    2: ($spacer * .5),
    3: $spacer,
    4: ($spacer * 1.5),
    5: ($spacer * 3)
  ),
  $spacers
);

All of these values will help us create the structure of the .citation block:

.citation {
  position: relative;

  display: block;

  margin: 0;
  padding: map.get($spacers, 5) map.get($spacers, 4) map.get($spacers, 3);

  color: $blockquote-footer-color;
  font-size: $blockquote-font-size;

  border-radius: $border-radius; // .25rem
  @include box-shadow($box-shadow); // 0 0.5rem 1rem rgba(0, 0, 0, 0.15)
}

Let us try to create quotation marks. We use the ::before pseudo-element, which creates a new element immediately after opening a tag with the .citation class. We use a perfectly positioned element with the Times New Roman font inside the pseudo-element. To do this, create a variable called $font-family-serif in the custom.scss file:

$enable-shadows: true; // enable the box-shadow mixin
$font-family-serif: "Times New Roman", Times, serif;

@import "../node_modules/bootstrap/scss/bootstrap";
@import "./citation";

Now everything is ready for us to create a pseudo-element:

.citation {
  position: relative;

  display: block;

  margin: 0;
  padding: map.get($spacers, 5) map.get($spacers, 4) map.get($spacers, 3);

  color: $blockquote-footer-color;
  font-size: $blockquote-font-size;

  border-radius: $border-radius;
  @include box-shadow($box-shadow);

  &::before {
    position: absolute;
    top: -#{map.get($spacers, 4)};

    font-size: $display1-size; // 6rem
    font-family: $font-family-serif;

    content: '“';
  }
}

The basic layout of the citation container is complete. Now you can move on to creating styles for the .citation-footer. You may notice that the .citation-body styles are missing because we inherited them from the parent .citation block. In the future, we can use this wrapper to specify Bootstrap utility classes, which we will look at in a later lesson.

The task of the footer is to specify the slant and to set the top margin and all indents. Since we always specify the author of a blockquote in a smaller font than the blockquote, we use the `$blockquote-footer-font-size' variable:

.citation {
  position: relative;

  display: block;

  margin: 0;
  padding: map.get($spacers, 5) map.get($spacers, 4) map.get($spacers, 3);

  color: $blockquote-footer-color;
  font-size: $blockquote-font-size;

  border-radius: $border-radius;
  @include box-shadow($box-shadow);

  &::before {
    position: absolute;
    top: -#{map.get($spacers, 4)};

    font-size: map.get($display-font-sizes, 1);
    font-family: $font-family-serif;

    content: '“';
  }

  & > &-footer {
    margin: $spacer 0 0;
    padding-top: map.get($spacers, 2);

    font-size: $blockquote-footer-font-size;
    font-style: italic;

    border-top: 1px solid;
  }
}

We finished the main layout. If we use the component we’ve created, we’ll get the following block:

The last task is to create modifier classes that will add a background color to quotations. In addition, these classes must override the color of the text and make it white to create the correct contrast.

With the $theme-colors array, you can go through all colors and add the background-color property. The $theme-colors array has the following values:

$theme-colors: map-merge(
  (
    "primary":    $primary,
    "secondary":  $secondary,
    "success":    $success,
    "info":       $info,
    "warning":    $warning,
    "danger":     $danger,
    "light":      $light,
    "dark":       $dark
  ),
  $theme-colors
);

Since this is an associative array, you can use the @each function to go through it:

@each $color, $value in $theme-colors {
  .citation-#{$color} {
    color: $white;

    @include gradient-bg($value);
  }
}

The following styles will appear as a result of the compilation:

.citation-primary {
  color: #fff;
  background-color: #007bff;
}

.citation-secondary {
  color: #fff;
  background-color: #6c757d;
}

/* And so on. A total of 8 classes */

We have finished developing the component. We can refine it by creating additional modifier classes or adapting it to different screen resolutions. The principle for creating these add-ons won’t be much different from what we’ve discussed in this lesson.


Do it yourself

Create a quotes component. Add the ability to select different box-shadow options.


Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs
profession
Layout with the latest CSS standards
5 months
from scratch
under development
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.