I want a div on my page to have the id of header but because the nature of the site requires 3rd party code to be loaded into the page I want the header div to be unaffected by any css other than the css defined explicitly for it via #header { }
Possible? I'd rather not use iframes to seperate it or anything like that.
You would have to set a reset rule for your #header which would redefine all properties you want to protect with the !important next to them to make them override any other rule..
That would be a basic protection, but it can still be overriden.. no way to completely protect it from deliberate attempts to override it .. if you are trying to protect it from mistakes and not deliberate attempts then just add a really obscure classname and style it from the class and not the id selector...
To guarantee that, you'd probably need some sort of CSS reset. As in, think of everything that might affect it and set it to a default value first.
This could get complicated depending on what the CSS for your site looks like. It might be a good idea to refactor your CSS in a way that wouldn't affect stuff in #header{}.
CSS rules have a priority order. The !important and id based rules take the highest priority, so if you can ensure that the id is unique, you wouldn't see any major problems. A quick google search yielded this, http://hungred.com/useful-information/css-priority-order-tips-tricks/. I cann't recollect the actual url though.
Related
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.
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:
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.)
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:
An introductory tutorial.
An actual example of incorporating the "Shadow DOM" concept into a Chrome extension:
RobW's Display Anchors extension
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.
I am working on a system that will allow users to embed content into a web page that they have access to.
Conceptually the user would create a div with a specific id (let's call it "myId") on their page, and include a JavaScript file that I control which would basically inject markup into "myId".
The markup returned would include divs with inline styles to them. I can't allow the users who are embedding this content into their page override the CSS styles.
I've read hundreds of articles and threads about CSS Specificity, !Important, etc. It seems the only true way to block users from overriding your styles is to use iFrames.
Below are three articles a few co-workers and I have been bouncing around.
http://weblog.bocoup.com/3pjs-css-defense/
https://speakerdeck.com/antonkovalyov/achieving-harmony-with-third-party-javascript
http://weblog.bocoup.com/3pjs-css-delivery/
One of the concerns is that iOS will stop supporting iFrames, and honestly we've all been told for years not to use iFrames. While it seems like the perfect and only solution it really does sound "hacky".
Does anyone have any insight into any other solutions? I looked at how linkedIn embeds their "connect with linkedIn button" and they are simply wrapping every property value with an !important (which a) seem super hacky and b) doesn't account for undeclared properties and values).
Your main concern with !important is that they can still override it with a later declaration using the !important keyword.
You are right about iFrames.
So you are not left with a lot of options:
one option is to prepend your own CSS declarations with a custom non-generic package-like name so that the chances the user will override them will be very slim:
.content h1
will become
.my-custom-css .content h1
the other option is to modify their css markdown instead of yours. Prepend each of their declarations with a specific css class and use that class for their div container so it applies to all of its contents.
I have element that could be injected into any page using a Firefox Addon.
Naturally, it and its ancestors are affected by the CSS rules defined on that page.
I can get so far by simply being explicit about every attribute, but even then my declarations may be overridden by an earlier declaration on the page with greater specificity.
Without making a huge mess of needlessly specific selectors and hanus use of !important, how could I go about resetting all elements' attributes under a given element (div#my_root_container_element) and ensure that my declarations under this parent element apply.
Using an iFrame is one option, but I would rather avoid it if possible - is there another way? Given the application, solutions need only work in Firefox.
Thanks.
Obviously, it seems like this aims to override the "specificity" which is core to CSS in general, but this is the closest I remember ever seeing someone attempt it. It seemed somewhat reputable at the time coming from someone involved with the YUI project:
http://developer.yahoo.com/yui/reset/#code
Using SASS, it's not too unpalatable nesting everything under a div with an ID to achieve sufficient specificity, which is the solution I've opted for.
That said, any !important declaration made in the page CSS will overrule my styles.
I built an extension which, whenever user visits some specific sites, I inject my script on the top of there web pages. I used
document.body.insertBefore(wrapperDiv, document.body.firstChild)
to do so.
Now problem: CSS of injected script gets messed up for each and every site(differ from one site to another).
How should I maintain single css structure for all sites?
You should be able to solve this problem by using unique IDs for your html tags with CSS.
That is, if your DIV CSS properties are interfering with their DIV CSS add a #uniqueNameHere ID to your DIV and set the CSS for the #ID.
This page on the use of the !important keyword may be useful too.
http://css-tricks.com/9462-when-using-important-is-the-right-choice/
Use unique selectors for your elements (be it classes with specific prefix or similarly constructed IDs), but you probably try to include CSS along with your script, which may not be a good idea.
In some cases the inline styling is the best idea - it will overwrite all the styles for your elements and will make sure the outlook of these elements is consistent across different pages.
So, I would say, go with inline styling.
For documentation on how the styles are overwritten in CSS 2.1, please see the following page: http://www.w3.org/TR/CSS21/cascade.html#specificity
Sometimes !important is useful, for example if I have defined common style for all links on the site (selector, say, a), but when I want to override some rules I have the following choices:
Use more specific (longer) selector
Use !important
Which way is better and may be there are some guidelines?
Use !important very, VERY sparingly -- it overrides just about everything, even inline styles, and messes in a less-than-obvious way with the "cascade" of style rules that gives CSS its name. It's easy to use badly, and tends to multiply, particularly when misused. You can easily end up with a element with !important rules that you want to override, at which point you often have to either refactor your styles, or use another !important rule and contribute to the problem.
And once it's spread and you're using it everywhere, you're back up in the same situation you'd be in without it (difficulty in specifying elements specifically enough to override other styles), but you also don't have !important anymore cause everything else is using it too.
When faced with a situation where !important looks appealing -- or worse, one where it's already in use and spreading -- prefer to refactor your CSS if you can. (Frankly, if you need !important outside of a user style sheet, it's usually because your selectors are already way too specific, and/or you're not taking advantage of the C in CSS.) You'd do better to define your basic styles as close as possible to the html or body elements, and when you want to override, use as little specificity as you can get away with. That way, you have plenty of room to make changes. Usually there's a reason you want to override a style, and those cases can quite often be boiled down to a class name, a particular section of the page (read: a particular parent element), etc.
(The only real exception that springs to mind is if the styles you're overriding are effectively out of your control. (If you use a framework that has very strong opinions on how your page should look, for example, you might find it annoyingly difficult to override anything. I've worked with applications that actually inserted their own inline styles, where nothing but an !important rule could override them.) If you don't have full access to the code, overriding and refactoring can easily be more trouble than they're worth. You can use !important to claw back some control, as long as you're aware of the consequences.)
What i can say is that you should try to avoid it as much as you can because it means that there are redundant code, and give an indication that the CSS and styles are not well structured.
But in some cases its a must to use it and no way to avoid.
So just do your best.
Avoid it when you can as this is what most advocate but at the same time it is important.
Have a look at:
The importance of !important in CSS