Overriding BS styles

Tags

Lesson contents

When the standard styles don't fit

Sometimes the standard BS styles won't fit your site. Maybe you want to change just one thing. Maybe you want to change all of the colors and fonts.

You can either:

  • Override BS styles yourself
  • Use a theme that someone else has created

In this lesson, we'll talk about the first one. We'll cover the other option later.

Bootstrap is complicated, and changing it can be quite difficult. So, you should only do it yourself when you want to make simple changes.

Overriding CSS

The key is how CSS lets one stylesheet override another. We'll just talk about one aspect of overriding here: rule order.

A simple example. Say we have this HTML. It's not BS, just regular HTML:

  • <!doctype html>
  • <html lang="en">
  •   <head>
  •     <meta charset="utf-8">
  •     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  •     <title>Doggos</title>
  •     <link rel="stylesheet" href="small-stuff.css">
  •     <link rel="stylesheet" href="big-stuff.css">
  •   </head>
  •   <body>
  •     <h1>Doggos</h1>
  •     <p class="true-dat">Doggos are the <em>best!</em></p>
  •   </body>
  • </html>

There are two stylesheets, small-stuff.css, and big-stuff.css:

  • <link rel="stylesheet" href="small-stuff.css">
  • <link rel="stylesheet" href="big-stuff.css">

Both CSS files define the same class: true-dat. Here's what's in small-stuff.css:

  • .true-dat {
  •   font-size: 70%;
  • }

Here's what's in big-stuff.css:

  • .true-dat {
  •   font-size: 140%;
  • }

In the HTML, true-dat is used like this:

  • <p class="true-dat">Doggos are the <em>best!</em></p>

So, there are two CSS files that have rules for the same class, true-dat.

Will the text be small, like this...

Small text

... or will it be big, like this?

Big text

The answer depends on the order the stylesheets are listed in. Here's what we have.

  • <link rel="stylesheet" href="small-stuff.css">
  • <link rel="stylesheet" href="big-stuff.css">

Rules in later sheets override rules in earlier sheets. So, the rules in big-stuff.css override the rules in small-stuff.css. The rule in big-stuff.css is:

  • .true-dat {
  •   font-size: 140%;
  • }

So the page looks like:

Big text

Ray
Ray

So the second one wins?

Right. Think of it this way. Here's the HTML again:

  • <link rel="stylesheet" href="small-stuff.css">
  • <link rel="stylesheet" href="big-stuff.css">

The browser applies the rules from small-stuff.css first. So the font size is set to 70%.

Then the browser applies the rules from big-stuff.css. The rule in big-stuff.css overrides the rule in small-stuff.css. The font size is set to 140%.

Overriding some properties

Let's change small-stuff.css to this:

  • .true-dat {
  •   font-size: 70%;
  •   border: 4px black dashed;
  •   padding: 0.5rem;
  • }

So there's more than just font-size being set. There's a black dashed border, and some padding.

Let's leave big-stuff.css alone:

  • .true-dat {
  •   font-size: 140%;
  • }

big-stuff.css just has one property. So, what happens?

Remember that small-stuff.css gets applied first, because it's listed first.

  • <link rel="stylesheet" href="small-stuff.css">
  • <link rel="stylesheet" href="big-stuff.css">

The browser reads small-stuff.css, that sets several properties for true-dat. Then it reads big-stuff.css, with overrides just one of those properties.

The browser ends up with this:

  • .true-dat {
  •   font-size: 140%; <- Overridden
  •   border: 4px black dashed;
  •   padding: 0.5rem;
  • }

The result is:

Font size overridden

Ray
Ray

Oh, OK. The browser takes the first stylesheet, and then, like, merges in the next one.

Yes! That's a good way to think of it.

Changing the border style

OK, here's small-stuff.css again.

  • .true-dat {
  •   font-size: 70%;
  •   border: 4px black dashed;
  •   padding: 0.5rem;
  • }

Let's change big-stuff.css to this:

  • .true-dat {
  •   font-size: 140%;
  •   border-style: solid;
  • }

So we have this first...

  • border: 4px black dashed;

... which sets three properties of the border. Then we merge in...

  • border-style: solid;

That rule changes one of the border properties. Here's the result:

Solid border

What does all this mean? We can change the individual properties of styles, by overriding those properties.

Changing BS

We can override Bootstrap's styles, as well as our own.

In the last lesson, you saw what the class text-primary does to color.

  • <p>
  •   This is the <span class="text-primary">text-primary</span> class.
  • </p>

