Using CSS selectors, is it possible to differentiate between these 2 code snippets?

Viewed 65

Using CSS selectors, is it possible to differentiate in any way between the following two code snippets? By differentiate, I mean selecting any part (or the whole) of either snippet, but not the other.

<span role="presentation">
   <span class="test" role="presentation" test-text="foo">bar</span>
</span>

and

<span role="presentation">
   <span class="test" role="presentation" test-text="foo">bar</span>
   baz
</span>

The web browser being used is only Firefox, so Mozilla-only features are also acceptable.

EDIT 1:

Additional details that may help answerers:

More complex versions of both of the above HTML snippets are present in the code. I've isolated it down to simplify this question, as everything else will be relevant. The only difference is the string (baz in this simplified example) in the outer span.

I'm looking for a selector that will match anything in one snippet, without matching anything in the other snippet. (I'm not sure if this is possible, so I'm trying to be maximally flexible with answers.) I can't change the upstream HTML, but I can change the CSS.

EDIT 2:

I've been asked to add more details and specifics, as this may impact the answer.

I think this will really help clarify: My goal is to hide the string bar if and only if baz is present in the upstream HTML (as shown in the second code snippet).

I'm good with hiding the entire span.test element or just the bar text string within it... either way is fine.

Regarding hiding bar, I'm open to all possibilities of hiding it so it takes up no space. I'm thinking of display: none or width: 0, but anything that results in it not taking up any space when baz is present is good.

EDIT 3:

Just a quick update: I went through the upstream code in depth, and it looks like bar will always be whitespace. I'm not sure if that opens any doors, but if it does, I thought it worth mentioning.

2 Answers

A very hacky idea to use with caution (or to not use at all ...). Only work if baz is longer than bar

[role=presentation] {
  text-indent: -13px; /* based on "bar" text */
  display: inline-block;
  position:relative;
}
[role=presentation]::before {
   content:"";
   position:absolute;
   top:0;
   bottom:0;
   right:0;
   left:0;
   background:#fff;
    z-index: -1;
}

[role=presentation] [role=presentation] {
  text-indent: 0;
  z-index:-2;
  transform: translateX(calc(100% + 7px)); /* the 7px is the whitespace*/
  margin-right:0;
}
[role=presentation] [role=presentation]::before {
  content:none;
}


/* irrelevant, simply to separate both elements */
.extra {
  margin: 10px;
  font-size:30px;
}
<div class="extra">
  <span role="presentation">
   <span class="test" role="presentation" test-text="foo">bar</span>
  </span>
</div>
<div class="extra">
  <span role="presentation">
   <span class="test" role="presentation" test-text="foo">bar</span> baz
  </span>
</div>

<div class="extra">
  <span role="presentation">
   <span class="test" role="presentation" test-text="foo">bar</span> another baz
  </span>
</div>

The only difference between the 2 code blocks is that in the latter there is the text node baz.

However, text nodes cannot be selected.

Even if baz was wrapped by an HTML element it wouldn't help select a previous sibling or a parent element. It is just not possible.

The only way to select them that I can think of is by the position of span[role="presentation"] in a parent element.

For instance, if span[role="presentation"] were children of the same parent you could select them with pseudo classes such as :first-child, :last-child, :nth-child() etc...

div > span[role="presentation"]:first-child {
  background: red;
}

div > span[role="presentation"]:last-child {
  background: green;
}
<div>
  <span role="presentation">
     <span class="test" role="presentation" test-text="foo">bar</span>
  </span>

  <span role="presentation">
     <span class="test" role="presentation" test-text="foo">bar</span> baz
  </span>
</div>

I'm not aware of any Mozilla-only feature that would allow to do it differently.

Related