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.
Related
I'm trying to figure out why one of my css classes seems to override the other (and not the other way around)
Here I have two css classes
.smallbox {
background-color: white;
height: 75px;
width: 150px;
font-size:20px;
box-shadow: 0 0 10px #ccc;
font-family: inherit;
}
.smallbox-paysummary {
#extend .smallbox;
font-size:10px;
}
and in my view I call
<pre class = "span12 pre-scrollable smallbox-paysummary smallbox ">
The font (The overlapping element) shows up as 10px instead of 20 - could someone explain why this is the case?
There are several rules ( applied in this order ) :
inline css ( html style attribute ) overrides css rules in style tag and css file
a more specific selector takes precedence over a less specific one
rules that appear later in the code override earlier rules if both have the same specificity.
A css rule with !important always takes precedence.
In your case its rule 3 that applies.
Specificity for single selectors from highest to lowest:
ids (example: #main selects <div id="main">)
classes (ex.: .myclass), attribute selectors (ex.: [href=^https:]) and pseudo-classes (ex.: :hover)
elements (ex.: div) and pseudo-elements (ex.: ::before)
To compare the specificity of two combined selectors, compare the number of occurences of single selectors of each of the specificity groups above.
Example: compare #nav ul li a:hover to #nav ul li.active a::after
count the number of id selectors: there is one for each (#nav)
count the number of class selectors: there is one for each (:hover and .active)
count the number of element selectors: there are 3 (ul li a) for the first and 4 for the second (ul li a ::after), thus the second combined selector is more specific.
A good article about css selector specificity.
Here's a compilation of CSS styling order in a diagram, on which CSS rules has higher priority and take precedence over the rest:
Disclaimer: My team and I worked this piece out together with a blog post (https://vecta.io/blog/definitive-guide-to-css-styling-order) which I think will come in handy to all front-end developers.
What we are looking at here is called specificity as stated by Mozilla:
Specificity is the means by which browsers decide which CSS property
values are the most relevant to an element and, therefore, will be
applied. Specificity is based on the matching rules which are composed
of different sorts of CSS selectors.
Specificity is a weight that is applied to a given CSS declaration,
determined by the number of each selector type in the matching
selector. When multiple declarations have equal specificity, the last
declaration found in the CSS is applied to the element. Specificity
only applies when the same element is targeted by multiple
declarations. As per CSS rules, directly targeted elements will always
take precedence over rules which an element inherits from its
ancestor.
I like the 0-0-0 explanation at https://specifishity.com:
Quite descriptive the picture of the !important directive! But sometimes it's the only way to override the inline style attribute. So it's a best practice trying to avoid both.
The order in which the classes appear in the html element does not matter, what counts is the order in which the blocks appear in the style sheet.
In your case .smallbox-paysummary is defined after .smallbox hence the 10px precedence.
First of all, based on your #extend directive, it seems you're not using pure CSS, but a preprocessor such as SASS os Stylus.
Now, when we talk about "order of precedence" in CSS, there is a general rule involved: whatever rules set after other rules (in a top-down fashion) are applied. In your case, just by specifying .smallbox after .smallbox-paysummary you would be able to change the precedence of your rules.
However, if you wanna go a bit further, I suggest this reading: CSS cascade W3C specification. You will find that the precedence of a rule is based on:
The current media type;
Importance;
Origin;
Specificity of the selector, and finally our well-known rule:
Which one is latter specified.
Also important to note is that when you have two styles on an HTML element with equal precedence, the browser will give precedence to the styles that were written to the DOM last ... so if in the DOM:
<html>
<head>
<style>.container-ext { width: 100%; }</style>
<style>.container { width: 50px; }</style>
</head>
<body>
<div class="container container-ext">Hello World</div>
</body>
...the width of the div will be 50px
AS is state in W3:
W3 Cascade CSS
the orden that different style sheet are applied is the following (quote from W3 cascading section):
user agent declarations
user normal declarations
author normal declarations
author important declarations
user important declarations
More information about this in the referred W3 document
Element, Pseudo Element: d = 1 – (0,0,0,1)
Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
Id: b = 1 – (0,1,0,0)
Inline Style: a = 1 – (1,0,0,0)
Inline css ( html style attribute ) overrides css rules in style tag and css file
A more specific selector takes precedence over a less specific one.
Rules that appear later in the code override earlier rules if both have the same specificity.
In a simple and short way, one should keep in mind the two things below:
Inline CSS has a higher priority than embedded and external CSS.
So final Order is: Value defined as Important > Inline > id nesting > id > class nesting > class > tag nesting > tag
Here is the official documentation for the CSS3 :not() pseudo-class:
http://www.w3.org/TR/css3-selectors/#negation
and the proposed CSS Selectors Level 4 enhancement:
http://dev.w3.org/csswg/selectors4/#negation
I've been searching the implementation and browser support for :not(), but the only examples I found were with a single element or with a direct child of an element, e.g.:
div *:not(p) { color: red; }
The example above works when <p> is a direct child of <div>, but it does not work when <p> is a more distant descendant of <div>.
div :not(p) {
color: red;
}
<div>
<ul>
<li>This is red</li>
</ul>
<p>This is NOT</p>
<blockquote><p>This is red but is not supposed to be!</p></blockquote>
</div>
If the answer is in the official documentation above, then I didn't find/understand it. As I said, I have searched this site and the web but couldn't find any discussion about the support or lack thereof of :not() as grand-children of another element.
Is this supposed to work like I think it should?
Is this supposed to work like I think it should?
No, the behavior you're seeing is correct.
In your last example, although the <blockquote> contains a <p>, it's the <blockquote> itself that's matching *:not(p), as well as the condition that it must be a descendant of the <div>, which it is. The style is applied only to the <blockquote>, but it is then inherited by the <p> inside it.
The <p> element itself still counts against the negation, so the <p> itself is still being excluded from your selector. It's just inheriting the text color from its parent, the <blockquote> element.
Even if none of its relatively close ancestors matched the selector, you have elements like html and body to worry about as well — although you could probably just tack on a body selector in the very beginning:
body div...
This is why I often strongly advise against using the :not() selector for filtering descendants, especially when not qualified with a type selector (like div in your example). It doesn't work the way most people expect it to, and the use of inherited properties like color only serves to compound the problem, on top of making it even more confusing for authors. See my answers to these other questions for more examples:
Why doesn't this CSS :not() declaration filter down?
CSS negation pseudo-class :not() for parent/ancestor elements
The solution to the problem described is to simply apply a different color to <p> elements. You won't be able to simply exclude them with a selector because of inheritance:
/* Apply to div and let all its descendants inherit */
div {
color: red;
}
/* Remove it from div p */
div p {
color: black;
}
On Selectors Level 4: yes, :not() has indeed been enhanced to accept full complex selectors that contain combinators. Essentially, this means (once browsers begin implementing it) you will be able to write the following selector and have it do exactly what you want:
p:not(div p) {
color: red;
}
In case anyone is interested, this works in jQuery today.
The color is assigned to the blockquote, and is then inherited by the p.
:not(p) just makes it so that the styles are not directly applied. They are still inherited though.
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.
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.
Given this:
<a class="details" href="#">more…</a>
...
<input type="submit" value="Gogogo">
Say that both should have very similar appearance, because that's what the designer wants. Do you do this:
<a class="fancybutton" ...
<input class="fancybutton" ...
.fancybutton { /* ... */ }
or this?
a.details, .someform input[type="submit"] { /* ... */ }
I'm struggling with this issue and I'm not sure where to go. It seems to be a choice between having a really clear stylesheet vs. nice markup that isn't littered with classes.
When do you choose one over the other?
The main reason to choose classes over more fancy CSS selectors is compatibility. Several versions of at least one major browser still in use don't support more advanced selectors properly and thus it's actually less painful to just use classes, since they "just work".
IE6 doesn't support input[type=submit], so if I'm developing for it, I'll definitely go for the class.
I'd generally use class because that has wider support than attribute selectors amoung browsers. Until the vast majority of the population have a browser that supports the CSS attribute selectors I would continue to uses classes in such a case.
I'd say, within complaint browsers, that the answer is specificity. Look to the breadth of the application of the style and define it with sufficient specificity to be unambiguous within the scope of your web-app.
Also, don't be afraid to use more than 1 style class on an element to develop a layered presentation approach, i.e. class="blackborder smalltext centred".
Like other users have said, using classes is good because it really simplifies the question of browser compatibility (problems arise when you try to use fancy CSS 2 selectors).
Another great reason to use simple class-based (or id-based, if possible) selectors over complex CSS 2 selectors is speed.
From google's "Optimize browser rendering", descriptions of why you should try to use simple selectors (class-only/id-only selectors are very simple):
Descendant selectors are inefficient because, for each element that matches the key, the browser must also traverse up the DOM tree, evaluating every ancestor element until it finds a match or reaches the root element. The less specific the key, the greater the number of nodes that need to be evaluated.
Child and adjacent selectors are inefficient because, for each matching element, the browser has to evaluate another node. It becomes doubly expensive for each child selector in the rule. Again, the less specific the key, the greater the number of nodes that need to be evaluated. However, while inefficient, they are still preferable to descendant selectors in terms of performance.
And a specific note about class-selectors over descendant selectors from the same article:
Use class selectors instead of descendant selectors.
For example, if you need two different styles for an ordered list item and an ordered list item, instead of using two rules:
ul li {color: blue;}
ol li {color: red;}
You could encode the styles into two class names and use those in your rules; e.g:
.unordered-list-item {color: blue;}
.ordered-list-item {color: red;}
If you must use descendant selectors, prefer child selectors, which at least only require evaluation of one additional node, not all the intermediate nodes up to an ancestor.