This is the text-primary class.

But...

Adela
Adela

It's blue. Links are blue. The user would expect to be able to click on blue things.

It's a bad idea to use blue for text that isn't clickable.

Let's make primary-text, say, brown. Why brown? Just because.

We'll make a new file called overrides.css, and put this is in it:

  • .text-primary {
  •   color: brown;
  • }

OK, now we'll make a new HTML file from our standard BS template, but we'll add a link to our new stylesheet:

  • <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
  • <link rel="stylesheet" href="overrides.css">

The browser will load in bootstrap.min.css, and then merge overrides.css. So the properties in overrides.css will override those in bootstrap.min.css. Since overrides.css has this...

  • .text-primary {
  •   color: brown;
  • }

... then primary-text should be brown, and not blue.

Here's the HTML we'll use to test it:

  • <h1>Doggos</h1>
  • <p>Doggos are the <em><span class="text-primary">best</span>!</em></p>

Recall that em means emphasis, rendered as italics.

OK, ready? We look at the output, and see:

Argh! Didn't work!

Wait, what?! It didn't work! The text should be brown, not blue!

Hmmm... OK, I'll need some help here. What should I do, when CSS doesn't work the way I think it should?

Adela: Aha!
Adela

A while back, we used the dev tools to check out some styles. Would that help?

Maybe. Let's give it a try.

I'll look at the page, and press F12, to show dev tools.

Then I'll click the choose-element button.

Choose element button

Now, I'll click on the element I want to inspect, the one with the text-primary class that we're trying to override.

Choosing an element

Dev tools shows the element, and the CSS that styles it. You might need to mess around with the dev tools display to see this.

After clicking element

Let's focus in on the rules that affect text-primary:

Rules that affect <code>text-primary</code>

There are two of them, one from overrides.css, and the other from a BS file.

Our brown rule has a line through it! Why?

You can see the problem in BS's rule. It has the modifier !important. That modifier tells the browser to use the blue color, even if something else tries to override.

Argh!

But wait. What if we added !important to our rule as well? Blue is important, and brown is important, and the rule for brown comes after the rule for blue, because of the order of the stylesheets in the head of the page. What happens?

Got it!

Yay! It worked! Our brown rule overrode the blue one.

So, we wanted to override a BS class. We made our own CSS file, with overrides. We linked the CSS file into the HTML page, after BS's CSS file.

It didn't work. We used the browser's dev tools to figure out why. Now we are happy. W00f!

Mix-in your own styles

You can add your own styles, in addition to those created by BS. For example, here's some HTML:

  • <h1>Doggos</h1>
  • <p>Doggos are the <em>best!</em></p>
  • <div class="border p-2 m-2">
  •   <p class="lead">Reasons to love doggos</p>
  •   <ul>
  •     <li>Always glad to see you</li>
  •     <li>Fun to play with</li>
  •     <li>Cuddly</li>
  •     <li>Happy</li>
  •   </ul>
  •   <p>And many more!</p>
  • </div>

It looks like this:

Before mix-in

Suppose you wanted the box to stand out, by setting the background color:

New background color

You could add your own class to the element you want to style:

  • ...
  • <div class="border p-2 m-2 highlight-box">
  •   <p class="lead">Reasons to love doggos</p>
  •   ...
  • </div>

highlight-box isn't a BS class. It's just something I made up.

To define the class, I make my own stylesheet. I'll call it mix-in.css, but it could be anything. Then, in the HTML file, I'll add a link to it, after the link to the BS stylesheet:

  • <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
  • <link rel="stylesheet" href="mix-in.css">

Now, I'll add the rule for highlight-box to mix-in.css:

  • .highlight-box {
  •   background-color: lightgoldenrodyellow;
  • }

So:

  • The browser loads in the BS stylesheet: <link ... href=".../bootstrap.min.css">
  • The browser loads in my stylesheet: <link ... href="mix-in.css">
  • mix-in.css defines the class highlight-box.
  • A div uses highlight-box, along with BS classes: <div class="border p-2 m-2 highlight-box">
Georgina
Georgina

If I was overriding some BS classes, and making my own classes, they could all go in the same file, right?

Sure. Here's one stylesheet with the text color override from before, and highlight-box:

  • .text-primary {
  •   color: brown !important;
  • }
  • .highlight-box {
  •   background-color: lightgoldenrodyellow;
  • }

Up next

Let's see how we can use a theme file to change colors and fonts.