multiple colons in css - css

I have seen a line of code in CSS looks like this:
[icon]:not([focused]):not([pressed]):not([disabled]){ background-position-y:-0px; }
What is the meaning of the multiple colons in this case? Are they still Pseudo selectors?

It's not pseudo-selectors - it's selectors for pseudo-classes. Quoting the W3C Selectors Level 3 doc:
6.6.7. The negation pseudo-class
The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument. [...]
The following selector matches all button elements in an HTML document
that are not disabled.
button:not([DISABLED])
The following group of selectors represents all HTML elements except links.
html|*:not(:link):not(:visited)
The last example (as well as this answer) shows that it's quite valid to use a chain of several :not pseudo-class selectors, if what you want is setting a rule for some element that is not either of several mentioned types.
In your case the selector catches all the elements with icon attribute set (to any value) - except those that have either focused, pressed or disabled set (again, to any value) as well.

Related

Does CSS selector .class-xyz:not(.class-xyz) ever match?

Given any CSS with a selector like:
.class-xyz:not(.class-xyz) {
...
}
Is it possible that it ever matches any element?
What about augmenting it with things like ::after, ::placeholder and so on?
My intent is to simplify a bunch of huge CSS sheets, with lots of selectors like this.
That selector will not match any element, regardless of namespace (since, even with namespaces present, the outside .class-xyz represents the default namespace, and the one inside the negation always considers the same namespace as the outside selector).
Since that selector will not match any element, it follows that no pseudo-element will be matched. For a pseudo-element to apply, elements need to be matched in the first place.
If you wish to hide a CSS rule without outright deleting the rule or tampering with the original portion of the selector, a shorter way to do so using the negation pseudo-class would be :not(*) (or, if namespaces are present, :not(*|*)). This use case is explicitly given in the level 3 and 4 specs.
But the shortest and clearest way to hide a CSS rule by far is to comment it out.

What is the difference between E:dir(dir) and E[dir="dir"] in CSS? [duplicate]

This question already has answers here:
What's the difference between html[lang="en"] and html:lang(en) in CSS?
(4 answers)
Closed 6 years ago.
W3C is introducing a new pseudo-class for direction detection in Selectors 4. I am wondering what is the difference between that and a normal attribute selector:
CSS2 - attribute selector
E[dir="rtl"] { ... }
Selectors 4 - dir pseudo-class
E:dir(rtl) { ... }
Is there a specific reason for creating a new pseudo-class for that? Are these selectors identical or do they behave differently? Are there any performance or specificity implications?
Is there a specific reason for creating a new pseudo-class for that?
The same reason the :lang() pseudo-class was introduced alongside attribute selectors in CSS2.1 See What's the difference between html[lang="en"] and html:lang(en) in CSS?
Are these selectors identical or do they behave differently?
See my answer to the linked question. Here's the relevant quotation from Selectors 4 for the sake of completeness:
The difference between :dir(C) and ''[dir=C]'' is that ''[dir=C]'' only performs a comparison against a given attribute on the element, while the :dir(C) pseudo-class uses the UAs knowledge of the document’s semantics to perform the comparison. For example, in HTML, the directionality of an element inherits so that a child without a dir attribute will have the same directionality as its closest ancestor with a valid dir attribute. As another example, in HTML, an element that matches ''[dir=auto]'' will match either :dir(ltr) or :dir(rtl) depending on the resolved directionality of the elements as determined by its contents. [HTML5]
To drive the point home on the similarities between :dir() and :lang(), if you look closely the first sentence is in fact a word-for-word copy of the same paragraph in the section describing :lang().
Much of the rest of the text for :lang() is new, however, because along with :dir(), Selectors 4 also introduces enhanced functionality for :lang().
Are there any performance or specificity implications?
Since the answer to your previous question is that they behave differently, performance is irrelevant.
No specificity implications because pseudo-classes and attribute selectors are equally specific.
1 It's not clear to me why it took almost 15 years for :dir() to be added to Selectors, but there you go.
According to MDN, some subtle differences exist:
The :dir CSS pseudo-class matches elements based on the directionality
of the text contained in it. In HTML, the direction is determined by
the dir attribute. For other document types there may be other
document methods for determining the language.
Note that the usage of the pseudo-class :dir() is not equivalent of
using the [dir=…] attribute selectors. The latter matches a value of
the dir and doesn't match when no attribute is set, even if in that
case the element inherits the value of its parent; similarly [dir=rtl]
or [dir=ltr] won't match the auto value that can be used on the dir
attribute. In the opposite, :dir() will match the value calculated by
the UA, being inherited or the auto value.
Also :dir() considers only the semantic value of the directionality,
the one defined in the document, most of the time in HTML. It won't
consider styling directionality, the one set by CSS properties like
direction which are purely stylistic.

