Encapsulating CSS within Content Script
See original GitHub issueMy extension needs a UI for the user to interact with beyond the popup.html. In order to achieve this, I have injected the Vue app into a element I append to the DOM in a content script. Like so:
var elem = document.createElement('div');
document.body.appendChild(elem);
/* eslint-disable no-new */
new Vue({
el: elem,
render: h => h(App)
})
However, I am having tons of issues encapsulating CSS. For instance, in the popup I use Buefy to make the frontend a bit faster and prettier, but doing this in the content script also affects the pages being visited, which is obviously a no-go. Similarly, I’d like the visited page not to affect the CSS on my Vue app, so that I can offer a consistent experience.
I am looking for a way to make sure that I can encapsulate the Vue app’s CSS in both ways. I have tried injecting the app to an element in the Shadow DOM like so:
var shadowElement = document.createElement('div');
shadowElement.attachShadow({mode: "open"});
document.body.appendChild(shadowElement);
var hello = document.createElement('div');
shadowElement.shadowRoot.appendChild(hello);
/* eslint-disable no-new */
new Vue({
el: hello,
render: h => h(App)
})
This is successful in avoiding external css from affecting my app, but I can’t get any CSS at all to work on it.
Any help is welcome!
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:19 (4 by maintainers)
Yeah, I did. After publishing a version that broke CSS on some popular websites that I don’t use/test on, yikes. Way after that comment was posted. Here’s what I did to get my stuff working:
.scss
, but I’ve had this one file that was.css
. This file was a major headache until I simply renamed it to .scss and corrected imports (which is strange, because in theory you should be able to scope.css
, too. Maybe I was doing something else wrong, I don’t know. That was most of the fix). (Side note: styles will still compile to .css. You still include the one[something].css
in your content script)Option B, if your styles are in a separate file:
So far, this appears to be working for me.
Edit: rewrote some bits for better readability.
And if @jigartankhupp’s solution doesn’t work for you, check your imports.
Because that solution worked for me in Firefox, but not in Chrome.
After some troubleshooting, I’ve noticed that the CSS that doesn’t work is actually imported from other files.
Long story short — in your vue component, you should import your (S)CSS this way:
And not this way: