Testing

webTiger Logo Wide

Modifying Bootstrap Styles – The Right Way

ASP.NET MVC web projects include the Bootstrap framework by default. If the styles aren’t to your liking ‘out-of-the-box’ then you can customise the look and feel quite easily by hacking the Bootstrap CSS file directly, but this isn’t necessarily the best way to go.

NOTE: This article was written for Bootstrap 3. Newer versions of the API may behave slightly differently.

I’ll be honest. When I initially started developing MVC applications I didn’t like the default settings for font size, margins, padding, etc. that Bootstrap used whenever I created a new MVC project in Visual Studio. Rather than being bothered to learn yet another web framework, having just spent a while learning MVC, I opted to summarily delete Bootstrap and continue to use my own, seasoned, set of CSS styles from the myriad of ASP.NET web apps I’d developed in the past. I also didn’t fancy digging through the reams of styles Bootstrap offered to work out how to customise my look and feel without properly learning about the framework first.

Over time I got a chance to read up on Bootstrap a little more, and decided to integrate it into my projects after all. As it turns out, it has made my development activities more straightforward as a lot of the large display versus mobile display layout issues, not to mention cross-browser compatibility, are taken care of by Bootstrap more elegantly than my own home baked and constantly evolving style-sets.

Unfortunately, the only guidance Microsoft offers (in the project_readme file) when you create a new project is to download alternative Bootstrap theme files from an external website and do some tweaks to the bundles being used to implement the new theme. With that approach, you are limited to implementing a complete set of style changes and to the version of Bootstrap that was being used at the time. You also get caught up modifying bundle names, etc.

I wanted my changes to be finer grain, and for them to survive updates to my Bootstrap version, so I decided to investigate how to selectively override individual styles instead.

As it turns out, Microsoft have demonstrated the best approach for doing this as they already override a few styles in the Site.css file that is created by the project. If you look at the default set of styles in this file, it already customises the Bootstrap styles for body, body-content and (annoyingly) limits the maximum width of input, select and textarea elements to 280px.

If you have read any of the documentation on Bootstrap CSSComponents and JavaScript then you’ll know the framework supports flexible display layouts for different device screen sizes. The default override in Main.css to globally limit the input, select and textarea element widths seems to immediately go against this design so it is normally the first thing I change.

Bootstrap uses pre-defined relative screen size identifiers to make handling layouts easier, with values of screen-sm-min, screen-md-min and screen-lg-min being defined for minimum screen widths of 768px, 992px and 1200px respectively. Armed with this information you can customise your styles based not only on style name but also on the size of the display device being targeted.

For example, in the Main.css file we could change the input, select and textarea overrides to make them more flexible (the original style defined in the file would apply to screen sizes of less than 768px in this case):

input, select, textarea {
    max-width: 280px;
}

@media (min-width: @screen-sm-min) {
    input, select, textarea {
        max-width: 400px;
    }
}

@media (min-width: @screen-md-min) {
    input, select, textarea {
        max-width: 600px;
    }
}

@media (min-width: @screen-lg-min) {
    input, select, textarea {
        max-width: 900px;
    }
}Code language: CSS (css)

Once you familiarise yourself with Bootstrap CSS, overriding the styling exactly how you want is fairly straightforward. For example, lets say we wanted to update the colour scheme we were using. We are using inverse nav-bar and want it to be borderless with a dark-red background colour and want the text to turn white when a mouse-over (hover) occurs. We also want the jumbotron to have less top padding and to have a beige background and we want to customise some of the button and label colours. Finally, we want to make the title region (header) of modal dialogs bold. To do this we can just add some overrides to the Main.css file:

.navbar-inverse {
    background-color: darkred;
    border: none;
}

.navbar-inverse .navbar-nav > .active > a,
.navbar-inverse .navbar-nav > .active > a:hover,
.navbar-inverse .navbar-nav > .active > a:focus {
    color: #000000;
}

.jumbotron {
    background-color: beige;
    padding-top: 10px;
}

