Vandervals
Vandervals

Reputation: 6054

Flawless way of preventing element from being affected by external css

I'm doing a script that will be implemented in multiple pages and I'm trying to prevent the elements it generates from being styled by the pages css. Some people have the great idea of writing css like this:

body>*{min-height:200px;}

So I found this new css property:

.elem{ all: initial }

And it seems to work quite well but I've already experienced some problems and I bet there may be many that I don't know about. For example, for internet explorer (even ie11!!!) to reset min-height, you can't use initial, you must use 0! Therefore, all:initial, doesn't override min-height...

Do you know of a better way to do this or at least a list of properties I should take care of individually??

EDIT: To better explain what I want. I will do this in JS (I mentioned before it is a script), and I'm not only interested in solutions. I'd like to know why that solution works and why is better than the one I offer. Also, I'm aware of performance, so I'd rather like to use the minimun amount of rules, if posible: I'd like to know for example, which are the most dangerous ones.

Upvotes: 15

Views: 1192

Answers (5)

Hazem_M
Hazem_M

Reputation: 589

If you style an element inline-ly, it won't be affected by external css unless you use [style] attribute to override the inline style.

Example:

<p style="background: red;">Paragraph</p>

The only way to override that style in an external css file will be like this:

p[style] {background: black !important;}

So the element won't be affected by external css unless you want to.

Upvotes: 0

Shomz
Shomz

Reputation: 37701

I'm doing a script that will be implemented in multiple pages and I'm trying to prevent the elements it generates from being styled by the pages css.

Not the most common thing to do in CSS, it's usually the other way round, so the solutions won't be common. Unless you want to generate inline rules in JavaScript, but I'll stay with CSS-only solutions.

One thing is to use a class and define a rule for each tag with that class (in order to make it more specific) - it's like a tag-specific reset class now, so say the class is called untouched:

a.untouched
div.untouched
.someOther.untouched
...etc

Now, I don't know how well structured your original CSS is - the better it's structured, the less of those untouched elements you'd have.

Even that might not be enough in some cases where the original rules have a higher specificity, and in order to overcome that (and not having to manually whitelist all the instance variations), I'm afraid you'd have to use the notorious !important rule for all those reset rules, like so:

a.untouched {color: black !important; font-size: 16px !important}

It looks ugly and it's definitely not the best practice, but it probably the easiest/most common sense solution in your case.

And here's a great tool for calculating selector specificity: http://specificity.keegan.st/


Here's a simple example with a few paragraph variations:

