marka.thore
marka.thore

Reputation: 2825

Isolate css scope

For a very mysterious reason, I have to limit the scope of a css file only to an element:

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="one.css">
    </head>
    <body>
        <div id="first-container">
        </div>

        <div id="second-container">
            <link rel="stylesheet" type="text/css" href="two.css">
        </div>
    </body>
</html>

The rules in one.css should be applied as usual, while the rules in two.css should be scoped to the div#second-container only.

That is exactly what the attribute scoped attribute should do: http://w3c.github.io/html-reference/style.html#style.attrs.scoped , but is not currently supported (and it will never be) http://caniuse.com/#search=scoped .

I've tried to isolate scope with a regex (CSS are 10K+ lines minified), but it didn't work out well.

Any solution (or dirty workaround) for a strange use case like this?

I can use one of these way:

Upvotes: 2

Views: 2166

Answers (4)

SirPilan
SirPilan

Reputation: 4837

You can do this with a Shadow-Dom aswell:

const component = document.querySelector('#component');
const host = document.querySelector('#host');
const shadow = host.attachShadow({'mode': 'closed'});
shadow.appendChild(component);
#component {
  display: none;
}
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.0.4/css/bootstrap-combined.min.css' />

<div id="component">
  <link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css'/>

  <button class='btn btn-primary'>I get bootstrap 4 css 😏</button>
</div>

<div id="host"></div>
<br />
<button class='btn btn-primary'>I get bootstrap 2 css 🀯</button>

This wont work in every Browser: Have a look here.

Upvotes: 1

Krzysztof Atłasik
Krzysztof Atłasik

Reputation: 22595

It might be a little complicated but this comes to my mind:

1) Create invisible iframe element anc copy content of div to it

var i = document.createElement('iframe');
i.style.display = 'none';
i.src = "data:text/html;charset=utf-8," + document.querySelector('#secondDiv').innerHTML;
document.body.appendChild(i);

2) Apply style in iframe

var cssLink = document.createElement("link") 
cssLink.href = "style.css"; 
cssLink.rel = "stylesheet"; 
cssLink.type = "text/css"; 
frames['iframe'].document.body.appendChild(cssLink);

3) Inline style of html in iframe.

4) Copy it back to div from iframe.

Upvotes: 3

cmorrissey
cmorrissey

Reputation: 8583

Use Sass and Nesting

// .scss
#second-container {
    @import 'two';
}

Upvotes: 3

coderodour
coderodour

Reputation: 1057

try this: add an extra id to the element, and make the isolated css to style that element using that extra id, in case the styling does not take effect, try adding !important to that particular line in your isolated css. e.g : height:0px !important;

Upvotes: 1

Related Questions