Decreased CSS Specificity with new HTML5 elements - css

Earlier to apply styles to a sidebar we would write the following
<div id="sidebar">
<p>Some text...</p>
</div>
and the corresponding CSS to set the color to Red would be like
#sidebar p{
color: Red;
}
The CSS Specificity here is {0,1,0,1}
In HTML5 We have the aside element that could be used as
<aside>
<p>Some text..</p>
</aside>
and the CSS to set the color to Red would be
aside p{
color:Red;
}
By using the HTML5 element the CSS Specificity is {0,0,0,2}
Using HTML5 elements improve the semantics. But HTML5 elements reduce the CSS Specificity. Provided that the target browsers support all HTML5 elements which among the 2 approaches would be appropriate?

Provided that the target browsers support all HTML5 elements which among the 2 approaches would be appropriate?
The latter approach using HTML5 elements would be the best approach, however there are two things to consider regarding rule specificity:
HTML5 is better at reducing clashes based on just element name alone as there are more of them, and when used correctly. Consider:
<div class="section">words...<div class="aside"><p>an aside</p>
versus
<section>words...<aside><p>an aside</p>
The latter is better as the semantics of the document are within the tags themselves.
When you are reusing a structure, its fine to add id and class attributes to make structure clearer.
<section>words...<aside><p>an aside</p>
<section>copyright...<aside><p>year of copyright</p>
versus
<section class="article">words...<aside><p>an aside</p>
<section class="copyright">copyright...<aside><p>year of copyright</p>
Here, the class on the latter adds context and reduces rule ambiguity.
So ultimately the answer to your question is use HTML5 elements intelligently with classes where appropriate.

According to MDN doc
The specificity is a weight that is applied to a given CSS
declaration based on the count of each selector type. In the case of
specificity equality, the latest declaration found in the CSS is
applied to the element. Specificity only applies when the same element
is targeted. CSS rules that directly target an element will always
take precedence over rules that an element inherits from an ancestor.
Then the tag, is lower then class, lower then id,
Also are evaluated External css link file precedence, and inner /in line css declaration.
For this kind of information you can refer to specific browser (engine)
for Mozilla you can refer to this doc https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
In your case you have a id css rule (more spcecific) and a tag css rule (minor specific)

Related

"*" is appearing top in CSS specificity, why?

I'm having trouble understanding why my CSS isn't being styled according to the way I understand the specificity rules. According to my reading across the web (including this calculator), the * (matches everything) has no specificity, while an element (e.g. h1,h2, etc) has is fourth most important, while a class is third most important. But that's not what I'm seeing in the Chrome debugger.
From the looks of it, the * has come out on top, followed by the h5, then two more * matches and then a match for the class .orange. Shouldn't the * be after everything else? And shouldn't the .orange win out over the h5? What is going on?
In your example, the * is the only selector that actually matches the element in question.
The other styles are only inherited by other element's definitions. These other elements are in a parent context with your element.
According to your screenshot, it must be some-element inside a structure like this:
<div class="row orange">
<div class="col-xs-10">
<h5 class="detail1">
<some-element></some-element>
With regard to your element, inherited styles do not have any specificity at all. Specificity is a concept that applies to CSS selectors, not CSS properties.
Specificity of inherited CSS properties

Do media queries affect precedence in CSS? Or why is this happening?

I was just looking at Inspect Element on one of my nested unordered lists and I noticed that one of my selectors with 2 ids is being ranked lower than the selector for a mere list element li. Does this have something to do with the media query that encloses the selector with 2 ids? Or why is this?
What you are seeing is not due to media queries but due to how inheritance is handled in CSS. Take the example below:
#super #specific {
color: blue;
}
p {
color: orange;
}
<div id="super">
<div id="specific">
<p>Paragraph text</p>
<div>Div text</div>
</div>
</div>
Even though you have a style that has a specificity value of 0200, the value of 0001 seemingly overrides it. From what I can tell the reason is due to how CSS calculates the specified value.
According to the spec, it first goes through the cascade to determine any values. If no values found then it will see if anything is inherited. Last it will use any default value for that element. Since the blue color in my example was passed to its inner elements through inheritance, that means that any CSS value applied to the inner elements would override that. It's also why the use of the inherit value in CSS is so important because it allows you to set inheritance as part of the cascade making sure those values take the correct precedence instead of just allowing it to default to it.

