1

I am using the @DisgruntledGoat method from here in order to place parenthesis around all of my ordered list types, with some relative and absolute positioning to make it look "normal". Everything is working completely as expected except my CSS selecting the proper type attribute.

I have this...

ol[type] {
    counter-reset: list;
}

ol[type] li {
    list-style: none;
    position: relative;
}

ol[type="1"] > li:before {
    counter-increment: list;
    content: " (" counter(list, decimal) ") ";
    position: absolute;
    left: -1.4em;
}

ol[type="a"] > li:before {
    counter-increment: list;
    content: " (" counter(list, lower-alpha) ") ";
    position: absolute;
    left: -1.4em;
}

ol[type="A"] > li:before {
    counter-increment: list;
    content: " (" counter(list, upper-alpha) ") ";
    position: absolute;
    left: -1.4em;
}

My problem is that according to (EDIT: the W3C rules and ideas found on some sites) it seems the type="var" selector as HTML is infact not case-sensitive (which makes no sense to me, because "a" gives lower-alpha and "A" gives upper-alpha... well according to here anyway.

So far no matter what I try, all of my ol[type="a"] objects are getting selected and remade as upper-alpha by this line content: " (" counter(list, upper-alpha) ") ". I need some help figuring out how to make sure my lower-alpha remain lower cased.

P.s. this is for a legal site with legal terms and they have informed me that they NEED lower case versus upper case distinctions.

EDIT:

I ended up using JQuery and added a class to each OL type within the DOM, one for number, one for lower-alpha and one for upper-alpha. Then it was easy to cover both the selection of each item as well as the :before Pseudo selector, which I was thinking might be a problem originally.

Community
  • 1
  • 1
GoreDefex
  • 1,461
  • 2
  • 17
  • 41
  • 6
    From the (not related to the W3C in any way) site you link to: "The value specified in an attribute selector is case sensitive if the attribute value in the markup language is case sensitive." – Quentin Nov 24 '14 at 11:49
  • thats not helpful... I need a solution not for you to tell me exactly what the site I linked said... thats why I linked it. – GoreDefex Nov 24 '14 at 11:51
  • I would say this leans towards content and not styling, so CSS is perhaps not the right approach for this. – Jørgen R Nov 24 '14 at 11:52
  • I know, I could add classes. This is just a massive legal site with over 130 pages of content all managed inside a content management system... in other words no simple search and replace methods... I just wanted to have this be a simple fix. – GoreDefex Nov 24 '14 at 11:54
  • or at least I was "hoping" for simple. – GoreDefex Nov 24 '14 at 11:54

3 Answers3

4

From the site you link to:

The value specified in an attribute selector is case sensitive if the attribute value in the markup language is case sensitive. Thus, values for id and class attributes in HTML are case sensitive, while values for lang and type attributes are not.

You are using a type attribute, which seems to be case-insensitive. Hence, with pure CSS, it's impossible to differentiate.

You might be stuck using JavaScript.

EDIT: Here's some JS to differentiate and add classes, a and A, respectively:

var alphaLists = document.querySelectorAll('ol[type="a"]');
for (var i = 0; i < alphaLists.length; i++) {
    if (alphaLists[i].type == 'a') {
        alphaLists[i].className += ' a';
    }
    if (alphaLists[i].type == 'A') {
        alphaLists[i].className += ' A';
    }
}

Fiddle

Scimonster
  • 32,893
  • 9
  • 77
  • 89
  • damn ok. I guess the consensus is to just use JQuery/JavaScript. and ya I read that line thats why I linked it. I was hoping maybe I just hadn't heard another rule yet or someone had found a way around it. Cheers – GoreDefex Nov 24 '14 at 11:56
  • FWIW, a JavaScript `querySelectorAll('ol[type="a"]')` also returned both items. – Scimonster Nov 24 '14 at 11:59
  • ya I know @Scimonster that's the first thing I tried lol. JQuery is always my CSS selector debugger :) – GoreDefex Nov 24 '14 at 12:00
  • I added some working code that checks the case and adds a class. No jQuery, even. :) – Scimonster Nov 24 '14 at 12:02
  • While obvious, I think it is worth noting that if you control the HTML you don't need any javascript. Just add the corresponding upper/lower classes to each `ol` element. Ultimately, the list style is getting set to `none` so the `type` attribute is only being used as a selector. To someone reading your code later, it may even be easier for them to understand that CSS is being used to style the list if an explicit class is present. In my opinion, if you control the markup, using javascript here is overkill. – Matt Scully Nov 03 '16 at 16:38
2

The case sensitivity of attribute values for the purposes of selector matching is usually left up to the document language to decide. Selector matching is performed based on the rules given by the document language.

In HTML 4, this is what the attribute definition looks like:

type = style-information [CI]

However more details on case sensitivity are given in the prose. In particular it says that values are case-insensitive for the ul element and case-sensitive for the ol element.

For some reason, no browser honors this distinction when matching values with selectors, and it's likely browsers went with the [CI] flag given by the HTML 4 spec for both ul and ol elements, resulting in the case-insensitive matching behavior seen.

In HTML5, all attribute values must now match selectors case-sensitively regardless of the attribute. From the looks of it, no implementation has yet updated its behavior to match the latest standard, and so attribute selectors matching the type attribute on ol elements will continue to match case-insensitively. Either way, this behavior is buggy and should probably be fixed, in all browsers. Hopefully, it will be fixed along with the implementation of counter styles.

You can still work around this by using class names — for some reason, browsers implemented case-sensitive selector matching for the class attribute but not the type attribute in cases where the latter should be case-sensitive.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • ok thanks I appreciate the concise answer and links. I am gonna +1 since I am accepting this answer. There doesn't seem to be a CSS way even though type="" itself has no trouble in the DOM figuring it out. – GoreDefex Nov 24 '14 at 11:57
  • Actually the spec [states](http://www.w3.org/TR/html401/struct/lists.html#idx-list-5): `For the OL element, possible values for the type attribute are summarized in the table below (they are case-sensitive):` while they are case-insensitive for `UL` elements. – Hashem Qolami Nov 24 '14 at 12:01
  • 2
    @Hashem Qolami: Then the HTML 4 spec was misleading and all the browsers are buggy regardless. – BoltClock Nov 24 '14 at 12:04
  • @GoreDefex You say you accept the answer, but are you going to [click the check mark to accept it](http://stackoverflow.com/help/accepted-answer)? – Scimonster Nov 24 '14 at 12:16
1

If it's not working, then I doubt there is a solid solution using pure css. I would use jQuery to inject the labels.

If there is nothing stopping you from adding classes to your html, then you could do this:

ol[type="a"].lower > li:before {
counter-increment: list;
content: " (" counter(list, lower-alpha) ") ";
position: absolute;
left: -1.4em;
}

ol[type="A"].upper > li:before {
counter-increment: list;
content: " (" counter(list, upper-alpha) ") ";
position: absolute;
left: -1.4em;
}

And add the 'upper' and 'lower' classes accordingly.

If you can't change the html, then use jQuery to add the classes:

$('ol').each(function(){
    if ($(this).attr('type') == "a") $(this).addClass('lower');
    if ($(this).attr('type') == "A") $(this).addClass('upper');
});
markt
  • 903
  • 7
  • 21