Why Use an Attribute Selector to Match Classes

Why use an attribute selector to match classes?

The [] syntax is an attribute selector.

a[class="btn"]

This will select any <a> tag with class="btn". However, it will not select <a> which has class="btn btn_red", for example (whereas a.btn would). It only exactly matches that attribute.

You may want to read The 30 CSS Selectors you Must Memorize. It's invaluable to any up-and-coming web developer.

CSS Performance between class and attribute selectors

There is no performance issue. Both act same. But there is difference in specificity of the css with class versus Elements.

Specificity - Specificity determines, which CSS rule is applied by browsers.

If two selectors apply to the same element, the one with higher specificity wins.

But specificity has hierarchy.

  1. Inline styles (Presence of style in document).
    An inline style lives within your XHTML document. It is attached directly to the element to be styled. E.g.
  2. IDs (# of ID selectors)
    ID is an identifier for your page elements, such as #div.
  3. Classes, attributes and pseudo-classes (# of class selectors).
    This group includes .classes, [attributes] and pseudo-classes such as :hover, :focus etc.
  4. Elements and pseudo-elements (# of Element (type) selectors).
    Including for instance :before and :after.

Source: http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/

Hence div.test {} is more specific.

Combining class selector with attribute selector

You don't need the second period, unlike JavaScript the [class*="large-"] isn't compiled to return the found-string, it's simply evaluated as-is:

.button[class*="large-"] {
font-size: 0.9em;
}

JS Fiddle demo.

Combining a class selector and an attribute selector with jQuery

Combine them. Literally combine them; attach them together without any punctuation.

$('.myclass[reference="12345"]')

Your first selector looks for elements with the attribute value, contained in elements with the class.

The space is being interpreted as the descendant selector.

Your second selector, like you said, looks for elements with either the attribute value, or the class, or both.

The comma is being interpreted as the multiple selector operator — whatever that means (CSS selectors don't have a notion of "operators"; the comma is probably more accurately known as a delimiter).

Is there a way to use a CSS attribute selector to select a class name?

You could use this selector:

[class="className"], [class^="className "], [class$=" className"], [class*=" className "]

It's a bit long because we need to check whether it's just that class, whether it's at the beginning of the class attribute, the end, or in the middle.

css attribute selector not matching dynamically added class names

The $= operator matches the end of the whole attribute, so if the class you're targeting isn't the last one of the element (say class="whatever-enter other-class"), the selector won't match.

You can try this:

[class$='-enter'], [class*='-enter '] {
opacity: 0.01;
transition: opacity .25s ease-in;
}
[class$='-leave'], [class*='-leave '] {
opacity: 1;
transition: opacity .25s ease-in;
}

It will become more complex when combining two classes (2*2 = 4 selectors), so maybe you'll be better off sticking to the *=operator alone:

[class*='-enter'] {
opacity: 0.01;
transition: opacity .25s ease-in;
}

[class*='-enter'][class*='-enter-active'] {
opacity: 1;
}

[class*='-leave'] {
opacity: 1;
transition: opacity .25s ease-in;
}

[class*='-leave'][class*='-leave-active'] {
opacity: 0.01;
}

This will work as long as you don't have any other classes ending with these suffixes.

CSS match elements with ANY attribute

There is no such selector.1

Such a selector has been proposed or requested a number of times over the last several years, and out of these the only time someone even bothered to suggest a use case, it's one that has no relevance to CSS at all:

this selector would be useful for debugging purposes in order to verify in complex layouts whether an element has attributes or not (instead of using DOM's hasAttributes() method).

Even if this was your use case (which, like the other threads on www-style, you haven't stated at all in your question), the fact remains that no such selector exists.


1 There is ::attr(*), but that selects attribute nodes, not element nodes based on attributes (which, ostensibly, is what the asker is interested in). Completely different things.

CSS substring matching attribute selectors: Contains multiple class names

The selector you're looking for is as follows, see this question for more details.

td[class*="foo"][class*="bar"]

However, if you need to use selectors like that then it's often a sign that your class name logic is bad.

Why are selectors such as a[title= home ] slower than using class?

Browser implementors optimize the most common cases. Since classes are used very frequently to match styles, they must implement this as efficiently as they can. When they load in CSS, they index the classes to make this possible.

Since random selectors like title="home" are not used very frequently, they can get away with implementing them using simpler searches. It won't have as much impact on performance, because it will rarely be used.

Classes also require special treatment in the browser, because an element may have multiple classes, e.g. class="foo bar baz". When parsing the document, the browser needs to split this up so that it can match any of them against CSS selectors.

Using two identical attribute selectors [class][class]

[class][class] matches any element that has a class attribute (or, to be more precise, at least one class attribute — see below for why). The only functional difference between [class][class] and [class] is specificity, as each attribute selector contributes its own specificity amount:

Note: Repeated occurrences of the same simple selector are allowed and do increase specificity.

For reference, here are the specificities of all three example selectors:

/* 1 class, 2 attributes -> specificity = (0,3,0) */
.classname1[class][class]

/* 1 class, 1 attribute -> specificity = (0,2,0) */
.classname1[class]

/* 1 class -> specificity = (0,1,0) */
.classname2

An !important declaration under a less specific selector will still override a non-important declaration under this selector. An !important declaration under this selector will override any !important declarations under less specific selectors (or equally specific selectors appearing earlier in the source order).

If the only selector that needed to be overridden was .classname2, then adding two attribute selectors on top of a class selector would indeed be overkill. But for all we know, the author might have intended to override a selector like your intermediate example. Or it might have indeed been a mistake. Only they would know for sure, but these are my educated guesses.


The reason [class][class] matches is because it does not require the element to have two class attributes — within a compound selector, all simple selectors are treated independently of each other, and this includes attribute selectors regardless of their names and/or values. Selectors does not specify or presume whether an element can have multiple class attributes — only that an attribute presence selector matches based on the presence of at least one.

Having said that, the spec does contain an informative note with respect to class selectors (i.e. not attribute selectors for the class attribute) suggesting that an element may theoretically have multiple class attributes, although this isn't possible in contemporary HTML. It also states, normatively, that an element can have multiple ID attributes and all of them must be used when matching ID selectors. No such explicit text exists for value-matching with respect to attribute selectors, as multiple IDs are only possible in HTML with different attributes, but it's probably logical to deduce that the same would apply.



Related Topics



Leave a reply



Submit