p {color: #999; font-size: 14px; margin: 0 0 2px;}
p.red {color: red}
p.big {font-size: 20px}
p#superRed {color: red; text-shadow: 0 0 4px red;}
p > span {color: blue}

p.untouched, p.untouched > span {color: green !important; font-size: 12px !important; text-shadow: none !important;}
Originals: 

<p>Test</p>
<p class="red">Test</p>
<p class="big">Test</p>
<p class="big red">Test</p>
<p id="superRed">Test</p>
<p><span>Test</span></p>

<br><br>
Untouched: 

<p class="untouched">Test</p>
<p class="untouched red">Test</p>
<p class="untouched big">Test</p>
<p class="untouched big red">Test</p>
<p class="untouched" id="superRed">Test</p>
<p class="untouched"><span>Test</span></p>


JS version of the example above:

var els = document.querySelectorAll('#m *');

var style = {
  'color': 'green',
  'font-size': '12px',
  'text-shadow': 'none'
}

for (var i = 0; i < els.length; i++) {
  console.log(els[i], els[i].style['color']);
  for(var s in style) {    
    els[i].style[s] = style[s];
  }
}
p {color: #999; font-size: 14px; margin: 0 0 2px;}
p.red {color: red}
p.big {font-size: 20px}
p#superRed {color: red; text-shadow: 0 0 4px red;}
p > span {color: blue}
Originals:

<p>Test</p>
<p class="red">Test</p>
<p class="big">Test</p>
<p class="big red">Test</p>
<p id="superRed">Test</p>
<p><span>Test</span>
</p>
<br><br>
New ones:

<div id="m">
  <p>Test</p>
  <p class="red">Test</p>
  <p class="big">Test</p>
  <p class="big red">Test</p>
  <p id="superRed">Test</p>
  <p><span>Test</span></p>
<div>

Upvotes: 2

shock_gone_wild
shock_gone_wild

Reputation: 6740

What about using Cleanslate ?

Wrap your generated elements with a container that has the class "cleanslate" and style the elements within that container with !important rules. More information can be found on the link above.

Upvotes: 2

Pratik Shah
Pratik Shah

Reputation: 828

Right now we don't have unified CSS effects on all major browsers! But we can still create a class which will reset most of all CSS properties to their initial values! Look at the below code:

.reset-this {
    animation : none;
    animation-delay : 0;
    animation-direction : normal;
    animation-duration : 0;
    animation-fill-mode : none;
    animation-iteration-count : 1;
    animation-name : none;
    animation-play-state : running;
    animation-timing-function : ease;
    backface-visibility : visible;
    background : 0;
    background-attachment : scroll;
    background-clip : border-box;
    background-color : transparent;
    background-image : none;
    background-origin : padding-box;
    background-position : 0 0;
    background-position-x : 0;
    background-position-y : 0;
    background-repeat : repeat;
    background-size : auto auto;
    border : 0;
    border-style : none;
    border-width : medium;
    border-color : inherit;
    border-bottom : 0;
    border-bottom-color : inherit;
    border-bottom-left-radius : 0;
    border-bottom-right-radius : 0;
    border-bottom-style : none;
    border-bottom-width : medium;
    border-collapse : separate;
    border-image : none;
    border-left : 0;
    border-left-color : inherit;
    border-left-style : none;
    border-left-width : medium;
    border-radius : 0;
    border-right : 0;
    border-right-color : inherit;
    border-right-style : none;
    border-right-width : medium;
    border-spacing : 0;
    border-top : 0;
    border-top-color : inherit;
    border-top-left-radius : 0;
    border-top-right-radius : 0;
    border-top-style : none;
    border-top-width : medium;
    bottom : auto;
    box-shadow : none;
    box-sizing : content-box;
    caption-side : top;
    clear : none;
    clip : auto;
    color : inherit;
    columns : auto;
    column-count : auto;
    column-fill : balance;
    column-gap : normal;
    column-rule : medium none currentColor;
    column-rule-color : currentColor;
    column-rule-style : none;
    column-rule-width : none;
    column-span : 1;
    column-width : auto;
    content : normal;
    counter-increment : none;
    counter-reset : none;
    cursor : auto;
    direction : ltr;
    display : inline;
    empty-cells : show;
    float : none;
    font : normal;
    font-family : inherit;
    font-size : medium;
    font-style : normal;
    font-variant : normal;
    font-weight : normal;
    height : auto;
    hyphens : none;
    left : auto;
    letter-spacing : normal;
    line-height : normal;
    list-style : none;
    list-style-image : none;
    list-style-position : outside;
    list-style-type : disc;
    margin : 0;
    margin-bottom : 0;
    margin-left : 0;
    margin-right : 0;
    margin-top : 0;
    max-height : none;
    max-width : none;
    min-height : 0;
    min-width : 0;
    opacity : 1;
    orphans : 0;
    outline : 0;
    outline-color : invert;
    outline-style : none;
    outline-width : medium;
    overflow : visible;
    overflow-x : visible;
    overflow-y : visible;
    padding : 0;
    padding-bottom : 0;
    padding-left : 0;
    padding-right : 0;
    padding-top : 0;
    page-break-after : auto;
    page-break-before : auto;
    page-break-inside : auto;
    perspective : none;
    perspective-origin : 50% 50%;
    position : static;
    /* May need to alter quotes for different locales (e.g fr) */
    quotes : '\201C' '\201D' '\2018' '\2019';
    right : auto;
    tab-size : 8;
    table-layout : auto;
    text-align : inherit;
    text-align-last : auto;
    text-decoration : none;
    text-decoration-color : inherit;
    text-decoration-line : none;
    text-decoration-style : solid;
    text-indent : 0;
    text-shadow : none;
    text-transform : none;
    top : auto;
    transform : none;
    transform-style : flat;
    transition : none;
    transition-delay : 0s;
    transition-duration : 0s;
    transition-property : none;
    transition-timing-function : ease;
    unicode-bidi : normal;
    vertical-align : baseline;
    visibility : visible;
    white-space : normal;
    widows : 0;
    width : auto;
    word-spacing : normal;
    z-index : auto;
}

Check out these links for more details:

Source of Properties | MDN Initial Value

Upvotes: 4

hijarian
hijarian

Reputation: 2228

Your only working best bet is to re-define styles in Javascript program by hand for all elements your program creates. For example, in jQuery:

$('.my-own-elem').css('attr', 'value');

That is, you create an element and immediately style it as you want. To prevent FOUC, you can create a raw DOM element, style it, and attach it after it was completely prepared.

Realistically, overrides of styles from Javascript takes maximal precedence in all browsers. It's quite a lot of work, however, to style via Javascript, and it'll be even more work to make resulting code maintainable.

Upvotes: 1

Related Questions