1

I have the following HTML, and I want to hide the element with the href that points to #something_else if its first sibling (or the first child of the parent element) has the class string.

<div class="description">
  <span class="string">blah</span>
  <a class="link" href="#something">blah blah</a>
  <a class="link" href="#something_else">blah blah blah></a>
</div>

I know this is possible using JS / jQuery, e.g.

if ($('.description').children().first().hasClass('string')) {
  $('a[href="#something_else"]').hide();
}

but it possible with only CSS?

Harry
  • 87,580
  • 25
  • 202
  • 214
bard
  • 2,762
  • 9
  • 35
  • 49
  • The `a` that points to `#something_else` is not the first sibling or child of the element that has class = string. I assume you want to replicate the jQuery behavior with CSS (even though the description seems a bit off). – Harry Feb 23 '16 at 05:02
  • I meant the first child of the parent element -- which has class `description` – bard Feb 23 '16 at 05:10
  • Ok, but the *first sibling* part is still confusing a bit. Hope one of the answers given below help you. – Harry Feb 23 '16 at 05:12

6 Answers6

2

Yep, that's perfectly possible, at least for browsers that are IE7 or higher.

Here's how:

.description *.string:first-child ~ a[href='#something_else'] {
  display: none;
}
<div class="description">
  <span class="string">blah</span>
  <a class="link" href="#something">blah blah</a>
  <a class="link" href="#something_else">blah blah blah></a>
</div>
Sarhanis
  • 1,577
  • 1
  • 12
  • 19
1

You can use the below selector. It will select (and style/hide) all the a (anchor) tags whose href is #something_else and is a sibling of the span which is the first child of its parent and has its class as string.

(I have set the color of the required element to red instead of hiding it for demo purpose.)

.description span.string:first-child ~ a[href="#something_else"] {
  color: red;
}
<div class="description">
  <span class="string">blah</span>
  <a class="link" href="#something">blah blah</a>
  <a class="link" href="#something_else">blah blah blah></a> <!-- this will be selected -->
</div>

<div class="description">
  <span class="notstring">blah</span>
  <span class="string">blah</span>
  <a class="link" href="#something">blah blah</a>
  <a class="link" href="#something_else">blah blah blah></a> <!-- this will not be selected -->
</div>

Note: If the element (first child) with class="string is not always a span then Sarhanis' answer is the best but if it is always a span, I would recommend not using * (more a personal preference but mainly because of (why) is the CSS star selector considered harmful?).

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • The performance concerns with * only apply when it's used alone. `*.string:first-child` is *exactly* the same as `.string:first-child` - whether you include the * there is purely stylistic. – BoltClock Feb 23 '16 at 08:45
  • @BoltClock: But will `span.string` and `*.string` be the same in terms of performance? – Harry Feb 23 '16 at 08:46
  • Assuming all `.string` elements are spans? I don't know. And honestly I haven't yet seen a case where it actually mattered. – BoltClock Feb 23 '16 at 08:47
  • @BoltClock I agree and which is why I also mentioned it is more of a personal preference as well. And I also don't know if all `.string` are `span` (as I type that I found a couple of wrong sentences in my answer :P). – Harry Feb 23 '16 at 08:49
0

It is possible using javascript or jquery.

$(document).ready(function(){
 if ($('.description').children().first().hasClass('string')) {
  $('a[href="#something_else"]').hide();
 }
});
<div class="description">
  <span class="string">blah</span>
  <a class="link" href="#something">blah blah</a>
  <a class="link" href="#something_else">blah blah blah></a>
</div>

see working example here.

Thanks

Amit Shah
  • 1,380
  • 1
  • 10
  • 19
0

Here it is:

.description span.string ~ .link[href="#something_else"] { display: none; }
<div class="description">
  <span class="string">blah</span>
  <a class="link" href="#something">link 1</a>
  <a class="link" href="#something_else">link 2</a>
</div>
pumbo
  • 3,646
  • 2
  • 25
  • 27
0
   .string+a[href="#something"] {
   color:red;
   }

You could use the above code heres the fiddle https://jsfiddle.net/gmp4d5ya/

Vivekraj K R
  • 2,418
  • 2
  • 19
  • 38
0

Sure, like this:

.description { margin:1em; }

.link[href="#something_else"] { display:none; }
.string + .link + .link[href="#something_else"] { display:block; }
<div class="description">
  <span class="string">string</span>
  <a class="link" href="#something">something</a>
  <a class="link" href="#something_else">something_else</a>
</div>

<div class="description">
  <a class="link" href="#something">something</a>
  <a class="link" href="#something_else">something_else</a>
</div>

<div class="description">
  <span >not a string</span>
  <a class="link" href="#something">something</a>
  <a class="link" href="#something_else">something_else</a>
</div>
c-smile
  • 26,734
  • 7
  • 59
  • 86