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, creating your own components is a simple operation. Let’s create our own quotation component, whose final appearance will look like this:

Before you start creating styles, you need to decide which elements will be used in the component and where modifiers will be needed. Structurally, the component can be broken down into the following parts:

  • Main Wrap. The component is called a citation. The class will be chosen 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 as colors

  • Text Wrap. This is a block with a quote body. Although this wrapper may not always be necessary (you won’t need it for a single line of text), with complex quotes it’s better for it to have its own wrapper. You can use the .citation-body class as the class

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

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. This means that the styles shouldn’t be tied to the tags.

The second step in creating the component is to create the file structure. In Bootstrap, each component is stored in a separate file. You also need to create a separate file, where Bootstrap and the component itself will be connected. We’ll call this file custom.scss. General view of the file structure:

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

In the custom.scss file, 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 own styles for quotes, and there are four variables for this in the \_variables.scss file. They can be used when developing a component. This will help maintain the continuity of our component 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)
}

To create quotation marks, we use the ::before pseudo-element, which creates a new element immediately after opening a tag with the .citation class. Inside the pseudo-element we use a perfectly positioned element with the Times New Roman font. 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 quote container is ready. Now you can move on to creating styles for the .citation-footer. You may notice that the styles for .citation-body are missing. The reason for this is that all necessary styles will be inherited from the parent .citation block. In the future, this wrapper can be used to specify Bootstrap utility classes, which we’ll look at in a later lesson.

The task of the footer is to specify the slant of the font and set the border at the top along with all the indents. Since the author of a quote is always specified in a font smaller than the quote itself, we’ll 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;
  }
}

The main layout of the component is finished. 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 compilation:

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

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

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

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


Hexlet Experts

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
Layout Designer icon
Profession
Under development beginner
Layout with the latest CSS standards
start anytime 5 months

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.