Enlico
Enlico

Reputation: 28500

Is or-ing together attribute selectors possible?

I see that multiple attribute selectors are "and-ed" together for example:

/* Links that start with "https" and end in ".org" */
a[href^="https"][href$=".org"] {
  color: green;
}

I there a way to express that I want to match all <a>s that have href containing one a, b or c?

Upvotes: 1

Views: 48

Answers (1)

Zach Jensz
Zach Jensz

Reputation: 4078

Yes, you can target elements with one attribute value OR another in CSS.

Geat's selector list approach with commas , is the most straightforward, and also the most browser compatible:

a[href^="https"][href$=".org"][href*="a"],
a[href^="https"][href$=".org"][href*="b"],
a[href^="https"][href$=".org"][href*="c"] {
  color: green;
}
<a href="https://a.org">https://a.org</a>
<a href="https://b.org">https://b.org</a>
<a href="https://c.org">https://c.org</a>
<a href="https://d.org">https://d.org</a>
<a href="http://a.org">http://a.org</a>

I agree though that this can become cumbersome. Luckily we can use the modern CSS :is() pseudo class to shorten this selector:

a[href^="https"][href$=".org"]:is([href*="a"], [href*="b"], [href*="c"]) {
  color: green;
}
<a href="https://a.org">https://a.org</a>
<a href="https://b.org">https://b.org</a>
<a href="https://c.org">https://c.org</a>
<a href="https://d.org">https://d.org</a>
<a href="http://a.org">http://a.org</a>

This also has the benefit of making the selector list forgiving, where if one selector within :is() is invalid, the others will still work - a regular selector list in CSS is actually unforgiving and will break the entire list if one selector breaks!

Also note that both examples above will match A, B, C if they are contained within the protocol, path (any part of the URL) i.e.

a[href^="https"][href$=".org"]:is([href*="org"], [href*="http"], [href*="h"]) {
  color: green;
}
<a href="https://org.org">https://org.org</a>
<a href="https://s.org">https://s.org</a>
<a href="https://x.org">https://x.org</a>
<a href="https://y.org">https://y.org</a>
<a href="http://website.org">http://website.org</a>

Unfortunately, the substring syntax for attribute selectors in CSS does not currently feature a way to match A OR B in an elegant way like I've illustrated below which I'm sure is what you were hoping for:

a[href^="https"][href$=".org"][href*="a"|"b"|"c"]

Upvotes: 1

Related Questions