Does :not() negation accept descendant selectors? [duplicate]

This question already has answers here:
:not() selector not behaving the same between Safari and Chrome/Firefox
(2 answers)
Closed 6 years ago.
I've been using the :not() pseudo-class to style things without the need to override it with a second unnecessary declaration to undo the first one,
but now I came across a weird behaviour where Safari accepts descendant selectors within the :not(), but Chrome doesn't.
I used something like a:not(.blue a).
I searched for answers, but I still don't fully understand the reason.
Are descendant selectors really allowed by the spec?
Here's a demo:
a:not(.blue a) {
color: red;
}
<div><a>this one should be in red</a></div>
<div class="blue"><a>this one shouldn't</a></div>
http://codepen.io/oscarmarcelo/pen/YqboQJ?editors=1100
In Selectors Level 3, the answer would be NO. The :not() notation accepts only simple selectors.
6.6.7. The negation
pseudo-class
The negation pseudo-class, :not(X), is a functional notation taking
a simple selector (excluding the negation pseudo-class itself) as an
argument. It represents an element that is not represented by its
argument.
What is a simple selector?
From selector syntax:
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
Nothing about a descendant selector.
HOWEVER, in Selectors Level 4, :not() accepts complex selectors, which would include descendant combinators. Browser support is still quite weak for this specification.

Correct terms and words for sections and parts of selectors

