Limit Scope of External CSS to Only a Specific Element

Limit scope of external css to only a specific element?

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.

Link external CSS file only for specific Div

Short answer: no.

Other ideas:

Use CSS preprocessor

.leftmenu {
@include 'style.css';
}

This uses the nesting capability of CSS preprocessors to pre-qualify all the rules in style.css. Replace the @include with your favorite preprocessor's directive for bringing in another CSS file.

Rewrite CSS manually

You can "namespace" the rules in style.css by changing all the selectors to be preceded by a qualifyng .leftmenu.

Rewrite CSS automatically

You could write JS code to rewrite the stylesheet selectors at run-time to prefix the selectors with the class name, which his essentially what this plug-in does: https://github.com/thingsinjars/jQuery-Scoped-CSS-plugin. Or you could do this rewriting on the server, whatever language it's written in.

Use IFRAME as sandbox

If the content of the thing you want to apply the styles to can be placed in an iframe, you could add the style.css frame to the HTML loaded in the iframe.

That's about it.

Restrict CSS applying on a particular div

This is a common problem that does not (yet) have a simple, universal solution.

Shadow DOM

Ideally you would use Shadow DOM, as it is specifically intended to solve such a problem:

Shadow DOM provides encapsulation for DOM and CSS in a Web Component.
Shadow DOM makes it so these things remain separate from the DOM of
the main document. You can also use Shadow DOM by itself, outside of a
web component.

Why would you want to keep some code separate from the rest of the
page? One reason is that on a large site, for example, if the CSS is
not carefully organized, the styling for the navigation can "leak"
into the main content area where it was not intended to go, or
vice-versa. As a site or an app scales, this kind of thing becomes
difficult to avoid.

  • Source
  • Also See

Unfortunately, Shadow DOM isn't well-supported yet. But if you can control the target browser (e.g. an internal application), it may be a viable option.

Iframes

On the other end of the spectrum is an iframe. iframes are supported everywhere, but may require a larger change to the page than you are able to make. More importantly, iframes introduce undesirable scrolling behaviors on iOS that may change from version to version.

Targeted Reset

A practical, though not foolproof, solution is to create a CSS reset that only targets the content you want isolated.

/* the start of a simple reset */
#email_content * {
border: 0;
margin: 0;
padding: 0;
}

This is one of the rare cases where it may be required to mark a rule as !important.

Targeted Unset (all/initial/unset)

Reset/remove CSS styles for element only

The answers to this question list possible solutions, but complete browser support does not appear to be present (notably IE).

Load an external CSS for a specific DIV

CSS applies to entire documents.

If you want to limit the scope, then you need to make use of a descendent selector.

e.g. #id_of_div .the .rest .of .the .selector {}

You have to apply this to every selector, and take into account groups (so it isn't as simple as just prefixing the whole stylesheet and suffixing every })

You would also find the stylesheet for the main document applying to your preview.

A frame would probably be the best approach to solving this problem.

Linking an external stylesheet to only specific HTML elements

What you can do is compile your own bootstrap from the source .scss files. See this related post: Limit the scope of bootstrap styles (except you don't actually have to fork bootstrap, that's overkill)

You'll end up with all the bootstrap rules prefixed with a certain selector - in your case, #preview ... so an excerpt of your-custom-bootstrap.css might look like this for you:

#preview .alert {
padding: $alert-padding-y $alert-padding-x;
margin-bottom: $alert-margin-bottom;
border: $alert-border-width solid transparent;
@include border-radius($alert-border-radius);
}

In part of your project files you'll have something like the following:

#preview {
@import (less) 'bootstrap.css';
}

You'll need to go through the process of setting up the build steps, etc. - take a look at http://getbootstrap.com/getting-started/#grunt

Here's someone who's done this and published it, but I'm not seeing any built assets in their repo so it looks like you'd still have to set up the build tools, but at least it works as a bit of a tutorial: https://github.com/homeyer/scoped-twbs

Can you scope CSS files so that they only apply to the descendants of a given element?

I’m afraid not. Some CSS pre-processors allow you to write code that achieves the same thing though.

E.g. LESS implements nested rules:

/* This LESS code... */

#header {
h1 {
font-size: 26px;
font-weight: bold;
}
p { font-size: 12px;
a { text-decoration: none;
&:hover { border-width: 1px }
}
}
}

/* ...produces this CSS */

#header h1 {
font-size: 26px;
font-weight: bold;
}
#header p {
font-size: 12px;
}
#header p a {
text-decoration: none;
}
#header p a:hover {
border-width: 1px;
}

And Andy mentioned SASS, which does the same thing.



Related Topics



Leave a reply



Submit