#id#id : Repeated occurrences of the same simple selector should increase specificity but don't for IDs in IE9

For some time now I'm using a little trick that I thought was smart.
That is combining the same css selector to add specificity to the rule's selector.
CSS Specs do mention :
Note: Repeated occurrances of the same simple selector are allowed and
do increase specificity.
http://www.w3.org/TR/css3-selectors/#specificity
For example if HTML is
<body>
<section id="main">
<header class="titles">
<h2>Title red</h2>
<h2 class="blue">Title blue</h2>
</header>
<h2 class="blue">Title blue</h2>
</section>
</body>
And CSS
#main .titles h2{
color: red;
}
#main .blue.blue{
color: blue;
}
This way I can use the class .blue to override styles, event in the header...
(I'm doing this because I hate using !important. To me it should be avoided at all costs.)
First selector weighs 0111 (1 id, 1 class, 1 element)
Second selector weighs 0120 (1 id, 2 classes)
Sometimes I do it with IDs. And it works... in real browsers...
This selector :
#main#main .blue{}
should weigh 0200, as it's got 2 IDs right?
Well IE9 (didn't try others) does not interpret multiple identical IDs in selectors.
This selector won't override #main .titles h2{} in IE9...
IE's css console shows a computed selector equal to #main .blue and removes the second occurence...
Why is that?
To me this is just another IE implementation "bug".
As #BoltClock suggested, I filed a report here :
https://connect.microsoft.com/IE/feedbackdetail/view/958790/repeated-occurrences-of-the-same-simple-selector-should-increase-specificity-even-with-ids
Yes, judging by the behavior shown in F12, this is definitely a bug. It's also a violation of the spec, if you interpret "do increase specificity" as "must increase specificity". This issue seems to only affect ID selectors. Class selectors, attribute selectors and pseudo-classes are OK.
This appears to have been reported before as when I search Microsoft Connect, it turns up an existing report, but I can't view it for some reason. The issue is still present in IE11; if you can't view the report either, feel free to file another one.

Is the CSS :not() selector supposed to work with distant descendants?

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.

What is the simplest way to implement pure css show/hide?

I discovered the <details> element for html5, and that made me want to determine whether it was possible to implement a simple and reusable show/hide via css alone.
I have created a show/hide mechanism in the past for showing and hiding content by giving two elements relative positioning and one a negative z-index, and then decreasing the z-index of the front element on hover (and increasing the z-index of the back element on hover).
However, that method only works for elements that are in the same location. Are there other techniques for simulating show/hide on non-overlapping elements? e.g. a title that causes a section of descriptive text to display.
Trivial example code that I would like to be able to apply a show/hide to:
<div id='container'>
<h3 id='show-hide-trigger'>summary</h3>
<p id='show-hide-text'>Paragraph of detail text paragraph Paragraph of detail text paragraph Paragraph of detail text paragraph Paragraph of detail text paragraph</p>
</div>
And yes, I do know that jQuery exists.
there is a plethora of options based on the structure (for modern browsers).
Have a look at the
selector + selector adjacent sibling selector
selector ~ selector general sibling selector
selector selector descendant selector
selector > selector child selector
These can be combined with classes / ids / pseudo-selectors like :hover etc, and create a big list of options.
here is a small demo i made to showcase them : http://jsfiddle.net/gaby/8v9Yz/
Try this using nested divs and targets.
I'm not a CSS guru, so there may be all kinds of flaws with this, but it seems to work.
http://jsfiddle.net/NmdxC/6/
#show {display:none ; }
#hide {display:block;}
#show:target {display: block; }
#hide:target {display: none; }
CSS without the exact code is hard to visualize, but what is wrong with changing the display or visibility declarations dangling from a :hover?
a #myelement{display:none;}
a:hover #myelement{display:block;}
I problably misunderstood the question...care to add code?
First thing that springs to mind is something like:
<a class="blah" href="#">Hello<span>Test</span></a>
a.blah {position:relative}
a.blah span {position:absolute;top:50px;left:50px;display:none;}
a.blah:hover span {display:block;}

Resources