Can the Universal selector * be replaced by :lang? - css

The universal selector asterisk (*) is unique in that it matches a single element of any type.
So if I have different elements within a div and I want to select them all with one selector, I can either add a class to all the inner elements (something like .parent .class {}) or I can use the universal selector (.parent * {})
Then I saw the spec for the :lang pseudo element (particularly the end):
Note the difference between [lang|=xx] and :lang(xx). 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).
<body lang=fr>
<p>Je suis Français.</p>
</body>
Which means that all elements within an element targeted by :lang selector are also targeted. (Wow!)
So let's say I wanted to add a border to all the elements within a div - instead of the selector div * {} I could theoretically use :lang
Here's a demo
As far as I can tell, the only difference is that the :lang selector selects the parent as well as all the children (and of course there's the technical difference the :lang has greater specificity)....however
if the :lang selector was applied in a semantic way that it included the whole document - with the lang attribute on the html element - I don't think that the above difference would matter.
So basically my question is:
Assuming that my html element has the attribute lang="en":
Can I replace code which uses the universal selector such like:
* { box-sizing: border-box; }
with:
:lang(en) {
box-sizing: border-box;
}
The code seems to work (DEMO), and it seems to be semantic as well, but I'm wondering if there are certain reasons/cons to the above technique.

Can the Universal selector * be replaced by :lang?
No, because you cannot write a selector using :lang() that is guaranteed to match all elements unless you assume all elements in the document will always be in the same language.1
If you're going to assume that all elements are in the same language, then using the :lang() pseudo is pretty pointless, since the whole point of that pseudo-class is to be able to distinguish parts of the document that differ in their content language.
Also note that the compound selector :lang(en) (consisting of just that one simple selector) is equivalent to *:lang(en). It is essentially the * selector with an additional qualification of a pseudo-class. You are not avoiding the use * by replacing it with :lang().
1 Selectors 4 allows a selector like :lang('*') to be written that matches elements in any language (which, again, is pointless if you don't care what language an element is in!), but this assumes the document even has content language semantics built into it. It is not clear if :lang() will work at all in a document lacking such semantics.

Related

Using CSS selectors and combinators (*, ~, >, <, +)

I am working with CSS selector symbols to create complex element selectors. I am currently stuck with selector symbols which I cannot create combinations with.
For instance, I am trying to create: body and children elements of body that are not of #foo id using
body > *:not(#main-div) + body
but the combinations of the elements don't work. I have used each of the selectors individually at least once before, but never tried their combinations. This feature seemed very useful to me and so I wanted to know whether it is possible to create combinations of these selector symbols. If yes, what is the correct syntax to follow?
In order to apply styles to both the body and all immediate children of the body (excluding the #main-div) element, you should use the following selector list:
body,
body > *:not(#main-div) {
...
}
Commas should be used to group selectors into selector lists. The + is an adjacent sibling combinator.
The Mozilla Developer Docs has a great primer on forming CSS selectors and rulesets here: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors
This feature seemed very useful to me and so I wanted to know whether it is possible to create combinations of these selector symbols. If yes, what is the correct syntax to follow?
Yes it is possible but i think the syntax you are using is incorrect instead you must use
body > :not(#main-div),body
And according to me there's no use of * and + because by even not mentioning * it will exclude all the id's that are #main-div and + is only used when the element is right after the current element.

how important the space between tag and class?

I read corresponding part of http://www.w3.org/TR/CSS21/selector.html#class-html but can't find clear note that space between dot-class and tag change meaning. According to spec tag.clazz is equivalent to tag[class~="clazz"], and I expect that tag .clazz is equivalent to tag *.clazz. Is that true?
I expect that tag .class is equivalent to tag *.clazz. Is that true?
No. This is because class and clazz is not the same.
However, if you meant tag .clazz and tag *.clazz, then yes.
Explanation:
tag .clazz means any element with the class clazz somewhere
inside a tag tag.
tag *.clazz means any element of any tag name (*) with the class clazz somewhere inside a tag tag.
…which is effectively identical. The space essentially means “somewhere inside”.
5.2 - Selector syntax
A simple selector is either a type selector or universal
selector followed immediately by zero or more attribute
selectors, ID selectors, or pseudo-classes, in any
order. The simple selector matches if all of its components match.
Note: the terminology used here in CSS 2.1 is different from what
is used in CSS3.
A selector is a chain of one or more simple selectors separated by
combinators. Combinators are: white space, ">", and "+". White space
may appear between a combinator and the simple selectors around it.
So a space between a type selector and a class selector is a descendant combinator.

Using CSS pseudo and attribute selectors together

Because of a bug in webkit browsers, you can't use attribute and :before/:after classes by default.
The fix doesn't seem to have any effect when using nth-last-of-type selector.
Here's what I'm doing:
.left[class^='col']:nth-last-of-type{
margin-right: 0 !important;
}
Just wanted to check and see if I'm not overlooking something simple.
Your :nth-last-of-type syntax is a bit off — it's either :last-of-type or functional :nth-last-of-type() with a formula an+b as an argument.
The pseudo-classes pertaining to "type" refer to the element type, represented by its tag name. It does not mean "the last element matching the rest of this selector".
If, for example, the last element matching .left[class^='col'] is not the last span element, then :last-of-type will not match. You'll have to modify your HTML to either segregate those span elements from others, or add a class to the last such element, before you can target it with a selector.
WebKit does not have any issues with pseudo-classes and attribute selectors that I'm aware of (or if it did, those issues have long been fixed). It does have issues with pseudo-elements, which I address here, where the fiddle link originates.

CSS - What does asterisk before class mean?

Whats the difference between .some_class{} and *.some_class{}.
Does it mean that the class is applied only on tags which are inside another tag or is there no difference at all?
There is no difference- see here
The universal selector, written "*", matches the name of any element type. It matches any single element in the document tree.
If the universal selector is not the only component of a simple selector, the "*" may be omitted. For example:
*[lang=fr] and [lang=fr] are equivalent.
*.warning and .warning are equivalent.
*#myid and #myid are equivalent.
There is no difference between them at all. If you don't specify an element type, like div or p, then whether you have * or not doesn't matter. Even if you leave it out, it's implied that you want to match any element so long as it has the class some_class. From the spec:
If a universal selector represented by * (i.e. without a namespace prefix) is not the only component of a sequence of simple selectors selectors or is immediately followed by a pseudo-element, then the * may be omitted and the universal selector's presence implied.
Examples:
*[hreflang|=en] and [hreflang|=en] are equivalent,
*.warning and .warning are equivalent,
*#myid and #myid are equivalent.
What you're describing in terms of elements being inside other elements only applies when * is separated from the class by a space, e.g. * .some_class. That would match an element with the class some_class only if it's inside another element (basically this means it will never match the root element).
And taking the above explanation about * being implied, this would make the selector with the space also equivalent to * *.some_class. Here you can see that two universal selectors are in use, separated by a combinator. The second one just happens to be optional because it's already qualified by the class selector (the first one is not optional because it exists on its own).
Assuming that before the class goes the id (#id.class):
there is not any difference between putting astherisc or not, because the asterisc means that the CSS will be applied to any id with this class, that is the same that putting the class withouth astherisc:
// This style will be applied to anybody that has the attribute class="my_class"
.my_class{
}
// This class will be applied to anybody to any id that also has the attribute class="my_class"
*.my_class{
}
Hope it helps!

What is appropriate ordering of css selector? eg p.class or .class p

While debugging some css i noticed there is a difference between this order of declaration. The first caused headings inside anchors to display inline as desired, the second seems not to:
1/ a.aname { display:inline; margin:0px;}
2/ .aname a { display:inline; margin:0px;}
<a name="download" class="aname"><h2>Download</h2></a>
I have mostly been using the second form to apply class styles.
What is the difference in how these are applied, and are there any guide rules when to use each? (to avoid the css-puzzlement which arises when it's done wrong)
Basic solution from answers:
Use "direct selection" elementtype.class{} or elementtype#id{} to apply style to elements directly. For styling which is intended to affect once each time the rule is used eg. a margin change, a display change, a noninheriting font change. Direct selection does not inherit to child elements, it is applied to parent element only.
Use "descendant selection" .class elementtype{} or #id elementtype to apply style to type descendants/children of the named or classed element. For styling which is intended to change appearance of elementtypes under an element/within a section of page where it is applied eg. inheriting font changes to text sections, inheriting format changes to paragraphs or list elements. Descendant selection applies to all child elements but never the parent.
NBself: learn about other selectors too asap ;)
The difference is the space between them, which is the descendant combinator in CSS.
The selector a.aname will match an anchor element with the class aname while the .aname a will match an anchor element that is a descendant of an element with the class aname:
<a class="aname">This matches the first rule</a>
<span class="aname"><a>This matches the second rule</a></span>
CSS combinators:
space = descendant combinator
> = child combinator (direct descendant)
+ = adjacent sibling combinator
The Selectutorial gives a pretty good overview or selectors and combinators.
If you use selectors where you can put identifiers together without combinators between them, the order doesn't matter. Example:
#id.class { ... }
.class#id { ... }

Resources