Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unquoted hyphen in attribute selector

I recently ran into a strange error where a selector stopped working after minification (using csswring 3.0.7). The selector in question matches elements where a data-property includes a hyphen. It worked in development but failed in production on all browsers tested (Chrome, Firefox, IE11, Edge).

After looking through the minified stylesheet, I found that the selector had been transformed from something like [data-attr*="-"] to [data-attr*=-]. Quotes have been removed and this is rejected by the browsers.

The thing is, I can't find any source that says a single hyphen requires quotes. Obviously the minifier-authors has found the same sources I have.

This page details the relevant parts of the specification.

So, a valid unquoted attribute value in CSS is any string of text that is not the empty string, consists of escaped characters and/or characters matching /[-_\u00A0-\u10FFFF]/ entirely, and doesn’t start with a digit or two hyphens or a hyphen followed by a digit.

A single hyphen seems perfectly valid in this case.

Here is a jsfiddle testing different scenarios. Only when trying to match exactly a single, unquoted hyphen does the selector fail.

Am I missing something? Shouldn't this be a valid selector?

like image 290
kgram Avatar asked Jan 13 '16 16:01

kgram


1 Answers

Here's the precise text from the CSS2.1 specification itself as referenced by the article:

In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit.

As you can see, this does not appear to address the case regarding a single hyphen.

However, looking at the grammar in section 4.1.1, we find the following tokenization for an ident:

[-]?{nmstart}{nmchar}*

{nmstart} is represented by [_a-z]|{nonascii}|{escape} and is mandatory in an ident. The preceding hyphen is optional, but as the hyphen does not appear in {nmstart}, this would imply that a single hyphen is not a valid CSS identifier.

Therefore, the selector [data-attr*=-] is indeed invalid, and a single hyphen has to be quoted in order to be treated as a string instead.

like image 162
BoltClock Avatar answered Oct 23 '22 23:10

BoltClock