What is the correct term for the sections of CSS selectors that are separated by commas?
body.foo .login , body.bar .login { ... }
/* |
Part 1 | Part 2 */
Within those sections, what is the term for the parts separated by combinators (spaces, +, >, etc)?
body.foo .login , ... { ... }
/* |
Part 1 | Part 2 */
What is the correct term for the sections of CSS selectors that are separated by commas?
These are called complex selectors. The entire comma-separated list is known as a selector-list.
Within those sections, what is the term for the parts separated by combinators (spaces, +, >, etc)?
These are known as compound selectors.
So, a selector-list is made up of one or more complex selectors separated by commas, and each complex selector is made up of two main parts: compound selectors, and combinators. It can also optionally contain pseudo-elements.
Compound selectors used to have the rather convoluted name "sequence of simple selectors". Worse still, complex selectors were just called "selectors". Needless to say, I recommend using the new terms as they are much more straightforward, much less cumbersome and completely unambiguous compared to their predecessors.
And since I'm here, here are the rest of the definitions...
A simple selector is one fundamental component of selectors. It is any one of the following:
Universal selector (*), optionally with a namespace
Type selector (a, div, span, ul, li, etc), optionally with a namespace
Attribute selector ([att], [att=val], etc), optionally with a namespace
Class selector (.class)
ID selector (#id)
Pseudo-class (:pseudo-class)
As answered above, a compound selector (formerly a "sequence of simple selectors") is a chain of simple selectors not separated by a combinator:
a:not([rel="external"]):hover
A combinator is another fundamental component of selectors. It is a symbol or token that separates two compound selectors, establishing in its place a relationship between the two elements represented by the two compound selectors. There are currently four combinators in use today:
Descendant combinator:
article p
Child combinator:
/*
* The extra spaces in between are whitespace,
* and are therefore insignificant.
*/
ul > li
Adjacent sibling combinator:
header + section
General sibling combinator:
h2 ~ p
More combinators may be introduced in later specifications.
And a complex selector (formerly just "selector") is a complete string made up of compound selectors linked by combinators:
nav[role="main"] > ul:first-child > li
The subject of a complex selector is its last, or only, compound selector, representing the element that will be matched or styled. In the above example, the subject of the selector is li.
The term selector has been generalized, so it may now refer to any of the following for the purposes of simplicity and brevity, and which one it's referring to at any given moment should be gleaned from context:
Simple selector
Compound selector
Complex selector
Selector-list (e.g. the "selector" component of a style rule)
Some personal notes:
The term "key selector" was coined by browser vendors for use with selector implementations, and is not an official term. It is often used to mean "subject of the selector" however, because implementations happen to use the subject of the selector as the key for the purposes of determining matches.
The term "pseudo-selector" was coined by authors to mix pseudo-classes and pseudo-elements, and is not an official, or indeed meaningful, term. Although you can find it in some early-stage W3C CSS2/3 drafts, that was probably a mistake. Please don't use this term, as it needlessly creates confusion by attempting to group two completely different concepts into a single umbrella term.
Pseudo-elements (::pseudo-element) are not simple selectors, and therefore cannot appear in places where only actual elements may be matched. However, they are still considered selectors for the purposes of CSS parsing, and as stated above currently can appear at the end of any complex selector in a list (i.e. at the end of the last, or only, compound selector of each complex selector).
In CSS, a typical style rule (formerly "ruleset") consists of a selector and a declaration block.
Namespace prefixes are not selectors in their own right, but they may be applied to type selectors, universal selectors and attribute selectors to match components in a document that are (or are not) namespaced.
The specificity of a selector currently only refers to that of a single complex selector. When matching rules, any of the complex selectors in a list that match a given element will be considered for specificity calculations. If more than one complex selector matches an element, the most specific one will be used for calculations.
Specificity will be a more complicated issue with some level 4 selectors, such as :is() and the enhanced :not(), and the of S notation in the enhanced :nth-child() pseudo.
The specification offers terminology for this:
A selector is a chain of one or more sequences of simple selectors separated by combinators. One pseudo-element may be appended to the last sequence of simple selectors in a selector.
A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
Combinators are: whitespace, "greater-than sign" (U+003E, >), "plus sign" (U+002B, +) and "tilde" (U+007E, ~). White space may appear between a combinator and the simple selectors around it. Only the characters "space" (U+0020), "tab" (U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form feed" (U+000C) can occur in whitespace. Other space-like characters, such as "em-space" (U+2003) and "ideographic space" (U+3000), are never part of whitespace.
There are some small terminology differences between CSS 2 and 3
the list of basic definitions (selector, group of selectors, simple selector, etc.) has been changed; in particular, what was referred to in CSS2 as a simple selector is now called a sequence of simple selectors, and the term "simple selector" is now used for the components of this sequence
The parts separated by commas are called selectors.
Within a selector we have simple_selectors and combinators.
See the grammar.

What's the difference between html[lang="en"] and html:lang(en) in CSS?

The CSS language pseudo-class to allow us specify different styles for different languages, like so:
html:lang(en) .foo { ... }
However, this doesn't work in IE7, so I've been using an attribute selector:
html[lang="en"] .foo { ... }
They seem to do the same thing, but are there any subtle differences? And if not, why does CSS even have a language pseudo-class, when the attribute selector does the exact same thing?
In HTML, both the :lang() pseudo-class and the attribute selector will match an element with the corresponding lang attribute.
The difference is that a browser may have other ways of determining the language of a given element when testing against the :lang() pseudo-class which may be defined by the document language and/or the implementation, whereas an attribute selector will only check an element for that given attribute, without any accompanying document-based semantics.
For example, in HTML, the pseudo-class will also match any of the element's descendants for which there isn't a different lang, depending on how a browser determines the language for those descendants. Usually, the descendants will inherit the language attribute from their ancestor if it is not explicitly set.
Here's what the spec says:
The difference between :lang(C) and the ‘|=’ operator is that the ‘|=’ operator only performs a comparison against a given attribute on the element, while the :lang(C) pseudo-class uses the UAs knowledge of the document's semantics to perform the comparison.
In this HTML example, only the BODY matches [lang|=fr] (because it has a LANG attribute) but both the BODY and the P match :lang(fr) (because both are in French). The P does not match the [lang|=fr] because it does not have a LANG attribute.
<body lang=fr>
<p>Je suis français.</p>
</body>
Notice the specific phrasings of "has a LANG attribute" and "are in French". These two phrases have very different meanings in English, as you might imagine.
In your example, the following selector will also match your .foo element:
.foo:lang(en)
But the following selectors won't, if it doesn't have its own lang attribute set:
.foo[lang="en"]
.foo[lang|="en"]
As for browser support, the :lang() pseudo-class is supported starting from IE8, so IE7 really is the only browser you will be unable to support by using the pseudo-class over the attribute selector.
Based on this understanding you can then answer the question "which should I use": you should always use the :lang() pseudo-class by default, unless certain quirks (or the need to support IE7) require working around by using an attribute selector instead.
Selectors 4 not only brings enhanced functionality to the :lang() pseudo-class (thereby widening the gap in functionality between it and attribute selectors), but also introduces the :dir() pseudo-class for matching elements based on their directionality. Because directionality is a language-related property, the dir and lang attributes work similarly in HTML, and the difference between :dir() and its corresponding attribute selector is analogous to that between :lang() and its corresponding attribute selector — to the point where the first sentence of the following quotation is in fact a word-for-word copy of the same paragraph in the section describing :lang():
The difference between :dir(C) and ''[dir=C]'' is that ''[dir=C]'' only performs a comparison against a given attribute on the element, while the :dir(C) pseudo-class uses the UAs knowledge of the document’s semantics to perform the comparison. For example, in HTML, the directionality of an element inherits so that a child without a dir attribute will have the same directionality as its closest ancestor with a valid dir attribute. As another example, in HTML, an element that matches ''[dir=auto]'' will match either :dir(ltr) or :dir(rtl) depending on the resolved directionality of the elements as determined by its contents. [HTML5]
One more thing that wasn't mentioned by anybody else - :lang() pseudoclass isn't interested in how one sets the element's language. In XHTML document (true XHTML with XML MIME type), you can use xml:lang="en" and the element will match :lang(en) but not [lang="en"].
According to the spec,
If the document language specifies how the human language of an element is determined, it is possible to write selectors in CSS that match an element based on its language. For example, in HTML [HTML4], the language is determined by a combination of the "lang" attribute, the META element, and possibly by information from the protocol (such as HTTP headers). XML uses an attribute called xml:lang, and there may be other document language-specific methods for determining the language.
The pseudo-class ':lang(C)' matches if the element is in language C. Whether there is a match is based solely on the identifier C being either equal to, or a hyphen-separated substring of, the element's language value, in the same way as if performed by the '|=' operator. The matching of C against the element's language value is performed case-insensitively for characters within the ASCII range. The identifier C does not have to be a valid language name.
That is:
It works for the many other ways of specifying a language besides the simple lang attribute.
Most importantly, as detailed in #BoltClock's answer, it will use the language specified (in whatever manner) on a container element, not just on the element itself, since language is inherited by child elements.
It uses |= semantics, i.e. :lang(en) and :lang(us) will both match span[lang=en-us].
It is guaranteed to be case-insensitive, whereas
The case-sensitivity of attribute names and values in selectors depends on the document language.
Css supports attribtue selectors for all elements, not just for the html tags lang attribute. For example html like <a title="Jeeha" href="foo.html">bar</a> could be selected like a[title=Jeeha] { ... } in css.
See this link for more details on partial matches and variants.

Resources