question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Encapsulating CSS within Content Script

See original GitHub issue

My 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:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:19 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
tamius-hancommented, Mar 15, 2020

This gets the CSS loaded, but its still not encapsulated. The page and app are both effecting each other. Did anyone find a solution?

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:

  1. Use scss, not css when writing your app (all you need is to change file extension for this one). I write my styles with .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)
  2. Scope your styles. Option A:
<style lang="scss" scoped>
// styles and imports go here
</style>

Option B, if your styles are in a separate file:

<style scoped src="../relative/path/to/style.scss"></style> 

So far, this appears to be working for me.

 

 

Edit: rewrote some bits for better readability.

2reactions
tamius-hancommented, Feb 6, 2020

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:

@import '../relative/path/to/css; /* works in FF and Chrome */

And not this way:

@import url('/absolute/path/to/css`); /* works in Firefox, but not in Chrome */
Read more comments on GitHub >

github_iconTop Results From Across the Web

css - How to really isolate stylesheets in the Google Chrome ...
The solution to this problem -isolation of styles without iframes- is Shadow DOM (since Chrome 25). You can find a tutorial at HTML5...
Read more >
Using web components to encapsulate CSS and resolve ...
The solution: CSS encapsulation with web components​​ Custom elements brought it all together. The top-level template loads source/javascripts/ ...
Read more >
Encapsulating Style and Structure with Shadow DOM
A shadow root's author can style content inside the light DOM to a limited extent using the CSS ::slotted() pseudo-selector; however, the DOM ......
Read more >
CSS for an encapsulated web - DEV Community ‍ ‍
The first solutions · no more ID's in selectors; · no "brute-force" values (as that z-index ); · no more !important or exotic...
Read more >
Writing CSS that scales: Encapsulation - Medium
Changes in one component break the other, implementing a facelift on a ... inner content (attributes/properties or DOM insertion points).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found