134

I know that I can target elements which have a specific attribute in CSS, for example:

input[type=text]
{
    font-family: Consolas;
}

But is it possible to target elements which have an attribute of any value (except nothing i.e. when the attribute hasn't been added to the element)?

Roughly something like:

a[rel=*]
{
    color: red;
}

Which should target the first and third <a> tags in this HTML:

<a href="#" rel="eg">red text</a>
<a href="#">standard text</a>
<a href="#" rel="more">red text again</a>

I figure it's possible because by default, cursor: pointer seems to be applied to any <a> tag which has a value for its href attribute.

Marty
  • 39,033
  • 19
  • 93
  • 162

3 Answers3

181

The following will match any anchor tag with a rel attribute defined:

a[rel]
{
    color: red;
}

http://www.w3.org/TR/CSS2/selector.html#pattern-matching


Update: To account for the scenario @vsync mentioned, in the comment section (differentiating between emtpy/non-empty values), you could incorporate the CSS :not pseudo-class:

a[rel]:not([rel=""])
{
    color: red;
}

https://developer.mozilla.org/en-US/docs/Web/CSS/:not

Alex
  • 34,899
  • 5
  • 77
  • 90
  • This also targets empty values, and sometimes you want **any** value, except `empty` – vsync Jan 17 '19 at 10:49
  • 3
    Last example should be `a[rel]:not( [rel=""] )` – cameronjonesweb Apr 25 '20 at 13:17
  • Unfortunately, the `not` trick ends up being non-dynamic. I tried doing this to highlight `input` fields when they had values versus when they had no values, and it seems that once the page loads, the style isn't re-evaluated if a value is typed-in (or when it's there to begin with and it's removed). – Christopher Schultz Jun 18 '20 at 04:24
  • The input-attribute is only for the initial value and changes to the value are not reflected back to the attribute. You can verify by inspecting the DOM in your browser. So this answer works perfectly and reacts dynamically to actual changes in the attribute. – Frettman Apr 25 '22 at 05:45
61

Yes in CSS 3 selectors there are several attribute selectors.

E.g.

[att] Represents an element with the att attribute, whatever the value of the attribute.

[att=val] Represents an element with the att attribute whose value is exactly "val".

[att~=val] Represents an element with the att attribute whose value is a whitespace-separated list of words, one of which is exactly "val". If "val" contains whitespace, it will never represent anything (since the words are separated by spaces). Also if "val" is the empty string, it will never represent anything.

[att^=val] Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.

[att$=val] Represents an element with the att attribute whose value ends with the suffix "val". If "val" is the empty string then the selector does not represent anything.

[att*=val] Represents an element with the att attribute whose value contains at least one instance of the substring "val". If "val" is the empty string then the selector does not represent anything.

Daff
  • 43,734
  • 9
  • 106
  • 120
2

Should add that if a browser sets an attribute by default you may need to work around. This does not appear to be an issue in "modern" brosers, however, this is an issue I have seen, so be sure to check cross-browser performance.

For instance, I discovered that in IE prior to 9, colSpan is set for all TD's in a Table, so any single cell has the hidden colspan value of 1.

So if you were targetting "any TD with colspan attribute" you apply in your webdoc, even the td's having no colspan attribute set, such as any TD being a single cell, will receive the css styling. IE less than 9 will basically style them all!

Only reason to concern over this is all the remaining XP users out there who cannot upgrade above IE8.

So for Example, I have a group of tables where the content may shift from end to end, leaving anywhere from 1 to 7 cells blank either at the end or the beginning.

I want to apply a color to any blank cells at the end or the beginning utilizing the colspan attribute. Using the following will not work in IE less than 9

#my td[colspan] {background-color:blue;}

...all TD's will get styled (funny since the conditional attribute styling was supposedly superior in IE, but I digress...).

Using the following works across all browsers when I set the value of colspan to 'single' for any solitary cell/TD I wish to include in the styling scheme, however its a 'hack' and will not properly validate...

#my td[colspan="single"] {background-color:blue;} /* 'single' could be anything */
#my td[colspan="2"] {background-color:blue;}
#my td[colspan="3"] {background-color:blue;}
#my td[colspan="4"] {background-color:blue;}
#my td[colspan="5"] {background-color:blue;}
#my td[colspan="6"] {background-color:blue;}
#my td[colspan="7"] {background-color:blue;}

Alternatively you should be able to more appropriately address the issue using conditional styling using "if lt IE 9" to override. It would be the correct way to do this, just keep in mind you must hide the "properly constructed css" from IElt9 in the process, and I think the only proper way to do that is with selective style sheets.

Most of us already do that anyway, but regardless, you still do well to consider and test if a browser applies an auto-attribute when it sees none, and how it may handle your otherwise corect syntax for styling on attribute values.

(btw, colspan just happens not to be in the css specification yet [as of css3], so this example throws no validation error.)

Adam Katz
  • 14,455
  • 5
  • 68
  • 83
TwoHawks
  • 121
  • 1
  • 4
  • 1
    *> Only reason to concern over this is all the remaining XP users out there who cannot upgrade above IE8.* You'd think that, until you run into enterprise environments with IE8 on Win7. – Bob Feb 02 '15 at 05:55