zurfyx
zurfyx

Reputation: 32787

CSS/SCSS Adjacent sibling selector between certain types

Is there any way to accomplish all combinations of sibling selectors without having to write them all one by one?

Let's say I want font-size: 30px; in the second element, and any element can be an a, b or span.

I would normally write:

a + b, b + a, a + span, span + a, b + span, span + b {
  font-size: 30px;
}

But that's leads to n*(n-1) combinations!

I'm looking forward something like this:

{a,b,span} + {a,b,span} {
  font-size: 30px;
}

Though if there is no alternatively let me know if the best choice is to always make sure that the elements contained are always the types I want so I can use *:

* + * {...}

CSS solution if possible, or SCSS if it leads to a cleaner or the only unique possible solution.

Edit:

Some of you are suggesting nth-child. Whilst this is good for one or two formattings, that was not my aim (my fault, should've probably specified it better).

I meant to give result to a long div of text containing different formatting. I.e.:

<div class="text">
  <span>The weather</span> <i>is</is> <img src... /> <b>nice</b> <span>today</span>
</div>

So, what I thought at first was to change the ones I wanted to format to <div class="whatever"> so I could just focus div with certain class. But then again, something like { span, i, b } would be the most ideal.

Upvotes: 3

Views: 2382

Answers (3)

eballeste
eballeste

Reputation: 849

the accepted answer is outdated.

today, the correct answer would be to use the is pseudo-class which is now supported by all browsers:

support for is:

p {
  margin: 0;
}

:is(p, div) + :is(p, div) {
  margin-top: 24px;
}
<p>lorem ipsum</p>
<div>hello</div>
<p>consecetur loremis pestillis</p>
<div>world</div

Upvotes: 0

David Thomas
David Thomas

Reputation: 253396

In compliant browsers (sigh...), there's the option of using:

:matches(a, b, span) + :matches(a, b, span):nth-child(2) {
  color: #f90;
}

To style the :nth-child(2) element that is an <a>, <b> or <span> element following a previous sibling element of the type <a>, <b> or <span>.

The problem, of course, is that "in compliant browsers" part, and so far IE and Edge are both reluctant to join that particular party. Also, Webkit (Chrome, Opera and Android) are implementing a vendor-prefixed incorrect version using :-webkit-any(). On the plus side, though, as I write now, Safari, both desktop and iOS implement the :matches() pseudo-class correctly.

So, if you don't require IE/Edge support you have the option of:

:-webkit-any(a, b, span) + :-webkit-any(a, b, span):nth-child(2) {
  color: #f90;
}
:-moz-any(a, b, span) + :-moz-any(a, b, span):nth-child(2) {
  color: #f90;
}
:matches(a, b, span) + :matches(a, b, span):nth-child(2) {
  color: #f90;
}

a::before {
  content: 'link';
}
b::before {
  content: 'bold'
}
span::before {
  content: 'span';
}
em::before {
  content: 'em';
}
:-webkit-any(a,
b,
span) +:-webkit-any(a,
b,
span):nth-child(2) {
  color: #f90;
}
:-moz-any(a,
b,
span) +:-moz-any(a,
b,
span):nth-child(2) {
  color: #f90;
}
:matches(a,
b,
span) +:matches(a,
b,
span):nth-child(2) {
  color: #f90;
}
<div>
  <a href="#"></a> <span></span>
</div>
<div><span></span>
  <a href="#"></a>
</div>
<div><b></b>  <span></span>
</div>
<div><b></b>
  <a href="#"></a>
</div>
<div><b></b>  <em></em>
</div>
<div><em></em>
  <a href="#"></a>
</div>

JS Fiddle demo.

References:

Upvotes: 3

mholzer78
mholzer78

Reputation: 315

I think

a *:nth-child(2), b *:nth-child(2) {
  font-size: 30px;
}

should work

Upvotes: 0

Related Questions