Search code examples
cssnpmvuejs2overridingbootstrap-5

Custom stylesheet in index.html not overriding Bootstrap 5 installed with NPM


In my Vue 2 project I installed Bootstrap 5.3 using NPM, but my custom CSS stylesheet in the index.html code is not overriding Bootstrap's CSS.

I had no problems when getting Bootstrap via CDN. Also, my custom CSS added directly in the components are correctly overriding Bootstrap's CSS. It's just my global stylesheet in index.html that is being overridden.

My main.js looks like this:

import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'

let Bootstrap = require('bootstrap')
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import Vuex from 'vuex'
import store from './store'
import VueI18n from 'vue-i18n'

Vue.use(Vuex)
Vue.use(VueI18n)

Vue.use(Bootstrap)
Vue.use(BootstrapVue)
Vue.use(IconsPlugin)

new Vue({
    store: store, 
    router,
    i18n,
    beforeCreate() { this.$store.commit('initialiseStore');},
    render: h => h(App),
}).$mount('#app')

And my index.html looks like this:

<!DOCTYPE html>
<html lang="pt-br">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">

    <link rel="stylesheet" href="<%= BASE_URL %>media/css/layout.css?v2">
    <link rel="stylesheet" href="<%= BASE_URL %>media/css/mobile.css?v1">

I was able to make it work by removing my stylesheet reference from index.html and inserting the code below in the App.vue:

<style lang="scss">

@import '/media/css/layout.css';
@import '/media/css/mobile.css';

</style>

But I don't know if calling my custom stylesheet in App.vue is the correct way to do this. And should I still have to reference Bootstrap in index.html if it is installed by NPM? If yes, how can I do this if its folder is in node_modules?


Solution

  • You either use bootstrap through npm or use CDN, you don't have to do both. In either case, it's best to stick to one method throughout your app, for more info about the different ways to use bootstrap, take a look at the official documentation.

    In either case, when importing or including bootstrap CDN, you should take care of CSS precedence and specificity rules. Import or include your most important stylesheets last, as follows:

    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
    
    <!-- your most important rules imported last -->
    <link rel="stylesheet" href="/mycustom.css">
    

    Or using imports as follows:

    import 'bootstrap/dist/css/bootstrap.css';
    
    /* your most important rules imported last */
    import 'mycustomstyles.css';
    

    If you use a hybrid approach .e.g. some styles are imports and others you include in the html, it depends on how the imports are added in the html page. For example, in react, styles imports are added at the end of the <head> element. So generally, they have higher priority than any css stylesheets links defined in the html page itself as they would be insered below it. Specifity is also important, inline styles and !important styles have high priority.

    So, if a boostrap rule is listed !important, it will override your rule even if the stylesheet imported or included after it unless you use !important, too for same target element or use inline styles.

    For more info about specifity, look at this answer