1

I'm not sure this is possible, but id like to set all user styles back to chrome defaults for div and descendants.

I'm building a Chrome plugin that creates a popup on any web page, however due to the fact every page has a plethora of custom styles, trying to track down every inconsistency and overwrite it with my divs (and descendants) custom style, it is becoming a nightmare.

Every time I think I've covered all bases another site implements something else that needs to be overridden.

What would be the easiest approach to standardize my popup in this situation?

One approach I can think of is to (bite the bullet) and get a hold of the the default Chrome CSS styles and implement them into a series of catch all descendant selectors, however surely there is a better way.

halfer
  • 19,824
  • 17
  • 99
  • 186
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • Surely there *should* be a better way. :) We can do [scoped CSS](http://css-tricks.com/saving-the-day-with-scoped-css/) but we want to do the opposite: escape from the page scoped CSS! – joeytwiddle Jun 28 '14 at 19:07

2 Answers2

2

If you want to be absolutely sure that the styling of your elements is not affected by the web-page's CSS, there are 2 possible solutions:

  1. Use an iframe to implement your popup. (This solution is "safe" and simple enough, but based on the kind of interaction between the popup and the web-page it might become cumbersome.)

  2. Utilize the Shadow DOM. (This is probably the "proper" solution, but the implementation might be a little more complicated.)

Some resources regarding the 2nd solution:

gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • Always glad to help ! (Feel free to upvote if you really liked the answer :)) – gkalpak Jan 05 '14 at 07:57
  • I would love to see an example of using Shadow DOM to achieve this. It will soon be [available](http://caniuse.com/shadowdom) in Firefox, and is already in Safari and Chrome. – joeytwiddle Jun 28 '14 at 19:04
0

There is a third option worth discussing and rejecting, which is to reset all the style properties of the div and its descendents to its default value. Pseudo-code:

#my-div, #my-div * {

  @for-every-css-property {

    %propertyName: initial !important;

  }

}

This answer shows an attempt at such a solution. It uses specific values instead of initial which will work in older browsers without the initial keyword, but will not correctly reset elements which have a different default from the base (e.g. user566245 mentions that textarea elements should have a border).

Issues:

  • Unfortunately initial is not actually the browser's default value.
  • If we don't use !important above then there is a risk that the page might have provided a rule with a more specific elector which overrides our own. For example if the page specified properties for table > tr > td then this would be applied over our rule because that selector is more specific than #my-div *.
  • Since we do use !important, any custom styling we want to do after the reset must also use !important on every property.
  • If the page happens to inject any additional CSS styles after ours that uses !important then these can override our reset.
  • It is rather inefficient. We are asking the browser to apply a huge bunch of CSS rules to every element under our div.
  • Vendor-specific properties should also be reset. (E.g. -webkit-animation-name.)
  • If new CSS properties come into existence in future, you will need to update your list.

Whilst this solution can be applied to current browsers, it is rather horrible, so roll on Shadow DOM! I would recommend the <iframe> solution in the meantime.

I don't know if anyone has tried this, but a more efficient solution might be to use Javascript to detect what site-defined CSS properties could be problematic, and reset only those.

Community
  • 1
  • 1
joeytwiddle
  • 29,306
  • 13
  • 121
  • 110