I firstly say that i don't know anything about how css rules are assigned to DOM elements by browser, so that my question is more around it, but i got wondering this in this particular situation I got into, so I use it for formalizing my curiosity:
I do have an HTML snippet like this:
<section>
<div>I'd like to be blue</div>
<div style="color:green">I am quite <p style="font-weight: bold">self confident</p> about my styles</div>
<p>I'd like to be biig</p>
</section>
The text's content of the divs tries to describe my requirements: The first div MUST be blue, the second one i don't care because I will probably use inherited properties or I will set through js or whatever.
The p should be bold,
So I want to assign styles to do that, and I do something like this:
section div {
color: blue;
}
section p {
font-weight: bold;
}
And that obviously works as expected. But, CSS has nice features to target more specific elements. So I could do, for doing the same thing:
section > div:first-child {
color: blue;
}
section > p {
font-weight: bold;
}
This will affect only elements that are direct children of the section, and only the first div of the set, so that i will have the same result, but selecting elements more specifically.
I wonder if this helps browsers assigning css rules to elements.
I think that at some level the browser check for each DOM element the css' rules that target it, and if it finds matches (a css class is actually targeting it), it checks for conflicts and performs overriding if needed.
Would excluding elements from that sets, by targeting them more specifically help the browser to assign style (increase performance or decrease) ?
If it increases, is it meaningful or it is so little that everyone ignores it ?
If it decreases, how much and why ?
Thanks for any advice.
According to this article from Mozilla Development Network, the more specific your selectors are, the better. So if you do not bother how many divs get colored blue, the general selector section div is better. The longer your selector chain is, the harder it is for the browser to find that element since it needs to match more things. The most performant option in this case would actually assigning a class named for example .blue to the div you want blue.
The element>element (direct child) selector is more performant than the element element (descendand) selector in the sandbox but will probably force you to write a longer selector chain if you wish to overwrite it at another point.
To answer your question, in your example (at least in a nutshell), the overall performance will probably decrease by a little (meaningless) bit since pseudo-elements like :first-child are the least performant selectors and you furtherly have a longer selector chain.
If you actually asked me which of those to use in a project with more than just six lines of css, I'd encourage you to use the first example aswell since it's much more easy to overwrite and reuse.
Related
So, I was looking at a tut on youtube the other day, and this guy kept defining css rules with classes really weirdly, and I wondered if one of u guys could explain the necessity of it: here is the code:
ul.class li{
color:#fff
}
Why can't he just do:
.class{
color:#fff
}
Thank you for reading my question, I hope you understand what I am asking for.
Video: https://youtu.be/2wCpkOk2uCg
P.S - Sorry for the giganticly large title š
When you put the element before the class, CSS only applies the styles to the members of that class that are of that specific element.
For example, if you had .class applied to 3 headers and 3 paragraphs, writing p.class would only affect the paragraphs.
With ul.class you're saying "Apply this styles to all the ul's with this class. If you only use .class you're saying "Apply this styles to ANYTHING that has this class". It's very different. :)
I can think of at least two reasons to include the element name as well as the class:
Specificity, i.e., which CSS rule takes effect on a target element when multiple rules apply to to it. There is a specificity algorithm that determines which rule is applied when multiple rules are in competition. This awesome Specificity Calculator is a great tool to help you understand the algorithm. So, in short, including the element name and the class gives it additional weight.
Documentation in your CSS. I tend to include the element as well as the class, e.g. h1.customer-name, to self-document what type of element the rule is being applied to. When I see .customer-name without the element name, I am not totally confident in what type of HTML element it is. Doing this means I don't have to keep the HTML structure in my head or consult the HTML repeatedly while I work on CSS. But this is pretty dependent on one's approach to CSS as well as the tools used, so I'm not sure I would consider it a good idea across the board.
And one more, but not least important thing. If you adding the tag name before the class name (such as span.class{}), so you got more specific rule and it's have bigger priority (no matter in which order that rules writter in css file). For example, if you write two rules:
.class { color: red }
and
span.class { color: blue }
you will get a blue text as a result.
I read an article with some css file
#mainNav #toTop a {
float: right;
margin: 0 8px 0 0;
font-size: 40px;
}
Can someone explain why they have two # things in one css id type ? and how can I use it?
Thank you in advance
I don't know what you mean by a "CSS id type". So I'm just going to explain CSS in general, and we'll see if what this snippet is doing becomes clear.
In CSS you have selectors and property blocks. Your question is about a selector:
#mainNav #toTop a
Selectors are used to target (and on some other platforms to query) HTML (and sometimes XML) elements. This particular rule is using three simple selectors - two id selectors and a tag name selector - put together with two descendant combinators.
That means the selector will target (and the rule block accompanying it will affect) any anchor element (<a>) which is the descendant of any element with id=toTop which in turn is the descendant of any element with id=mainNav.
Since id elements are supposed to be unique, it might seem silly to have two of them in one selector. You can do it if you want to though, and sometimes you'll need to: we haven't spoken about selector specificity.
Specificity defines which rules take precedence over other rules. For example, if two elements both seem to target the same element:
form .label { color: blue; }
#contact-us .label { color: green; }
/* what color is the label? */
... then which rule takes precedence? To figure that out we calculate the specificity. I won't explain the math.
So, let's suppose you have a CSS stylesheet in your project which you can't change - it comes from a 3rd party vendor or something, and it looks like this:
#toTop a { /*...*/ }
If you needed to change the styling of the elements affected by that rule, what would you do?
You could (and probably would) define a new rule with greater specificity. One of the ways you can do that is by adding another id selector to your rule:
#mainNav #toTop a { /*...*/ }
But realistically you could just as easily add any other selector:
div#toTop a { /*...*/ }
Realistically whether it's necessary or not depends on what you're trying to do, what other rules it's interacting with, and what kind of HTML you're dealing with.
Here's another thing to consider: CSS stylesheets are meant to be re-used. What if that element should behave differently if it is in a different place in the document? What if the id="toTop" is sometimes inside the id="mainNav" element on some pages, and in a different place (let's say in the id="footer" element) on others? What if it moves, depending on client-side JavaScript? Then you might want to define CSS like this:
#mainNav #toTop a { /*...*/ }
#footer #toTop a { /*...*/ }
... so ultimately again, why a developer would choose to do this really depends on the CSS, JavaScript and HTML they are working with. It's definitely unusual, but it's not unnecessary nor bad practice.
ID must always be unique. However it is valid to use more than one id to make styles more specific.
In your example you are looking for an element with id #toTop inside #mainNav.
This is a perfectly valid CSS rule. It is very specific. The motivation for this use may have to do with how the page layout is designed and/or how JavaScript handlers interact with the DOM.
This is an example of poor CSS. The selector hierarchy in your example is redundant and unnecessary. It says select all a elements that are descendants of the element with the ID of toTop that is a descendant of the element with the ID of mainNav. So it assumes a basic structure like this:
<div id="mainNav">
<div id="toTop">
link
</div>
</div>
However, as IDs must be unique, only this is needed to target the same elements:
#toTop a
#mainNav #toTop a is using the Descendant Combinator to specify an element a descendant of an element with id toTop descendant of an element with id mainNav.
As said by other answers, this rule seems to be overly specific, because IDs must be uniques and then #toTop a should do the trick.
The real reason behind the choice of declaring this rule is:
Assuming that in a website you have one or more shared CSS (read:
you don't have an different CSS for every page), this rule means:
in a page where a is descendant of #toTop, but #toTop is descendant of an #mainNav element too, then apply this rule;
in a page where a is descendant of #toTop, but #toTop is NOT descendant of an #mainNav element, then DO NOT apply this rule;
because #toTop could be an reusable element that could be declared in different places (one-per-page, of course), for example inside the #mainNav in a page, and inside the #sideNav in another page, with a desired potentially different behavior and look-and-feel.
Let's say I have some deeply nested markup that I want to target with CSS. It could be anything, but for example:
<div>
<div id='someid'>
<span class='someclass'>
<a class='link' href='alink'>Go somewhere</a>
</span>
</div>
<div>
Is it acceptable to write a CSS rule targeting the <a> tag directly, like this?
a.link { font-size: large; }
Or is this considered non-standard that may fail in some browsers? Do I need to target each element in the chain like this?
div div span.someclass a.link { font-size: large; }
Both are completely acceptable to use and the answer depends on your specific solution. For instance if you have other areas where you are sharing common properties that are defined by that class you'd want to keep it as general as possible. If for instance you have a navigation and the links in that area share some common elements those could be defined by a.link
Then in your nested html, you might do something like
.someclass a.link {font-size:8px} to make that text smaller.
Here is an article that discusses how the specificity works: http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
Both are perfectly valid, and which one you use depends on what you want to do.
If you are creating a generic class that you want to be able to use throughout your entire site regardless of element and where the element is, you should only use .class. A good example for this is something like .icon which you may want to use on links, list items, headings etc. And you want to be able to use them everywhere.
If you're creating a class that is specific to/only works on one certain type element, it's best to use the element in the selector as well. An example of this would be a bullet list you want to display on one line, since this class requires the HTML to be a <ul> you should specify it in the CSS as well; ul.inline. This way you can use the "inline" class name for other elements as well, without the styling affecting both.
If you're only using the class in order to select the element but it shouldn't have any generic styling you should be specific. For example, you may want the first paragraph in your #blog-post element to be larger, then you should specify both #blog-post and the class; #blog-post p.first (note that these types of classes are rarely needed anymore thanks to advanced selectors like :first-of-type, h2 + p etc).
Saying that ".link is the best, a.link is second best and a long selector is bad" is just wrong. It all depends on the situation.
The more targeted you make your CSS the less flexible it becomes. It's your own trade off. If you are going to give the links a specific class like that I am pretty sure they'll be visually the same whether they appear inside this tree or outside of it so you can stick with your first example.
It's actually recommended to use a.link instead of the long, ugly second option, which can cause specificity and performance issues.
It's even better if you use just .link. That's the best option.
a.link is the best way to do it. If you want a certain a.link to be different from the rest, you'll need to add some weight to it.
a.link { ... } /* Global */
span.someclass a.link { ... } /* Finds all a.link within span.someclass */
Descendant selectors (line 2) aren't the most efficient way to add style to an element, so use them sparingly. Personally, I use them when I need to give special styles to a Global Class within a certain ID/Class.
First of all, I've seen this question IE Compatibility issue, but I have a slightly different issue:
I have a span with display: block and I want to put a H2 tag inside it. Will this look good in every (major) browser?
The answer on the previously stated link, was to make the H2 display:inline, which I don't want, and also I don't want to replace the span with a div, because I would have to change a lot of CSS.
PS. I don't want my HTML to validate (using the validator), I just want it to work.
When you say "I don't want my HTML to validate (using the validator), I just want it to work." You're making a very big mistake. If HTML doesn't validate, there's no telling what might happen. The standards are there for a reason.
Replace the span with a div, you don't need display block on the div as it has this by default. A span is an inline level element, whereas an H2 is block level. An inline element cannot contain a block level element (true up to HTML5, where you can wrap block level elements in anchors)
This will validate, and will work!
It works on current browsers (including old versions), and it is unlikely that this will change. Errors like this are common enough to make it rather pointless to browser vendors to change their error recovery mechanisms. HTML5 is about to make the error recovery rules mandatory.
On the other hand, what is the point of using span with display: block, instead of using div? And CSS should be written so that it does not depend on specific choices of markup elements where different choices could make sense; for example, as a rule, .foo is a better selector than span.foo.
Any extensive change to markup or style sheets has a nonnegligible risk of causing problems even when the change is a such an improvement and a simple one. (For example, a global search and replace often does too much, or misses something.) This could be a reason for continuing the use of invalid markup, in cases where it has minimal risk in practice.
we can solve IE second line problem first
h2{}
h2 span{ float:right;}
Correct way in all browsers
<h2><span>sub content</span> Heading</h2>
wrong way ie browser
<h2>Heading<span>sub content</span></h2>
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!