.btn-default {
    color: white;
    background-color: lightcoral;
}

.btn-primary {
    color: white;
    background-color: darkred;
}

.label-default {
    color: white;
    background-color: lightcoral;
}

.label-primary {
    color: white;
    background-color: darkred;
}

.modal-header {
    font-weight: bold;
}Code language: CSS (css)

As you can see, by customising Bootstrap in this way we achieve bespoke styling and layout while continuing to be able to harness the flexibility and feature-set offered by the framework. Even better, because we aren’t modifying the Bootstrap files directly, our customisations survive Bootstrap version updates and we aren’t reliant on the timescales another developer may work to when updating their style-sheets!

Once you familiarise yourself with the framework’s structure and CSS style names, creating completely bespoke looking websites using Bootstrap is easy.

Remember, the reference to the CSS file with the changes that override Bootstrap must appear AFTER the bootstrap CSS file references in the HTML page.

Here is a more comprehensive set of classes we may want to override…

body {
    padding-top: 40px; /* only required if using a fixed navbar that could obscure some content - height dependent on layout! */
    padding-bottom: 20px;
}

/* Set padding to keep content from hitting the edges */
.body-content {
    padding-left: 15px;
    padding-right: 15px;
}

/* Let the print view use all the available space on the page! */
@media print {
    body {
        margin: 0;
        padding: 0;
        width: 100%;
    }
}

/* Stop default behaviour of truncating terms that are too long to fit in LHS column. */
.dl-horizontal dt {
    white-space: normal;
}

/* Remove x-axis padding from collapsed navbars. */
.navbar-collapse {
    padding-left: 0;
    padding-right: 0;
}

/* Customisations of the reversed navbar colour scheme. */
.navbar-inverse {
    background-color: red;
    border: none;
}
.navbar-inverse .navbar-brand {
    color: red;
}

.navbar-inverse .navbar-nav > .active > a,
.navbar-inverse .navbar-nav > .active > a:hover,
.navbar-inverse .navbar-nav > .active > a:focus {
    color: darkred;
    background-color: #ffffff;
}

/* Alter padding on the default nav list-item with embedded anchor tag styling. */
.nav > li > a {
    padding: 5px 5px;
}

/* Customise the widths of form input elements based on viewport size, since they're 100% wide by default */
/* NOTE: MS Visual Studio projects set the first set of widths - adding viewport specific overrides is also useful to fix the layout issues introduced by that! */
input,
select,
textarea {
    max-width: 250px;
}

@media (min-width: @screen-sm-min) {
    input,
    select,
    textarea {
        max-width: 375px;
    }
}

@media (min-width: @screen-md-min) {
    input,
    select,
    textarea {
        max-width: 600px;
    }
}

@media (min-width: @screen-lg-min) {
    input,
    select,
    textarea {
        max-width: 900px;
    }
}

/* Override the default table styling. */
th {
    font-weight: bold;
    font-size: medium;
}

td {
    font-size: small;
    vertical-align: middle;
}

/* override default jumbotron styling. */
.jumbotron {
    background-color: lightgreen;
}

/* override bootstrap label styles */
.label {
    font-size: medium;
    vertical-align: middle;
}

/* override bootstrap alert styles (alert needs to be after label!) */
.alert {
    font-size: small;
    padding: 5px;
    margin-bottom: 5px;
}

/* Some customisations for modal popups for medium and large displays only. */
@media screen and (min-width: @screen-sm-min) {
    .modal:before {
        display: inline-block;
        vertical-align: middle;
        content: " ";
        height: 100%;
    }
}

.modal-dialog {
    display: inline-block;
    text-align: left;
    vertical-align: middle;
}

.modal-header {
    font-weight: bold;
}

/* Some tweaks to the layouts of input groups and list groups. */
.input-group {
    padding-bottom: 5px;
    max-width: 500px;
}

.list-group {
    margin-bottom: 5px;
}

.list-group-item {
    padding: 5px;
}Code language: CSS (css)