Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS attribute selector and case sensitivity with the "type" attribute vs. made-up attributes

I'm trying to style an OL based on its type attribute. The list-style attributes for all ULs and OLs have been wiped out previously by another CSS stylesheet which I cannot really modify, and I need to re-style the list-style, taking the type into account, i.e. if the OL should use Roman characters or alphanumerics, etc.

That's easy, I thought; I'll just use the attribute selector to target the OLs based on the value of the type attribute. The attribute selector is case sensitive, so this should be easy, right?

Wrong - at least when you try to use the standard "type" attribute.

Here's an example (which works):

/* Remove default list style */
ul, ol { list-style:none; }

/* This works, using a non-standard foo attribute. The selector is case sensitive, so I can target 'i' and 'I' separately */
ol[foo='i'] {
  list-style-type:lower-roman;
}

ol[foo='I'] {
  list-style-type:upper-roman;
}
<ol foo="i">
  <li>Styled with lower case roman</li>
  <li>Styled with lower case roman</li>
</ol>

<ol foo="I">
  <li>Styled with uppercase roman</li>
  <li>Styled with uppercase roman</li>
</ol>

Now, replace foo with type and try again:

/* Remove default list style */
ul, ol { list-style:none; }

/* Trying to use the standard type attribute, the selector is no longer case sensitive, so I cannot style 'i' and 'I' individually .... */
ol[type='i'] {
  list-style-type:lower-roman;
}

ol[type='I'] {
  list-style-type:upper-roman;
}
<ol type="i">
  <li>Should be lower-case roman</li>
  <li>Should be lower-case roman</li>
</ol>

<ol type="I">
  <li>Should be upper-case roman</li>
  <li>Should be upper-case roman</li>
</ol>

Now it's like the selector is no longer case-sensitive and both lists are affected, and both use upper-case Romans.

I've not been able to find any information whether this is the correct behaviour or not, that is, when using a known attribute such as 'type' v.s using non-standard attribute like 'foo'. The fact that this happens both in Chrome and Firefox makes be believe that it's not a bug.

Any ideas?

Here is a CodePen to mess with: https://codepen.io/haukurhaf/pen/NOQYOz

like image 229
HaukurHaf Avatar asked Nov 01 '18 10:11

HaukurHaf


People also ask

Are CSS attribute selectors case-sensitive?

That is because CSS respects the case-sensitivity of the document language for element names, and attribute names and values. And as HTML is case-sensitive for (most) attributes, the selectors are processed in a case-sensitive way.

What are the three different types of CSS Selectors What are the three different types of contextual selectors?

Simple selectors (select elements based on name, id, class) Combinator selectors (select elements based on a specific relationship between them) Pseudo-class selectors (select elements based on a certain state)

What CSS selector is used to select elements with a specified attribute and value?

CSS [attribute="value"] Selector The [attribute="value"] selector is used to select elements with a specified attribute and value.

What is a CSS selector attribute?

The CSS Attribute Selector is used to select an element with some specific attribute or attribute value. It is an excellent way to style the HTML elements by grouping them based on some specific attributes and the attribute selector will select those elements with similar attributes.


1 Answers

This, and the broader use case of forcing attribute selectors to match case-sensitively, has been addressed by the introduction of a case-sensitive attribute selector flag s:

ol[type='i' s] {
  list-style-type:lower-roman;
}

ol[type='I' s] {
  list-style-type:upper-roman;
}

Now we await implementations...


The HTML spec seems to suggest that the behavior of the type attribute of ol is incorrect, but its use of certain keywords makes this less than 100% clear. Section 4.16.2 uses "must":

Attribute selectors on an HTML element in an HTML document must treat the values of attributes with the following names as ASCII case-insensitive, with one exception as noted in the rendering section:

  • ...
  • type (except as specified in the rendering section)

All other attribute values and everything else must be treated as entirely case-sensitive for the purposes of selector matching.

And points to section 14.3.8, which uses "expected" as described in the abstract of section 14 (tl;dr: a browser is not necessarily in violation of the spec if it chooses not to follow what is stated as "expected" behavior):

The following rules are also expected to apply, as presentational hints:

@namespace url(http://www.w3.org/1999/xhtml);

ol[type="1"], li[type="1"] { list-style-type: decimal; }
ol[type=a], li[type=a] { list-style-type: lower-alpha; }
ol[type=A], li[type=A] { list-style-type: upper-alpha; }
ol[type=i], li[type=i] { list-style-type: lower-roman; }
ol[type=I], li[type=I] { list-style-type: upper-roman; }
ul[type=none i], li[type=none i] { list-style-type: none; }
ul[type=disc i], li[type=disc i] { list-style-type: disc; }
ul[type=circle i], li[type=circle i] { list-style-type: circle; }
ul[type=square i], li[type=square i] { list-style-type: square; }

In the above style sheet, the attribute selectors for the ol and li elements are expected to be treated as case-sensitive.

Given that the expected behavior as described in the latter is more in line with author expectations than actual browser behavior, I'm going to say that this is indeed incorrect behavior despite the permissiveness of the word "expected".

like image 200
BoltClock Avatar answered Oct 04 '22 18:10

BoltClock