0

I'm writing a Chrome extension that injects HTML into a displayed page. I want the injected HTML to have it's own style, protected from the CSS that may be present in the host page.

I've tried using conventional CSS, and still suffer from style corruption from the host page.

After watching the Polymer presentation from I/O 15, I was wondering if there are any new, Chrome-specific techniques that I can use to achieve this?

pinoyyid
  • 21,499
  • 14
  • 64
  • 115
  • For more info on styling in the ShadowDOM, see this related question: http://stackoverflow.com/questions/27622605/what-is-the-content-pseudo-element-and-how-does-it-work – TylerH Jun 11 '15 at 16:03

2 Answers2

2

What you will want to look into is shadow-dom. This will enable you to create a widget/component (which would be your injected html). This would mean that the DOM tree for the widget/component is encapsulated and no external styles from the page will affect it. There is a good article on html5rocks covering this. You may also want to look into WebComponents. Bear in mind that this functionality is only available in the latest browser versions.

Ben Thomas
  • 3,180
  • 2
  • 20
  • 38
  • Cool. That's kinda what I was looking for. Can I confirm that "now external styles" should read "no external styles"? – pinoyyid Jun 10 '15 at 09:39
  • Does it require any command line flags or non-default settings to work? – pinoyyid Jun 10 '15 at 09:41
  • That was a typo which I've corrected. **No** external styles will affect it. You won't need to change any settings in Chrome for this to work. If you use Polymer, shadow dom is turned off by default. You can read about this [here](https://www.polymer-project.org/1.0/docs/devguide/settings.html) – Ben Thomas Jun 10 '15 at 10:51
0

Two things that I currently use at my place of work are:

I use react at work, hence react-css-modules, but css-modules should work in your case. It's not Chrome specific, but we use them within the context of each component we build. Basically, like the docs state, a class of row would become something like table__row___2w27N. The breakdown of the built name is the filename of the CSS than the class name followed by a base64 hash of 5 char. I hope this helps.

One potential downside is Webpack would be required.

Here is an example of our component folder structure:

- component
  - Component.jsx/js
  - component.css/scss/sass
  - component.test.js
Corey Trombley
  • 136
  • 1
  • 9
  • Also just found this, [css-modulesify](https://github.com/css-modules/css-modulesify). – Corey Trombley Sep 12 '16 at 19:35
  • I don't see how this is a complete solution. You can make your class names unique, but assume that the host page sets styles for basic tags, i.e. just plain `div`. You need to combine it with a pretty thorough CSS reset for all of your injected DOM. – Xan Sep 13 '16 at 08:38
  • Yeah, I don't think this could be a full solution without work. With Sass/Scss I think it could be a lot easier to manage by wrapping the entire injected HTML in a class and then changing the element defaults there. Like you said though @Xan you would need a thorough CSS reset. – Corey Trombley Sep 16 '16 at 14:19