The third way of using Bootstrap styles is utilities. Utilities are a great help when creating layouts. They usually come in the form of atomic classes.
An atomic class
consists of a single property and has a description of the property that the class uses in its name. For example, d-block
refers to the display
property with the value as block
. The overflow-hidden
class refers to the overflow
property with the hidden
value.
The main advantage of using these classes is speed. To interpret these classes, the browser doesn’t have to deal with long selectors with many properties inside to apply to elements. However, this is also a major part of their disadvantage; atomic classes require you to use many classes within HTML, which can affect its readability.
We can divide all utilities in Bootstrap into two main groups:
-
Structural utilities, including classes that affect width/height, display method, indents, and position
-
Design Utilities, including classes affecting color and shadow
As an example for this lesson, we’ll go through the text color utility. It almost completely covers all possible scenarios of text layout on the page, meaning you don’t have to use separate CSS. The other utilities work according to similar principles. All of them you can find in the official Bootstrap documentation.
A feature of the utilities in Bootstrap is the !important
flag inside the CSS code. Although the practice is fred upon as it violates normal CSS cascading, it has a purpose. Utilities are used to override the current CSS and add a new one. Since you can’t guarantee that custom CSS code will be above utilities, you need to use !important
to override styles. This must be taken into account when writing your CSS.
If you use the !important
, flag inside the custom selector, there’s a chance that the utilities associated with this property won’t work. This would break the standard behavior of the framework. Consequently, we must use the !important
flag when creating custom utilities. Other classes mustn’t use this flag.
Colors
In the lesson on components, we saw that Bootstrap has a color map that allows you to create classes based on colors. The same colors are available for text. we create the following classes after compilation:
<p class="text-primary">Primary</p>
<p class="text-secondary">Secondary</p>
<p class="text-success">Success</p>
<p class="text-danger">Danger</p>
<p class="text-warning">Warning</p>
<p class="text-info">Info</p>
<p class="text-light">Light</p>
<p class="text-dark">Dark</p>
By changing the $theme-colors
array, you can add any custom colors you want:
$theme-colors: (
"brand": #66bb6a
);
After compilation, a new .text-brand`
class will be available:
In addition to adding colors for text, changing $theme-colors
will create new classes for other utilities and components, such as .bg-
, .border-
, alert-*
, and so on. It will increase the size of the resulting CSS file. If the color isn’t part of your brand and you need it for some elements, it’s better to add it to the $colors
array. After compilation, these colors will be available as global CSS variables.
Creating custom utilities
When you’re designing layouts, there aren’t always enough default utilities. Developers often add the necessary code to CSS files, but this isn’t good practice. We can create any utility using Bootstrap, which means not deviating from the framework and accelerating the creation of custom utilities.
Create a utility that allows you to change the cursor type when hovering over an HTML element. To begin with, it’s worth determining which classes we need as utility values. Most websites use the pointer
cursor. Let’s also create default
and none
.
We’ll get the following classes:
-
cursor-pointer
-
cursor-default
-
cursor-none
Starting with Bootstrap 5, all utilities are generated automatically. To this end, we have the necessary values for the variable $utilities
. After compiling all the source files, the utilities will appear in the main CSS file. To get a better idea, it’s worth looking at the existing utilities.scss
. It contains all the utilities that Bootstrap generates by default. As an example, let’s look at the justify-content
utility:
"justify-content": (
responsive: true,
property: justify-content,
values: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
evenly: space-evenly,
)
)
At first, seeing so many different values may be confusing or scary, but once you create your utility, you’ll see how much easier this API makes life for developers. The array keys we represent here:
-
responsive
— do you want to create utilities for different screen resolutions? If responsive istrue
, the utilities will have the prefixes-sm-
,-md-
,-lg-
, and so on -
property
— the name of the CSS property. In this case, it’sjustify-content
-
values
— the values the property can take
There are several variations on how to set values here. For the justify-content
property, we also specify aliases — alternative names, so we can get readable class names when generating utilities. Let us compare:
/* No aliases specified */
.justify-content-space-around {
justify-content: space-around;
}
/* Alias specified */
.justify-content-around {
justify-content: space-around;
}
In addition to these keys, there are several others:
-
class
— alternative name for the class. The default name for the class is the name of the utility itself. It can sometimes be quite cumbersome:
"justify-content": (
responsive: true,
property: justify-content,
class: jc,
values: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
evenly: space-evenly,
)
)
.jc-around {
justify-content: space-around;
}
-
state
— the ability to add utilities for pseudoclasses, such as:hover
and:focus
:
"justify-content": (
responsive: true,
property: justify-content,
state: hover,
values: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
evenly: space-evenly,
)
)
.justify-content-around-hover:hover {
justify-content: space-around;
}
Only the property
and values
keys are mandatory. Other keys are used based on the developer’s needs.
Creating a cursor
utility is now a simple task. We add the new utility to the $utilities
variable and compile the project. We create the utility through the map-merge
function:
$utilities: map-merge(
$utilities,
(
"cursor": (
property: cursor,
class: cursor,
values: pointer grab help progress,
),
)
);
After compilation, we add the following classes to the main CSS file:
.cursor-pointer {
cursor: pointer !important;
}
.cursor-grab {
cursor: grab !important;
}
.cursor-help {
cursor: help !important;
}
.cursor-progress {
cursor: progress !important;
}
Do it yourself
Create an opacity
utility with values:
*0
*0.25
*0.5
*0.75
*1
Add the possibility of implementation at different resolutions, meaning you should generate classes for prefixes -sm-
, -md-
, and so on. Make the utility work on hover over the element using the hover
state.
Recommended materials
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
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.