-1

I can not figure out how to select an element (several elements back) from a specific element that has a certain title attribute.

For example, using the following example code, I am trying to target the first <renderer> element...

<renderer class="scope">
   <div id="content" class="scope">
      <renderer class="scope">
         <div class="scope">
            <div id="details" class="scope">
               <a title="Foo Bar" href="#">LINK TEXT</a>
            </div>
         </div>
      </renderer>
   </div>
</renderer>

I have tried many variation including this...

renderer:has a[title*="Foo Bar"] {
    opacity: 0.2 !important;
}

Other things that I have tried don't even come close to working either (even JavaScript).... But possibly because every answer I found on here or other sites are not related to this issue enough to solve the problem.

How can I target and style the first <renderer> element (or at least 2 levels back) if the link title has specific text in it?

user2284703
  • 357
  • 3
  • 11

2 Answers2

1

There is no way to select parent element in CSS. You can use javascript to achieve desired results.

You can do something like this

let anchor = document.querySelector('a[title="Foo Bar"]');
anchor.closest('renderer').style.opacity = 0.2;

If you want to select all elements in the document you can use querySelectorAll like:

let anchors = document.querySelectorAll('a[title="Foo Bar"]');
anchors.forEach(function (anchor) {
    anchor.closest('renderer').style.opacity = 0.2;
});

Note: closest() will not work in IE, so you might have to add its polyfill or use parentNode instead.

Kawaljit Singh
  • 192
  • 1
  • 6
  • I was asking for help in either method. Could you help me on how to do this with javascript then? – user2284703 Feb 16 '20 at 05:43
  • I have updated the answer. Please try this and let me know if this helps. Or check this JSFiddle https://jsfiddle.net/kawal/z9qepbc7/ – Kawaljit Singh Feb 16 '20 at 05:58
  • Close but it only get's the first match on the page. I need it to do this for several occurrences within a page. – user2284703 Feb 16 '20 at 14:46
  • You can use querySelectorAll to get all the elements from page and loop through each element and set that element's style. Please check the updated answer or check this fiddle https://jsfiddle.net/kawal/z9qepbc7/9/ – Kawaljit Singh Feb 16 '20 at 22:55
0

As of Feb 2020, the :has CSS pseudo-class is not currently supported by any browser.


JS solution

If you're not sure how high up the DOM your renderer is you might need to recursively call Element.closest() in order to find it.

function getHighestRenderer(el) {
  const closestRenderer = el.parentNode.closest("renderer");
  if (closestRenderer) {
    return getHighestRenderer(closestRenderer);
  }
  return el;
}

const titleToMatch = "Foo Bar";
const detailsLinks = document.querySelectorAll(".details a");

detailsLinks.forEach(link => {
  if (titleToMatch === link.getAttribute("title")) {
    getHighestRenderer(link).classList.add("foobar");
  }
});
.foobar {
  border: 1px dotted blue;
  padding: 10px;
  display: block;
}
<renderer class="scope">
  <div id="content" class="scope">
    <renderer class="scope">
      <div class="scope">
        <div id="" class="details scope">
          <a title="Not Foo Bar" href="#">LINK TEXT  - title: Not Foo Bar</a>
        </div>
      </div>
    </renderer>
  </div>
</renderer>


<renderer class="scope">
  <div id="content" class="scope">
    <renderer class="scope">
      <div class="scope">
        <div id="" class="details scope">
          <a title="Not Foo Bar" href="#">LINK TEXT - title: Not Foo Bar</a>
        </div>
      </div>
    </renderer>
  </div>
</renderer>

<renderer class="scope">
  <div id="content" class="scope">
    <renderer class="scope">
      <div class="scope">
        <div id="" class="details scope">
          <a title="Foo Bar" href="#">LINK TEXT - title: Foo Bar</a>
        </div>
      </div>
    </renderer>
  </div>
</renderer>
ksav
  • 13,381
  • 5
  • 27
  • 51
  • doesn't seem to work on mine... However perplexing as that is since it does work here and the code is the same. – user2284703 Feb 16 '20 at 22:13
  • Take a look at `
    – ksav Feb 16 '20 at 22:22
  • I've already considered that as well. – user2284703 Feb 16 '20 at 22:31
  • Which part doesn't work? Do you see any errors in the console? – ksav Feb 16 '20 at 23:58
  • Don't see any errors and I don't know what you mean about "what part". There's only one part. It just isn't working. Not judging your code or anything because obviously your code is working fine as demonstrated here in this site but the fact that the console doesn't give me any errors is why I'm having such a problem pinpointing why it won't do anything like it does here. – user2284703 Feb 17 '20 at 01:30