Limit scope of external css to only a specific element?
Asked Answered
R

6

80

I am creating a mobile simulator that mocks the appearance and functionality of an iPhone (and other devices later) in a web browser, using 100% javascript, HTML5, and CSS, with the simulator fully functional with only client side code.

While trying to accomplish this task with as little modification as necessary to the original app projects themselves to be hosted in the simulator, I am injecting the <script> and <link> tags into the head of the page, then loading the html into a <div> screen.

The problem is that when I load in a new css file, it (obviously) overrides the one I'm using to style the page, and therefor some elements are affected (ex the background changes color).

My question is: Is there any way to limit the "scope" of an external .css file to apply only to objects within the <div> screen? Would it make any difference if instead of me injecting it into the <head> of the page, I inject it into a <style> element in the <div> screen?

Raama answered 16/7, 2013 at 4:12 Comment(2)
Can't you just scope the CSS to specific elements/classes and then change the elements/classes as needed?Surtax
I could, but then I would have to require all users of the simulator to follow a specific css layout, whereas I am trying to explore options to accomplish the same without any modification to typical css stylingsRaama
R
43

UPDATE Support for this feature has been dropped. Please seek other options

Original Post:

You may want to look at scoped styles; see http://css-tricks.com/saving-the-day-with-scoped-css/.

The basic idea is

<div>
    <style scoped>
        @import "scoped.css";
    </style>
</div>

However, you are on the bleeding edge here in terms of browser support. See http://caniuse.com/style-scoped.

One alternative would be to use an iframe.

Raceme answered 16/7, 2013 at 4:27 Comment(3)
There's a jQuery polyfill for scoped CSS: github.com/thingsinjars/jQuery-Scoped-CSS-pluginSurtax
Unfortunately, that polyfill does not implement scoped styles correctly, in that it does not apply them to the parent of the style element as it should. See github.com/thingsinjars/jQuery-Scoped-CSS-plugin/issues/6.Raceme
For the future reader, scoped styles have been removed from the CSS spec. Don't use this!Fitz
W
32

Simply wrap all you css code inside the selector for parent element, say it's a div with id of foo you'd do the following:

div#foo{
//All your css
}

And convert it as less to css, it will prepend the right selectors. Note that you'll need to take care manually of things like @media queries and so on.

Wirer answered 29/6, 2015 at 12:41 Comment(1)
You would require all users of the simulator to do the same thing, as mentioned in the comments on the question.Creatural
L
3

While writing this, the <style scoped> is deprecated by the Chrome team. As a result I experimented with some approaches and released https://github.com/thgreasi/jquery.scopeLinkTags . Note: you should only have to use this approach in case that you can't control the imported CSS file. If you can use SASS/LESS/anything to pre-process your CSS, you should prefer that.

Lagunas answered 15/6, 2016 at 5:6 Comment(2)
Anyone know why they deprecated it? Seems like a great idea, no?Foust
"due to high code complexity.", see here.Angy
E
2

I had a similar issue and found that Shadow DOM can solve it easily.

let output = d.querySelector('#output')
let shadow = output.attachShadow({
  mode: 'closed'
});
shadow.innerHTML = HTMLcontent // HTML content and style injected 

Source

Enchanter answered 9/1, 2022 at 15:5 Comment(0)
O
1

A simple way is adding pre-class before all selector in css file.

I find a grunt script can do this:

https://github.com/ericf/grunt-css-selectors

Onida answered 25/7, 2016 at 6:38 Comment(0)
J
1

This is how i do it if not using preprocessor in my project. Search for a online preprocessor then load copy paste the css under the parent class/id

.parent{
    // copy paste here
}

Example

  1. Find a preprocessor for example https://beautifytools.com/scss-compiler.php works very well for me (I have no affiliation with the given link)
  2. if you are using from a URL add the URL using the load URL button.
  3. Wrap the css code under parent and hit compile then minify.
Jerol answered 28/5, 2021 at 20:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.