CSS selector for immediately succeeding child element

Viewed 303

Two simple HTML examples:

<p>
  <i>Some text</i>
</p>

<p>Here's a paragraph that has <i>some text</i>, and then some more</p>

When using CSS, this selects the <i>'s in both cases:

p > i {
  border: 1px solid red;
}

> targets every <i> within every <p>.

What I'm looking for is a way to only target the <i>'s that immediately follow upon the <p>, in other words, that targets the <i> in the first example but not in the second. Kind of in a way that + selects adjacent siblings, but for adjacent children. Is this possible?

I looked into jQuery's only-child selector, but this also targets the <i>'s in both examples, since the text ("here's a paragraph...") isn't considered a child.

2 Answers

You can't do this work using CSS but using javascript/jquery you can select target element as shown in bottom.

Select all i element and use .filter() to filtering selected elements. In filter callback check previous text of i using previousSibling property.

$("p > i").filter(function(){
  return this.previousSibling.nodeValue.trim() == "";
}).css("border", "1px solid red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
  <i>Some text</i>
</p>
<p>Here's a paragraph that has <i>some text</i>, and then some more</p>
<p>
  <i>Some text</i>
</p>
<p>text <i>some text</i>, text</p>

You can do this with plain javaScript or jQuery. Since you tagged jQuery in your question i made a solution with it. See below.

I made the solution using index. To be sure i always get the first item, i used trim() to delete the whitespaces because

<p>
  <i>sometext</i>
</p>

would make <i> to have index of 3 instead of 0. That's why you need trim().

Then you just do what you want with that i tag. I added a class and styled it in CSS.

const paragraph = $("p");
const i = $('p > i')
$(paragraph).each(function() {
  const index = $(this).html().trim().indexOf('<i>');
  index === 0 ? $(this).find(i).addClass('change-me') : ''
})
i.change-me {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
  <i>Some text</i>
</p>

<p>Here's a paragraph that has <i>some text</i>, and then some more</p>

Related