5

I'm trying to select <a> elements that are not the parents of <img> elements. (Note: if it's relevant some of the anchors I want to select are childless.) I tried this:

a > :not(img) {}

and this:

a:not(> img) {}

but neither of them seem to work. How would I accomplish this in CSS?

5
  • 2
    It's on the way: :has Commented Apr 6, 2018 at 20:16
  • I answered below. If you ask another question about the specific visual effect you're trying to achieve, someone might have a workaround for you, or at least tell you that you're truly stuck without resorting to JavaScript. Commented Apr 6, 2018 at 20:31
  • am i the only one to notice that img cannot have child element ? Commented Apr 6, 2018 at 22:37
  • @Temani Afif: Probably not, but the img in this case is the child, not the parent, so nothing to worry about there :P
    – BoltClock
    Commented Apr 7, 2018 at 2:54
  • 1
    @BoltClock well .. seems my mind is still not ready for parent selector :/ Commented Apr 7, 2018 at 8:17

2 Answers 2

7

There is a spec, currently in draft, for a :has() pseudo-class. No browser supports it yet. If the spec is someday approved and implemented, you'd be able to do this:

a:not(:has(img)) {
    // Styles
}

The MDN page says that :has would never work in stylesheets, only in JavaScript; but in saying that, it links to a section of the spec about a "dynamic selector profile" that apparently no longer exists.

I think the browser vendors typically have a problem with implementing CSS features that require knowledge of the DOM that only exists after the selected element is created, so I don't know if we should get our hopes up for this. Someone who follows the mailing lists or is generally smarter than me might offer a better prognosis.

4
  • The static and dynamic profiles were recently renamed to snapshot and live respectively, breaking links (which I'm gonna have to find and fix in all my answers here as well, just something you have to do when attempting to cite, or in the case of MDN document, an unstable spec and not something I'd be complaining about). The profiles themselves have not gone away. But there still haven't been any new developments or findings on how well :has() would perform in either profile since 2015. Your reasoning isn't that far off and is why the profiles exist in the first place.
    – BoltClock
    Commented Apr 7, 2018 at 2:52
  • Do you know why :has() wouldn't perform well? I know that CSS selectors are implemented from right to left (i.e. a img selects all img elements, then filters out the ones without a ancestors). It seems like it would be simple to implement a parent selector by simply getting the parent of each of the selected nodes, right?
    – James Ko
    Commented Apr 7, 2018 at 4:18
  • I read the Bugzilla thread on :has today. One example it gave is that if you allowed :has(:hover), a naïve implementation would have to recompute the style of every element in the document on every mouseenter or mouseleave event. Commented Apr 7, 2018 at 4:38
  • @James Ko: Because :has() isn't just a parent selector, so it's not as simple as implementing it as one. There have been talks of providing subsets of :has() such as E:has(> F) which would indeed function exactly like a parent selector, but as I've mentioned in my previous comment no work has been done on this by browser vendors at all since 2015, so nobody knows if it would perform well or poorly, let alone why. The dynamic pseudo-class example 75th cited is another possible reason.
    – BoltClock
    Commented Apr 8, 2018 at 16:53
1

Unfortunately, no. You'd need to use jQuery.

You could do some kind of workaround using CSS:

  1. Assign a class to links that do not have child elements that are images and use that class to style the links as normal (e.g. a.class{color: red})

  2. Assign a class to links that do have an image child element, and use a:not(.class){} to change their color

Reason: There is no parent selector in CSS. See: Is there a CSS parent selector?, CSS Parent/Ancestor Selector

Not the answer you're looking for? Browse other questions tagged or ask your own question.