Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Targeting List Items by their Value Attribute

As I recently learned, in HTML5 you can use the value attribute with list items, as long as they are inside of an ordered list. http://dev.w3.org/html5/markup/li.html

I have been trying to style the list items by their value. Preferably I would like to style them like:

li[value >= "10"] { background: orange; }
li[value >= "20"] { background: green; }

However, this is currently not possible with just CSS.


Here is a fiddle I've been playing around with, trying different things. http://jsfiddle.net/Hf57v/2/

HTML:

<ol>
    <li value="33"></li>
    <li value="4"></li>
    <li value="12"></li>
    <li value="88"></li>
    <li value="jadfk"></li>
</ol>

CSS:

li { width: 20px; height: 20px; margin: 20px; background: gray; }

li[value~="3"] { background: orange; }  /* #1  */
li[value="4"] { background: red; }      /* #2  */
li[value="12"] { background: blue; }    /* #3  */
li[value^="1"] { background: green; }   /* #4  */
li[value^="8"] { background: yellow; }  /* #5  */
li[value="NaN"] { background: pink; }   /* #6  */

1) This does not work at making the background orange for the <li value="33"></li>.
I thought it would since it contains a 3.

2) This works at changing the <li value="4"></li> to red.

3) This works at changing the <li value="12"></li> to blue.

4) This overrides the <li value="12"></li> background of blue, and changes the background to green. I thought it might not since ="12 is more specific than ^="1" (begins with 1).

5) This works at changing the <li value="88"></li> to yellow.

6) This does not work at making the background pink for <li value="jadfk"></li>. I tried it since the value must be a number, so if it's just a string/text, it returns NaN (not a number).

Also, the way the ol works, is if there is no value for a li, or the value is NaN, then that li takes on a value from the previous li. In the fiddle, the <li value="jadfk"></li> renders as 89. But even though it renders as 89. It does not obey the li[value^="8"] { background: yellow; } like the 88. does. I wonder why that is.


Main Question : Is there any way to target the li value's by > or < operators in CSS?

Follow Up Question : If the answer is no, then is there any hacks or selectors that I didn't include that do help target more list items by their value attribute's value at the same time?


Bounty Info :

The bounty jsfiddle link http://jsfiddle.net/tuDBL/

In the fiddle, I created an ordered list (ol), which contains 130 list items (li) whose values are from 0 to 129. The li's with values from 0-9 need to have a unique background color. The li's with values from 10-19 need to have a unique background color. Etc, etc, all the way through 129. So in the end, there will be 12 unique background colors, and each of them representing 10 consecutive li values. The bounty winner will most likely be the person that is able to do this with the least amount of valid CSS.

like image 492
CRABOLO Avatar asked Jan 18 '14 03:01

CRABOLO


People also ask

How do I target a value in CSS?

The [attribute^="value"] selector is used to select elements with the specified attribute, whose value starts with the specified value. The following example selects all elements with a class attribute value that starts with "top": Note: The value does not have to be a whole word!

What are 3 correct ways to target an element for styling?

URLs with an # followed by an anchor name link to a certain element within a document. The element being linked to is the target element. The :target selector can be used to style the current active target element.

When working with attribute selectors how can you select elements which contain a particular attribute value?

[attribute$=”value”] Selector: This selector is used to select all the elements whose attribute value ends with the specified value. The value doesn't need to be a whole word. [attribute*=”value”] Selector: This selector selects all the elements whose attribute value contains the specified value present anywhere.

How do I style a data attribute in CSS?

[attribute=”value”]: It selects the elements with a specified attribute and value. [attribute~=”value”]: It selects the elements with an attribute value which contains a specified word. [attribute|=”value”]: It selects the elements with the specified attribute which starts with the specified value.


1 Answers

I assume no explanation needed for the ones that are working as you expected. Here are the thoughts about the others.

Point 1: (as noted in JoshC's comment) you have the wrong selector. li[value*="3"] is what you were looking for if you want it to change because it "contains" a 3.

Point 4: Selector specificity has nothing to do with anything inside the attribute selector, but rather the presence of the attribute selector itself. So li[value="12"] and li[value^="1"] have the exact same specificity because both have the type selector li and the attribute selector [value] tied to them. Therefore, the css cascade order wins out; therefore in your example li[value^="1"] is the last matching selector in the cascade and it wins (if you reversed the order the other would win).

Point 6: The css is only reading the html. It does not see what the ol itself is doing with the text that is not a number. In fact, in Firebug, it shows the value as being 0 on my system, but [value="0"] still does not work. The only two selectors that will work for non-numerical values are the actual value itself li[value="jadfk"] or the unqualified attribute value of li[value], which if you made that the default, then it would need to be first in the order of your calls, otherwise it would make all of them pink (again, because of cascade order and equal specificity).

I am not aware of any current way to directly do an evaluation of > or < for an attribute as you desire without javascript. As to a hack to do something like that, a previous answer of mine may be helpful, assuming the number range is limited. That answer is using essentially the same technique as what Lior's later answer to this question has put in his answer (whether he got the idea from my link I provided or not I do not know, nor does it really matter), so I will not repeat the coding and concepts here.

Update (Adding a Solution IE7/8 Compatible)

Since Lior had an answer similar to my linked answer, I came up with this option. It does not use the :not() selector (so if IE7 compatibility is an issue, this may be preferable). Rather, it utilizes the general sibling selector which is IE7 compatible. It uses 12-13 selectors (depending on whether you want the first 10 to have the default background or not), and utilizes the cascade order to override the previous color values (so the order of these selectors in the css is important).

Fiddle Example

li[value] {background: yellow;} /* if other than default bkg. wanted on 1st 10 */
li[value="9"] ~ li[value] {background-color: red;}
li[value="19"] ~ li[value] {background-color: blue;}
li[value="29"] ~ li[value] {background-color: gray;}
li[value="39"] ~ li[value] {background-color: dimgray;}
li[value="49"] ~ li[value] {background-color: brown;}
li[value="59"] ~ li[value] {background-color: purple;}
li[value="69"] ~ li[value] {background-color: Chartreuse;}
li[value="79"] ~ li[value] {background-color: black;}
li[value="89"] ~ li[value] {background-color: DarkSlateBlue;}
li[value="99"] ~ li[value] {background-color: Bisque;}
li[value="109"] ~ li[value] {background-color: Indigo;}
li[value="119"] ~ li[value] {background-color: Lavender;}

(Thanks to Lior's code for the color values used here -- yes, I swiped those.)

This also only works because we are dealing with an ordered list. The previous answer I linked to, we were not (the numbers were arbitrary and in no relation).

Technically, some of the selectors above are redundant

Assuming the value attribute is only on the ordered list, then the selectors could be reduced to this:

Fiddle Example

[value] {background: yellow;} /* if other than default bkg. wanted on 1st 10 */
[value="9"] ~ li {background-color: red;}
[value="19"] ~ li {background-color: blue;}
[value="29"] ~ li {background-color: gray;}
[value="39"] ~ li {background-color: dimgray;}
[value="49"] ~ li {background-color: brown;}
[value="59"] ~ li {background-color: purple;}
[value="69"] ~ li {background-color: Chartreuse;}
[value="79"] ~ li {background-color: black;}
[value="89"] ~ li {background-color: DarkSlateBlue;}
[value="99"] ~ li {background-color: Bisque;}
[value="109"] ~ li {background-color: Indigo;}
[value="119"] ~ li {background-color: Lavender;}
like image 76
ScottS Avatar answered Oct 10 '22 18:10

ScottS