3

Context: I have a Vue CLI project, consisting of two main parts: 1) what the customers see and 2) what an administrator sees. The customer part is using Bootstrap CSS and the other part is using Vue Material. Even though I am planning to rewrite the Vue Material part to Vuetify, the problem will most likely persist.

The problem: The Bootstrap CSS is conflicting with the Vue Material CSS. When the Bootstrap CSS is applied to the Vue Material section, it looks messed up. The other way around too; when the Vue Material CSS is applied to the Bootstrap section, it looks messed up.

Is there any way I could make this work?

This Vue project used to be encapsulated inside a Laravel project, making heavy use of Laravel Mix. I could then use the mix file to compile all the Bootstrap CSS into 1 bundle. This bundle would be referenced in the index page using this line:

<link rel="stylesheet" href="bootstrap-bundle.css" id="bootstrap-stylesheet">
<link rel="stylesheet" href="vue-material-bundle.css" id="vue-material-stylesheet">

Using two layout components in Vue, I could then toggle the stylesheets in like this:

// The Bootstrap layout component:
created() {
  document.getElementById('bootstrap-stylesheet').disabled = false;
  document.getElementById('vue-material-stylesheet').disabled = true;
}


// The Vue-Material layout component:
created() {
  document.getElementById('bootstrap-stylesheet').disabled = true;
  document.getElementById('vue-material-stylesheet').disabled = false;
}

It may not be a pretty solution, but it works. Also works in most browsers.

However, I now use Vue CLI instead of Laravel & Laravel Mix. This means I cannot name the generated output as easily anymore.

I have already tried using the CSS deep selector: /deep/ & >>>. But this does not fully work since bootstrap also sets styles to the :root, html & body elements. So when using the deep selector in scoped CSS, those styles are not applied because the end result would be something like this:

.customers-container {
    body {
        // bootstrap adds style to the body
    }
}

The above does not work because the body is not a child of the customers-container but the other way around.

I feel like there might be a solution using bundle names or chunk names or something else from Webpack or Vue config. But my Webpack knowledge is not enough to work this out myself and I cannot seem to find the answer online.

OneBigOwnage
  • 428
  • 5
  • 10

1 Answers1

0

First thing that comes to my mind is just downloading the bootstrap and vue-material stylesheets. Then you can try doing the following, grab the bootstrap stylesheet and wrap it in something like:

.administrator-view {

/// the complete bootstrap stylesheet

}

Do the same with the vue-material but with a customer class .customer-view

Then you can add one of those classes at the HTML or body element whenever you switch between the views.

Don't forget to include both stylesheets!

EDIT: Did a search on the site, you should check Limit the scope of bootstrap styles

José Gazzano
  • 112
  • 1
  • 5
  • The problem is that bootstrap also adds stuff to the `html` & `body` elements. I have edited my question to make this clear. – OneBigOwnage Feb 28 '19 at 15:05
  • What do you mean? Are you removing the CSS from the index.html? If you have the entire bootstrap styles scoped in one of those classes and then add the class to the HTML tag you shouldn't have much problem. Worst case you'll need to search the bootstrap stylesheet and remove the `html` selector in order to have those styles applied to your base class. EDIT: Did a search on the site, you should check https://stackoverflow.com/questions/10568065/limit-the-scope-of-bootstrap-styles – José Gazzano Feb 28 '19 at 15:33
  • I appreciate the help, but downloading the bootstrap css & editing it myself makes it really hard to update my dependencies in the future. I would love to find an answer in webpack code-splitting and chunk naming or something like that. – OneBigOwnage Feb 28 '19 at 17:01