Overriding BS styles

Multiple choice

You have a stylesheet that you're not allowed to change. You have an HTML page that uses the stylesheet, but you want to make some of the styles different for that page. What's the best solution?

Saving
A

Change the stylesheet anyway.

B

Make a copy of the stylesheet, with a different name. Edit that one.

C

Make a separate stylesheet, that overrides just the styles you want to change.

D

Rebuild the original stylesheet from scratch.

Not graded. So why do it?

Lesson contents

When the standard styles don't fit

Occasionally, the standard BS styles won't fit your site. Maybe you want to change just one thing. Perhaps you would like to change all 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%;
  • }

Both rules are about the same property of true-dat: font-size. The rules conflict.

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%;
  • }

The page looks like:

Big text

Ray
Ray

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;
  • }

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.

Exercise

Exercise

Override styles

Make an HTML file with exactly this code. Change nothing:

  • <!doctype html>
  • <html lang="en">
  •     <head>
  •         <meta charset="utf-8">
  •         <title>Doggos</title>
  •         <link rel="stylesheet" href="base-styles.css">
  •         <link rel="stylesheet" href="overrides.css">
  •     </head>
  •     <body>
  •         <h1>Doggos</h1>
  •         <p>Are doggos the best?</p>
  •         <p class="highlight-content">Yes, doggos are the best!</p>
  •         <p>Are goats the best?</p>
  •         <p class="highlight-content">No. Goats are good, but doggos are the best.</p>
  •     </body>
  • </html>

Put this code in base-styles.css. Change nothing:

  • body {
  •     font-family: sans-serif;
  • }
  • .highlight-content {
  •     margin: 2rem;
  •     font-weight: bold;
  • }

Create your own file, overrides.css. It should make the page look like:

Output

The page background color is cornsilk. The blue border color is lightblue. The color inside the borders is lightgoldenrodyellow.

Upload the files to your server. Submit the URL, as usual.

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... what's the problem?

Adela
Adela

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

Right. 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. 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!

Hmm... 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 show 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 (our file), and the other from a BS file. (The BS CSS file is actually a merge of several smaller CSS files, one of which is _text-emphasis.scss.)

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 styles

We just changed one of BS's styles. You can add your 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 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?

Good question. Yes, you would. Here's one stylesheet with the text color override from before, and highlight-box:

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

Exercise

Exercise

Override Bootstrap styles

Make an HTML file with this exact HTML. Change nothing:

  • <!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 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">
  •     </head>
  •     <body>
  •     <div class="container">
  •         <div class="row">
  •         <div class="col">
  •             <h1>Doggos</h1>
  •             <p class="lead">Who's the best?</p>
  •             <p>Doggos are the <em>best!</em></p>
  •             <p>Here's one now!</p>
  •             <p class="m-4"><img class="border" src="goat.jpg" alt="Goat"></p>
  •             <p class="text-warning">Oops. That's a goat.</p>
  •             <p>Let's try that again.</p>
  •             <p class="m-4"><img class="border" src="doggo.jpg" alt="Doggo"></p>
  •             <p><em>That's</em> a doggo!</p>
  •         </div>
  •         </div>
  •     </div>
  •     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
  •     </body>
  • </html>

Grab some images of your own to use.

Create your own overrides.css. Make the page look like:

Output

Submit the URL of your page, as usual.

Up next

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