How can I override Bootstrap CSS styles?

Using !important is not a good option, as you will most likely want to override your own styles in the future. That leaves us with CSS priorities.

Basically, every selector has its own numerical 'weight':

  • 100 points for IDs
  • 10 points for classes and pseudo-classes
  • 1 point for tag selectors and pseudo-elements
  • Note: If the element has inline styling that automatically wins (1000 points)

Among two selector styles browser will always choose the one with more weight. Order of your stylesheets only matters when priorities are even - that's why it is not easy to override Bootstrap.

Your option is to inspect Bootstrap sources, find out how exactly some specific style is defined, and copy that selector so your element has equal priority. But we kinda loose all Bootstrap sweetness in the process.

The easiest way to overcome this is to assign additional arbitrary ID to one of the root elements on your page, like this: <body id="bootstrap-overrides">

This way, you can just prefix any CSS selector with your ID, instantly adding 100 points of weight to the element, and overriding Bootstrap definitions:

/* Example selector defined in Bootstrap */
.jumbotron h1 { /* 10+1=11 priority scores */
  line-height: 1;
  color: inherit;
}

/* Your initial take at styling */
h1 { /* 1 priority score, not enough to override Bootstrap jumbotron definition */
  line-height: 1;
  color: inherit;
}

/* New way of prioritization */
#bootstrap-overrides h1 { /* 100+1=101 priority score, yay! */
  line-height: 1;
  color: inherit;
}

In the head section of your html place your custom.css below bootstrap.css.

<link href="bootstrap.min.css" rel="stylesheet">
<link href="custom.css" rel="stylesheet">

Then in custom.css you have to use the exact same selector for the element you want to override. In the case of legend it just stays legend in your custom.css because bootstrap hasn't got any selectors more specific.

legend {
  display: inline;
  width: auto;
  padding: 0;
  margin: 0;
  font-size: medium;
  line-height: normal;
  color: #000000;
  border: 0;
  border-bottom: none;
}

But in case of h1 for example you have to take care of the more specific selectors like .jumbotron h1 because

h1 {
  line-height: 2;
  color: #f00;
}

will not override

.jumbotron h1,
.jumbotron .h1 {
  line-height: 1;
  color: inherit;
}

Here is a helpfull explantion of specificity of css selectors which you need to understand to know exactly which style rules will apply to an element. http://css-tricks.com/specifics-on-css-specificity/

Everything else is just a matter of copy/paste and edit styles.


It should not effect the load time much since you are overriding parts of the base stylesheet.

Here are some best practices I personally follow:

  1. Always load custom CSS after the base CSS file (not responsive).
  2. Avoid using !important if possible. That can override some important styles from the base CSS files.
  3. Always load bootstrap-responsive.css after custom.css if you don't want to lose media queries. - MUST FOLLOW
  4. Prefer modifying required properties (not all).

Link your custom.css file as the last entry below the bootstrap.css. Custom.css style definitions will override bootstrap.css

Html

<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/custom.css" rel="stylesheet">

Copy all style definitions of legend in custom.css and make changes in it (like margin-bottom:5px; -- This will overrider margin-bottom:20px; )


Update 2021 - Bootstrap 4 and Bootstrap 5

There are 3 rules to follow when overriding Bootstrap CSS..

  1. import/include bootstrap.css before your CSS rules (overrides)
  2. use more CSS Specificity (or equal) than the Bootstrap CSS selectors
  3. if any rule is overridden, use !important attribute to force your rules. If you follow rules 1 & 2 this shouldn't be necessary except for when using Bootstrap utility classes which often contain !important as explained here

Yes, overrides should be put in a separate styles.css (or custom.css) file so that the bootstrap.css remains unmodified. This makes it easier to upgrade the Bootstrap version without impacting the overrides. The reference to the styles.css follows after the bootstrap.css for the overrides to work.

<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/styles.css">

Just add whatever changes are needed in the custom CSS. For example:

legend {
  display: block;
  width: inherit;
  padding: 0;
  margin-bottom: 0;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
  white-space: initial;
}

Note: It's not a good practice to use !important in the override CSS, unless you're overriding one of the Bootstrap Utility classes. CSS specificity always works for one CSS class to override another. Just make sure you use a CSS selector that is that same as, or more specific than the bootstrap.css

For example, consider the Bootstrap 4 dark Navbar link color. Here's the bootstrap.css...

.navbar-dark .navbar-nav .nav-link {
    color: rgba(255,255,255,.5);
}

So, to override the Navbar link color, you can use the same selector, or a more specific selector such as:

#mynavbar .navbar-nav .nav-link {
    color: #ffcc00;
}

For example: https://codeply.com/p/FyQapHImHg

When the CSS selectors are the same, the last one takes precedence, which it why the styles.css should follow the bootstrap.css.