I have some html markup & css styling that will be embedded on several thousands of different websites. I want this section to only use my own stylesheet, while ignoring the original site's css.
Apart from using unique prefixes for all classes and id's, is there a way to not apply site wide css rules on a certain area, and only use my own styling?
FYI !important declarations in user CSS will always win against CSS Author and User Agent ones (resource: the cascade on Sitepoint), but that's not what you're competing with.
There's no way to only apply your CSS while completely ignoring the rest of the page, afaik (the C in CSS is there for a reason ;) ). But nevertheless, here's a bunch of things that should help:
!important is very powerful. Only other declarations with this modifier have a chance to still be applied
same for inline styles (not sure if it's as needed as it is for those dreaded HTML emails though)
id have a strong specificity. A selector with 412 classes and no id has less specificity than one with 1 id and no class (that's why it's a bad practice according to OOCSS and css linters based on it. Ymmv)
a nice trick allowing to artificially add to CSS specificity is .c.c { prop:val}: twice the specificity of .c {} and exactly the same scope. Imagine this with id ;) (you can also have an id on each and every ancestor of an element but you can't have 2 id on the same element)
initial and unset'd have been nice if it was supported by IE... Would be even better: all property but it's IE11+ and not in Safari
So you'll have to read carefully MDN for each property you want to reset and apply its default value. Or read this amazing answer here on SO on a related question: https://stackoverflow.com/a/18464285/137626
Don't forget about declarations inside Media Queries that could apply on client websites: you (or you clients) won't see them until they resize their browser.
I care a lot about not having not too much specificity in general rules and then specific ones in default resolution, but in that last MQ (320 or 1600+) of a given project, I don't really care anymore if it' more convenient for me (i.e. faster) as I know for sure that I won't need to override it later. Ever.
EDIT: don't forget to take into account pseudos :before and :after. Normalize.css is now declaring *, *:before, *:after { (-prefix-)box-sizing: border-box } and that may be surprising if you also use them. Better not use them imho as they can't be styled in style attribute (same problem with MQ).
To annihilate any style these pseudos could have, this code:
high-specificity-selector *:before,
high-specificity-selector *:after {
content: none !important
}
should be enough: no content, no pseudo.
/EDIT
If you're pretty serious about your project (thousands of websites, wow), you could also automatically test for the CSS applying on client's website in the wild, with tests verifying:
the CSS values of a bunch of properties on a bunch of elements of your widget. Resource: http://csste.st/tools/
the rendering of your widget compared to an initial screenshot with teh mighty PhantomCSS (based on CasperJS, itself based on PhantomJS. Casper tests in WebKit but there are clones testing in Gecko/SlimerJS or with IE/TrifleJS)
Related
In CSS, there's an hierarchy of developing stylesheets: the web-page developer writes a stylesheet, the reader writes another one, and then there's the default stylesheet of the browser. It is known that the order of precedence for the application of the stylesheets are: the developer's, the reader's and the browser's.
It is also known, however, that the reader can override a style assigned by the developer by appending !important to the property declaration:
h1 {
color: white !important;
}
However, what happens if the developer, too, appends !important at the end of their property declaration. Which one takes precedence in this case? Also, does the browser's stylesheet have any !important appended to any property declaration? If it does, how does this effect the style of the web-page?
The book I use for studying HTML and CSS, Head First HTML and CSS, 2nd edition by O'Reilly, tells me there's nothing I can do to override the reader's style (or atleast, that's what I've inferred—it may be that I've misunderstood). I did not try fiddling with the 'reader's' stylesheet simply because I don't know how to do it.
As you have mentioned you are referring Head First HTML and CSS, 2nd edition by O'Reilly, it is important to note it is released in 2012.and over the year !important rules have changed.
I would suggest you go through certian articles.
As #DBS suggested in the comment,
If two rules affecting an element both include an !important flag, it should fall back to standard specificity rules, not necessarily the last !important
Followed by this article
By default, CSS rules in an author's stylesheet override those in a user's stylesheet. However, to create a balance of power between authors and users, !important rules in a user stylesheet will override !important rules in the author’s stylesheet. This CSS feature is designed for accessibility. Users that need larger fonts, specific color combinations, or other requirements due to disabilities related to vision can maintain control over the presentation of a web page.
Hope it helps!
I've developing an app with Vue, and a third-party template, and dynamic plugins, and all kinds of trickery. I'm have a really hard time with the CSS.
Often I need to style particular element on the page, an <input> for example, and I can't figure out how to write a selector that actually works. The input may have been created dynamically by some Javascript and may have had CSS applied programmatically.
So I go to Firefox Web Developer, click on the element, and see a bunch of CSS classes. I create a rule:
.myCustomClass {
color: red;
}
put myCustomClass in the class="" tag in the <input>, and... nothing.
I'm thinking I need to prefix it like this:
.someOuterClass .someInnerClass .myCustomClass {
color: red;
}
but that rarely works. Sometimes I give up and add !important. Sometimes that works, and sometimes it doesn't.
So my question is, can I examine the classes that I can see in Web Developer and somehow derive a rule that is specific enough that it will always work?
I've read about specificity, but it's not helping.
Specificity is a PITA sometimes, especially when other 3rd party libraries are adding stuff to the mix.
Here are a few things you can try:
Make sure to add your styles to the END of the CSS. Theoretically, you can affect the order Webpack includes CSS (I've never tried it)
Add an ID not a class to a wrapper outside the elements you want to change. Then reference this ID in the CSS chain eg: #myAppID .className .subClassName {} Basically ID's are stronger than classes in CSS specificity. I would try to do this at a page/view level to make life easier.
If elements are already getting classes (as you see them in the inspector) try to reuse those classes with your "override" CSS. If the classes are modularized (Have a random suffix like someClass__34xft5) you shouldn't use those exact classes since they can change if the source is recompiled. In that case, use a "matching" selector [class^=”someClass__”] to match any selector with that prefix.
Not sure how deep you want to go, but here's an article about overriding Amplify-Vue prebuilt styling.
One caveat, if the CSS is being added inline via javascript somewhere, it's going to be very hard to override. You may want to use !important in conjunction with the above.
"...can I examine the classes that I can see in Web Developer and somehow derive a rule that is specific enough that it will always work?"
Probably, but why bother? You're already adding class attributes to elements. Why not add inline style attributes instead? Adding a bunch of classes or ids just to create a specificity chain to touch up styles is pretty messy...inline styles are barely if at all worse and are clearer to understand.
Inline attributes are the most specific CSS instructions you can give.
In modern HTML coding, it is popular to add several class names to an element such as
<div class="class1 class2 class3 class4 ..."
</div>
This gives us a great flexibility for mixing CSS properties without repeating them for different classes.
Logically, the browsers consumes more resources to collect CSS properties of different classes for applying to the corresponding element.
Since it is difficult to run a reliable benchmark on this, I am asking this question from theoretical point of view. Imagine that most of the HTML elements of a page have several classes (e.g. 10 classes). Does this make the page render more difficult and slower? Is this slowdown sensible and considerable?
In general, what is the common process of browsers to read properties from different classes?
The interest in adding many classes, is to have separate classes for individual styles and not repeat/create a new class for the same use.
For instance, if I have a button, I can have 3 classes, like .btn .big .grey. If I want to create another button, I only need to repeat the .btn class, and add my other custom classes, like .medium, and .green. It's called the OOCSS (Oriented Object CSS).
With regard to performance, I recommend you watch this little example http://www.css-101.org/descendant-selector/go_fetch_yourself.php, http://csswizardry.com/2011/09/writing-efficient-css-selectors and you can find a lot of articles about performance on ids vs classes.
Multiple classes can make it easier to add special effects to elements without having to create a whole new style for that element. For example, you may want to have the ability to float elements to the left or right quickly. You might write two classes "left" and "right" with just "float:left;" and "float:right;" in them. Then whenever you had an element you need to float left you would simply add the class "left" to its class list.
I like to use multiple classes for things that I want to keep standard across the entire site. For example, if I always want the bottom-margin for elements that have a bottom-margin to be 10px. By creating a class that only encompases the botom-margin:10px; I can add it wherever it's needed.
Disadvantages of Multiple Classes
While they are supported in the major browsers, really old browsers don't support them. So you should make sure that the first class you list is the one with the most specific information for that element.
Multiple classes can also get really confusing as you apply more and more to an element.
More...
Summary:
Reduce total number of selectors (including IE-related styles: .ie7
.foo .bar)
Avoid universal selectors (including unqualified attribute selectors:
[type="url"])
Page zoom affects CSS performance in some browsers (e.g. Opera)
Window size affects CSS performance in some browsers (e.g. Chrome)
Page reloads can negatively affect CSS performance in some browsers
(e.g. Opera)
“border-radius” and “transform” are among most expensive properties
(in at least WebKit & Opera)
“Timeline” tab in WebKit-based browsers can shed light on total
recalc/reflow/repaint times
Selector matching is much faster in WebKit
http://perfectionkills.com/
I want to know what things can be done "ONLY" with CSS , that are not available using dynamically updated style "attributes" using Javascript. So far I know:
Media queries
Pseudo tags
Any more?
Update:
This question was closed but I asked it as I am trying to decide on the technology to use for a project, but one of the options cannot use CSS style sheets, and can only manipulate the style attribute using javascript.
Inline style attributes can only contain property declarations (e.g. width: 10px or color: red). They can't contain any other CSS constructs: not selectors, at-rules (e.g. #import, #media, #font-face), etc. Just property declarations.
However, they play a big role in the cascade: any styles for an element with that attribute take highest precedence (after considering !important of course).
There's actually an entire module devoted to style attributes, by the way, but it's not essential reading for authors.
So, anything that isn't a CSS declaration, is only possible in a stylesheet, not a style attribute. Not sure if that's what you're asking...
Note that media queries and #media rules are not the same thing; media queries can exist in areas outside of stylesheets too, like HTML's media attribute, where they're next most commonly found.
I believe pseudo classes (:hover etc..) and pseudo elements (:after, :before) cannot be added/manipulated via JS (via the style property i mean) because they are not part of the DOM.
Is p.error better or worse than .error?
I have read that element-specific selectors are bad and should be used only if really needed but noone seems to know why. I mean I do understand that .error is better for code reuse, but is there somekinda specific reason why I shouldn't address class with element always?
CSS selectors are read right to left. So p.error has one additional step to .error. This may result in a smaller set or not - depends on your markup.
However, this is a micro micro optimization. There is not going to be a performance hit unless we're talking about a massive amount of selectors.
Here's a great article on CSS selectors that elaborates on how they are evaluated : http://css-tricks.com/efficiently-rendering-css/
.error is more efficient than p.error .
To understand why this is more efficient I recommend you read this article over at css tricks.
no it's not bad, but it may not always be necessary
tools like Google's PageSpeed and YSlow! refer to these type of selectors as being "over qualified" perhaps that's where you're hearing the "it's bad" part from - reading material
take for example p#myid - an ID should always be unique on a page anyway, therefore there is no need at all to qualify it with the p element. an ID already has the highest weight when specificity is being counted so again it's totally redundant to add the extra part to try and add more specificty.
However with class names like your example it can sometimes definitely be desirable to add the qualifier as you may want the class to be re-usable on different type elements but have different properties depending on if it's a div or a p for example, the "qualifier" then makes the selector slightly more specific
.error {background: red; margin: 5px;}
p.error {margin: 2px;}
The code above means you can use the error class on any element and it will have 5px margins however if you set the error class on a p element the second selector is actually doing something, it's over-riding the first's margins but still getting the background color
So they do a job, but too often you see too many people over qualifying all their elements when it is not necessary.. for example if you're only ever applying that .error class to a p element then you wouldn't need the second selector.
The rule of thumb is to make the selector unique as quickly as possible starting from the right side of it.
Having a very specific selector will not amount to bad performance, but if there are a lot of declarations applicable for an element, then the performance will take a hit. The only concern otherwise is that it increases the no. of bytes to be downloaded for loading the stylesheet. Trust me, Every extra character in HTML passed is evil and will amount to lower page load speed.
During CSS cascading is applied by modern-day browsers, the following is the process that occurs for each CSS property for each web page element:
Gather all the declarations for the property from all the sources. This includes default browser styles and custom user style, as well as author style sheets. If there is more than one, proceed to 2.
Sort the declarations by importance and origin in the following order (from lowest to highest priority):
user agent style sheets (default browser styles)
normal declarations in a user style sheet (a user’s custom style sheet)
normal declarations in an author style sheet (web page style sheets; external, embedded, and inline styles)
!important declarations in an author style sheet
!important declarations in a user style sheet
The one with the highest priority wins. If more than one have the same priority then proceed to 3.
Sort by selector specificity. The one with the most specific selector wins. If no clear winner, proceed to 4.
The one that comes last in the source wins!
If the cascade does not set a CSS property on an element, then the browser will fall back to using an inherited property from the element’s parent (this only happens for some properties), otherwise the property is set to the CSS default value.
According to the above process, if you use a lot of more specific selectors, there would be a choice made after atleast 3 levels deep. Hence, the more the no. of declarations which might be applicable to an element, the lower the performance would be.
So, You must as specific as it makes sense to be.
The reason is specificity. For example...
+1 each access by class
+1 each access by tag
+10 each access by ID
etc.
So, if you have a class and a tag access, that style has a specificity of 2 (1+1).
Later, if you're trying to style all .error elements, but you have a conflicting style in the p.error elements, the higher specificity will win. This may cause some headaches down the line. That is why you may not want to always use tag+class.
(That being said, specificity solves many more problems than it creates, and is generally regarded as Pretty Awesome.)
As a general rule of thumb, the less selectors a browser has to evaluate the better.
p.error isn't necessarily "worse" than .error, if .error is used for multiple tags. e.g. div.error (see a foot note at the bottom).
But if it's only used on a paragraph anyway, then having p.error is just making the browser work harder i.e.
First it will have to find all elements with the class attribute error and then filter these by only having tags that are p.
Here is some interesting reading on Optimize browser rendering on Google's Page Speed site.
Foot Note
However if you need to use a class on multiple tags, it's probably best only to put in the css styles which apply to those tags instead of trying to separate it. e.g.
.error
{
color:red;
}
h1
{
font-size:2em;
}
p
{
font-size:0.8em;
}
<h1 class="error">Bad Heading!</h1>
<p class="error">bad!</p>
So that kind of defeats the need to prefix classes with tags anyway.
I hope this helps!