Gijo Varghese
Gijo Varghese

Reputation: 11780

How to Isolate a DIV and its contents from external CSS

I'm creating a chat widget that will inject a div to the body of his website. However, I don't want the div to apply CSS from default style sheet of the website.

Is there any way to isolate a div like this?

Most of the existing solutions needs to change CSS code in their website, which is not possible for me

Upvotes: 3

Views: 3276

Answers (3)

Fred Gandt
Fred Gandt

Reputation: 4312

Shadow DOM

The feature(s) of the Shadow DOM v1 are currently (2024) "widely available across major browsers" according to caniuse.com, who describe it as a:

method of establishing and maintaining functional boundaries between DOM trees and how these trees interact with each other within a document, thus enabling better functional encapsulation within the DOM & CSS.

From Google Developers: Shadow DOM v1: Self-Contained Web Components (2017):

Hands down the most useful feature of shadow DOM is scoped CSS:

  • CSS selectors from the outer page don't apply inside your component.
  • Styles defined inside don't bleed out. They're scoped to the host element.

CSS selectors used inside shadow DOM apply locally to your component. In practice, this means we can use common id/class names again, without worrying about conflicts elsewhere on the page. Simpler CSS selectors are a best practice inside Shadow DOM. They're also good for performance.

Below, we attachShadow to a new createElement( "div" ) to which we apply the style.all = "unset" to disinherit all the rules applied to the rest of the document's divs.

We then fill our shadow-root with whatever content we like, and supply any styles desired, before appendChild( "new_div" ) injects our content into the body.

The result is stylistically isolated content.

const new_style = document.createElement( "style" ),
      new_div = document.createElement( "div" ),
      new_p = document.createElement( "p" ),
      shadow = new_div.attachShadow( { mode: "open" } );

new_style.textContent = `p {
  padding: 1em;
  border-radius: 1em;
  box-shadow: 2px 2px 15px 5px rgba( 0, 0, 0, .5 );
}`;
shadow.appendChild( new_style );

new_p.textContent = "Shadow DOM FTW \\o/";
shadow.appendChild( new_p );

new_div.style.all = "unset";
document.body.appendChild( new_div );
body {
  background: antiquewhite;
}
div {
  background: cornflowerblue;
  border: 2px grey solid;
  border-right: 0;
  border-left: 0;
  margin: 2em;
}
p {
  font-family: "Comic Sans MS";
  margin: inherit;
}
<body>
  <div><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p></div>
</body>

Upvotes: 4

Gijo Varghese
Gijo Varghese

Reputation: 11780

Shadow DOM with scoped CSS seems to be a good solution. However, it's still not production-ready, lacks browser support.

I ended up using Cleanslate CSS. It adds an extra ~20KB CSS. But do the job really well. Support all browsers too.

Upvotes: 0

Keith Santiago
Keith Santiago

Reputation: 1

im not sure if this is what you seek for. but you can inject a link and point it, on desired css that targets the div that is to be inserted to the website...

Upvotes: -2

Related Questions