Ralph David Abernathy
Ralph David Abernathy

Reputation: 5508

CSS selector: How to select element sibling AND element itself?

So I have a set of links, and want to apply a style [let's say color: red;] to those links only if they are siblings in the DOM. For example, if I have three links:

<a class="nav-link-primary">link</a>
<a class="nav-link-secondary">link</a>
<a class="nav-link-tertiary">link</a>

They should all be red.

But if I have something like this:

<a class="nav-link-primary">link</a>
<span>Lorem</span>
<a class="nav-link-secondary">link</a>
<a class="nav-link-tertiary">link</a>

Then only the last two links should be red, as they are siblings. Is it possible to do this with CSS?

Here is what I've tried

.nav-link-primary ~ .nav-link-primary,
.nav-link-primary ~ .nav-link-secondary,
.nav-link-primary ~ .nav-link-tertiary,
.nav-link-secondary ~ .nav-link-primary,
.nav-link-secondary ~ .nav-link-secondary,
.nav-link-secondary ~ .nav-link-tertiary,
.nav-link-tertiary ~ .nav-link-primary,
.nav-link-tertiary ~ .nav-link-secondary,
.nav-link-tertiary ~ .nav-link-tertiary {
  color: red;
}

.nav-link-primary:first-child + .nav-link-secondary{
  color: red;
}

.nav-link-secondary:first-child + .nav-link-primary{
  color: red;
}
<a class="nav-link-primary">link</a>
<a class="nav-link-secondary">link</a>
<a class="nav-link-tertiary">link</a>

Here is my CodePen link: http://codepen.io/obliviga/pen/jryPgO

This does not make the first link red, even though it has a sibling defined in the first block of selectors. Any ideas?

Upvotes: 1

Views: 3611

Answers (3)

jl_
jl_

Reputation: 5539

Regarding sibling selectors—there are Adjacent and General sibling selectors.


EDIT: Since the topic is on sibling selectors with different use cases, I have refined the post to give more useful input and a bit for more clarification.

In your case, rather than using a sibling selector, it is more straight-forward to use other combinator selectors like descendant selector or child selector (as we are selecting components inside a parent).

For the example mentioned above, it would be difficult to accomplish the results just by using sibling selectors alone. If we have to go about only using sibling selector, then, we would end up being not using the sibling selector in the right way or would need a hack (not the right way to go) which results in unreadable code (based on how dynamic the above markup is generated).

Linking the recommendation for further reference.

Short answer: I would not apply sibling selector on the markup in your case, but would go with Child combinator selector or Descendant selector.


Sample snippet to further clarify what is said above (hope the code is self-explanatory).

.nav-link-group > a {
  color: red;
}
<!-- apply a style `color: red` to those links only if they are siblings in the DOM -->
<div>Example 1 revised:</div>
<div class="nav-link-group">
  <a class="nav-link-primary">link</a>
  <a class="nav-link-secondary">link</a>
  <a class="nav-link-tertiary">link</a>
</div>

<hr>

<!-- only the last two links should be red, as they are siblings. -->
<div>Example 2 revised :</div>
<div>
  <a class="nav-link-primary">link</a>
  <span>Lorem</span>
  <span class="nav-link-group">
    <a class="nav-link-secondary">link</a>
    <a class="nav-link-tertiary">link</a>
  </span>
</div>

Upvotes: 1

RamenChef
RamenChef

Reputation: 5558

The first link isn't red because there's no preceding element to refer to, and there isn't a CSS selector that can do this. See Is there a "previous sibling" CSS selector?. A better idea would be to have a common parent element to refer to, such as .adjacent-links, like so:

.adjacent-links a { color: red; }
<a class="nav-link-primary">link</a>
<span>Lorem</span>
<span class="adjacent-links">
    <a class="nav-link-secondary">link</a>
    <a class="nav-link-tertiary">link</a>
</span>

EDIT 10/11/2016:

If you have a lot of these links to manage, or they're automatically generated, you can also use a bit of jQuery. Find the nav-links, check whether the next element is a nav-link, and if so, add the styling. You will need to have a common class for all the nav-links (in this case .nav-link) for this to run efficiently.

$('.nav-link').filter(function(e) {
    return e.nextElementSibling.classList.contains('nav-link');
}).css({
    color: 'red'
});

Upvotes: 4

priya_singh
priya_singh

Reputation: 2488

.nav-link-primary ~ a,.nav-link-primary { color: red; }

Use above css.

Hoping this will help you :)

Upvotes: 0

Related Questions