CSS: Multiple Attribute Selectors

Specify multiple attribute selectors in CSS

Simple input[name=Sex][value=M] would do pretty nice. And it's actually well-described in the standard doc:

Multiple attribute selectors can be used to refer to several
attributes of an element, or even several times to the same attribute.

Here, the selector matches all SPAN elements whose "hello" attribute
has exactly the value "Cleveland" and whose "goodbye" attribute has
exactly the value "Columbus":

span[hello="Cleveland"][goodbye="Columbus"] { color: blue; }

As a side note, using quotation marks around an attribute value is required only if this value is not a valid identifier.

JSFiddle Demo

CSS - How to select multiple attribute values?

This is not possible in the standard CSS. It is convenient to use a CSS preprocessor like SASS or LESS which allow you creating loops among many other features. An example with SASS:

$selector: '.div';
@for $i from 1 to 10 {
$selector: $selector + '[line-number=' + $i + ']';
}

#{$selector} {
// style
}

In pure CSS you are doomed to use this solution instead:

.div[line-number=1], .div[line-number=2], .div[line-number=3], .div[line-number=4], .div[line-number=5], .div[line-number=6], .div[line-number=7], .div[line-number=8], .div[line-number=9], .div[line-number=10] {
}

CSS how to target 2 attributes?

input[type=submit][value=Delete]

You're chaining selectors. Each step narrows your search results:

input

finds all inputs.

input[type=submit]

narrows it to submits, while

input[type=submit][value=Delete]

narrows it to what you need.

Can I use multiple [element=...] attribute selectors in CSS?

Multiple attribute selectors are allowed but there is no [attr!=value] attribute selector.

You could use :not() pseudo-class to exclude [href="#"] from the selector:

a[href^="#"]:not([href="#"]):after {
content: ' \f14c';
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
}

It's worth noting that :not() pseudo-class works on IE9+

WORKING DEMO.

Alternatively for IE8 (while DOCTYPE is declared), you could also override the applied styles for the [href="#"] selector as follows:

a[href^="#"]:after {
content: ' \f14c';
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
}

a[href="#"]:after {
content: none;
}

UPDATED DEMO.

Multiple attribute selectors in SCSS

An @each loop would be another way to write this:

$directions: left right bottom top;
@each $i in $directions {
[no-padding*="#{$i}"] {
padding-#{$i}: 0 !important;
}
}

Why aren't my multiple CSS attribute selectors working?

As per the documentation this matches when type=email AND type=text which can't be true.

Here, the selector matches all SPAN elements whose "hello" attribute
has exactly the value "Cleveland" and whose "goodbye" attribute has
exactly the value "Columbus":

span[hello="Cleveland"][goodbye="Columbus"] { color: blue; }

You would need to include both versions;

form input[type=text],
form input[type=email] {
background-color: #f0f0f0;
}

How to find_elements with multiple attributes using cssSelector Python and Selenium

This error message...

SyntaxError: invalid syntax. Perhaps you forgot a comma?

...implies that the css_selector you have used contains a SyntaxError.



Deep Dive

There are two approaches to write css-selectors as follows:

  • Either you mention the value of the attributes within single quotes i.e. '...' and the entire locator within double quotes i.e. "...". Example:

    "tag_name[attribute_name='attribute_value']"
  • Or you mention the value of the attributes within double quotes i.e. "..." and the entire locator within single quotes i.e. '...'. Example:

    'tag_name[attribute_name="attribute_value"]'


Solution

To identify all the elements having <a href=....> within <div id="contents" ...> you can use the following locator strategy:

elements = driver.find_elements(By.CSS_SELECTOR, "div[id='contents'] a[href]")

However, incase of css_selector:

  • class attributes can be shortened as .element_class
  • id attributes can be shortened as #element_id

So precisely, your locator strategy can be:

elements = driver.find_elements(By.CSS_SELECTOR, "div#contents a[href]")


Getting Granular

To be more canonical, you may like to consider the id attribute of the <a> element as well i.e. thumbnail. So effectively the locator strategy would be:

elements = driver.find_elements(By.CSS_SELECTOR, "div#contents a#thumbnail[href]")

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.

CSS selector, multiple attributes, OR operator

You will need to repeat the property attribute selector for each OR condition, combining each one with the second attribute selector like so:

[property="some URL"][resource], [property="some URL"][typeof] { color: red; }

Reference: http://www.w3.org/TR/css3-selectors/#attribute-selectors

Is there a way to include multiple attributes inside a bracket selector?

Besides removing the "[type=...]" as Abdul Hannan suggested, the only shorter way I can think of to express this would be the following:

.my-form input[type="text"],
.my-form input[type="email"]{
padding: 8px;
width: 100%;
}


Related Topics



Leave a reply



Submit