alienv.dev

use Shadow Dom for encapsulation css in google extensions

February 13, 2018

Recently in Round Table Apps, They assigned a project to me in last days, It was a google extension app and what it should do was track all users in more than 100 websites! I suggest to our team’s head use from react-redux for create google extension app and explained benefits of this work and he almost approved that.

Problem

One of our challenges was in application’s styles because we had a custom designs and css but when you run application in several websites it inherits from their styles. That was fucking crazy. For example we created:

<button className="login-button">login</button>
.login-button {
 color: red;
}

every thing was perfect just in localhost but when we tested it on another sites such as stackoverflow our button’s color changed to the blue because it inherits default styles from that site‌(In addition another styles such as borders, backgroundColor, boxShadow and …). we tested !important rule (color: red !important;) but it had some issues again. This was just little bit of our challenges with designs. We needed to a perfect solution!

The Solution was Shadow DOM

I was familiar with Shadow DOM because i read about it in Angularjs and how to use angular from that, but i didn’t have experience use it in a real project by my own, So i started for searching and read more about it and how to use it in ReactJs. I found a package that name was react-shadow.

before starting use from react-shadow i want show you how to use shadow DOM with pure javascript.(reference)

<div class="dom"></div>

let el = document.querySelector(".dom");
el.attachShadow({mode: "open"});
// Just like prototype & constructor bi-directional references, we have...
el.shadowRoot // the shadow root.
el.shadowRoot.host // the element itself.

// put something in shadow DOM
el.shadowRoot.innerHTML = "Hi I am shadowed!";

// Like any other normal DOM operation.
let hello = document.createElement("span");
hello.textContent = "Hi I am shadowed but wrapped in span";
el.shadowRoot.appendChild(hello);

This code will create a simple Shadow DOM in div.dom element. You can read more about it in mozilla website.

React-Shadow and Chrome Extension

window.addEventListener('load', () => {

  const injectDOM = document.createElement('div');

  document.body.insertBefore(injectDOM, document.body.firstChild);

  store.ready().then(() => {

  render(
    <Provider _store_={store}>
       <ShadowDOM include={['styles/global.css']}> <InjectApp />
       <ShadowDOM/>
     </Provider>,
     injectDOM);

  });

});

This was my experience in fixing and encapsulation styles in google chrome extensions and it works !