
CSS4 Preview – Selectors - dkd903
http://davidwalsh.name/css4-preview
======
garindra
What about LESS-style nested selectors? I've been using it in my projects and
it improves my workflow tremendously. I'd be thrilled if it's finally
integrated into the CSS specification.

~~~
jacobr
Might be harder to pull off wrt backwards compatibility.

~~~
bps4484
how so? Sass and Less seem to be able to pull it off.

------
geuis
Instead of $el > el syntax, wouldn't a simple version be better?

* el < el

I've run into many situations over the years where being able to select parent
elements based on a child would have come in handy. I think it would be a lot
simpler to just use < for direct parents, as > is used for direct children.

~~~
saurik
A) Using < would cause parsing problems when the stylesheet is embedded in an
enclosing HTML document. B) If you think about it, the selector is still
functioning the same: you are simply moving which node is being "targeted"; I
would therefore hope that you could also do "$el + el" to select nodes that
came before other nodes. (edit: Reading the linked update to the
specification, it seems like the people who wrote it did _not_ see that this
would be a useful, beautiful, and arguably important generalization; _sigh_.)

~~~
bps4484
could you elaborate on A? What's the problem of using "<" in an enclosing html
document that wouldn't also be a problem for ">", which already exists?

~~~
saurik
I'm confused by your comment: ">" only has special meaning in the context of a
tag, or after "]]"; "<" has special meaning meaning anywhere in a document you
are not inside of a tag.

~~~
bps4484
that actually answered my question. I don't know the html spec that well so I
didn't know if both "<" and ">" were reserved characters. From what I
understand of what you're saying, it's only when ">" comes after a "<" that is
has special meaning.

~~~
saurik
Correct. From the XML specification (which is easier to obtain than SGML, more
prescriptive than HTML4, and capable of being understood by humans in a way
the HTML5 "document IE" specification is unable to support), 2.4 "Character
Data and Markup" (note the "may" and "MUST"):

The ampersand character (&) and the left angle bracket (<) MUST NOT appear in
their literal form, except when used as markup delimiters, or within a
comment, a processing instruction, or a CDATA section. If they are needed
elsewhere, they MUST be escaped using either numeric character references or
the strings " &amp; " and " &lt; " respectively.

The right angle bracket (>) may be represented using the string " &gt; ", and
MUST, for compatibility, be escaped using either " &gt; " or a character
reference when it appears in the string " ]]> " in content, when that string
is not marking the end of a CDATA section.

------
yaix
There is one good point in the comments: "MATH! We need math! 50% -5px It’s
stupid having to do things like this in JS."

Completely agree! It should be possible to do this.

And please: vertical-align:center for any block element. Or is that in CSS3
and I am not aware of it?

~~~
Twisol
You can use calc (<https://developer.mozilla.org/en/CSS/calc>), but it isn't
well supported.

------
chrisbroadfoot
I like the $ syntax. It's powerful.

Can somebody explain the slash syntax in the example given?

    
    
        label:matches(:hover, :focus) /for/ input {

~~~
tlb
It's easy to cook up a syntax for selecting parents. The hard part is
implementing it efficiently. It requires browsers to scan more of the DOM tree
when elements are changed. I expect it to be one of the (many) parts of CSS
that are avoided by websites that want to render quickly.

~~~
masklinn
I'm not sure, CSS selectors are already matched left-to-right so you're not
scanning more stuff, it's just that you're selecting an other level of your
match tree.

    
    
        ul > li > p
    
        ul > $li > p
    

have the same matching complexity: the browser finds all p on the page, then
checks if their parent is a li, then checks if _that_ parent is a ul. The
difference (which may or may not require significant work) is that before the
check acted as a filter on the originally matched object, whereas now there's
a transform/translation.

~~~
masklinn
s/left-to-right/right-to-left/ of course

------
md224
This article might be a bit out of date... it appears the $ selector has been
changed to an exclamation point:

<http://dev.w3.org/csswg/selectors4/#subject>

------
masklinn
I'm not sure how I feel about CSS selectors closing in on XPath 1.0 in terms
of power, except with far, far higher levels of syntactic complexity.

------
yaix
Why only select an element based on its children? How about

el /if/ el > .someclass:hover { some:style; }

Style an element "el" if some other element exists or event occurs.

~~~
yaix
wtf? Why do I get downvoted? Could the downvoter explain please.

Again, insteat of being able to just select a parent on the existence of a
child, why not be able to select any element on the existence of another
element? Change the background of a body > div if there is only one child in a
list body > ul > li:only-child for example.

body > div /if/ body > ul > li:only-child { background:green; }

Or replace /if/ with :: or $ or whatever.

~~~
masklinn
I'm not sure you understand what /op/ does.

It's a reference indirection going through an IDREF type:

* It finds whatever elements are before the operator

* It gets the value of the operator's attribute (or type IDREF), ~ storing it in $ID

* it combines the selector after it with the root being extended with `[id=$ID]`

`/if/` would get the value of the attribute `if` and try to find an element
with that value as its id.

~~~
yaix
Again, what I care about is not the syntax but the functionality. If you want
write it as

body > div:if(body > ul > li:only-child) { background:green } body >
div:not(body > ul > li:only-child) { background:green }

which may or may not already work in CSS3.

~~~
masklinn
> Again, what I care about is not the syntax but the functionality.

Issue here is that you're talking about this using syntax for something which
has _absolutely no_ relation. Which is a tad confusing.

No, what you want does not work in CSS, you can't make a selector conditional
on a second completely unrelated selector (you probably can in XPath, although
I'm sure your colleagues will soon look to end your life if you do)

~~~
yaix
Could you explain why? Let's say you have a clickable element and want to
display a status text on hover. The status texts are loaded in some divs
somewhere else on the page. You would need JS to catch onhover and then swap
the display:hidden to block or whatever. Why would anybody look to "end my
life" if that was possible?

div.status > span:on(div.clickme > a:hover) { display:block; }

Why would that be bad?

~~~
masklinn
> Why would that be bad?

It's "action at a distance", it's very, very hard to understand and debug what
happens.

~~~
yaix
(1) You mean like when you do the same thing with Javascript? Why its okay
then? (2) If you alter a parent element with CSS that's "action on a distance"
as well.

Your argument is not very convincing.

------
wavephorm
Given the number of years it'll take for CSS3 to be used reliably, this
information isn't very useful.

~~~
batista
Given that you can target modern browsers like Chrome and Safari and Firefox,
and either fuck IE and older versions (e.g for an inhouse app) or just have
then not support some fancy features, it's VERY useful.

You don't have to have all of CSS3 implemented everywhere to be useful. Same
for CSS4.

