Is there a CSS selector for the first child, taking text nodes into account?

css selectors
css text nodes
css selector class contains text
css child selector
css select text inside div
css selectors cheat sheet
css selector tutorial
css advanced selectors

I'm trying to find a CSS selector for an element that is the first child, taking any text nodes into account that might come before it (i.e. if any elements come before, possibly unwrapped text nodes, this is no longer considered the first child).

But it seems :first-child does not include text nodes, neither does :nth-child, etc.

This is where I'm at, but it's not working:

.red-if-not-first {
  color: red;
  font-weight: bold;
}

.red-if-not-first:first-child {
  color: green;
}
<p>
  Lorem ipsum. <span class="red-if-not-first">This should be red, not green, because some content comes before it.</span> Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>

<p>
  <span class="red-if-not-first">This is rightly green, not red, because it's first bit of content in this paragraph.</span> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>

One workaround could be to make use of the :empty pseudo class. You will need more markup though.

p .red-if-not-first {
  color: red;
  font-weight: bold;
}

p > :empty + .red-if-not-first {
  color: green;
}
<p>
  <span>Lorem ipsum.</span> <span class="red-if-not-first">This should be red, not green, because some content comes before it.</span> Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>

<p>
  <span></span> <span class="red-if-not-first">This is rightly green, not red, because it's first bit of content in this paragraph.</span> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>

:first-child, but I will take a look at it, thanks :-) I thought if there was any way in using In the example given in the OP, you could (remove the :first-child rule and) add the h1 's margin if there's no text before the heading, but if there is the h1 you would have to account for that or use a fixed unit such as rem or px . Definition and Usage. The :first-child selector is used to select the specified selector, only if it is the first child of its parent.

In essence, you're asking if text can affect the styling of dom elements and the answer is - no, because text is not a dom element of it's own.

We can prove this with a simple experiment. Just add a marker element at the beginning of the paragraph and then use a sibling selector to override color. You'll see that this works in both cases, because text has no effect on surrounding dom flow.

For the record, I thought I was onto something by initially doing this marker experiment with ::before pseudo elements but they can't be used with sibling selectors either. Pseudo elements are not real elements and will have no effect on the relationships of actual dom tree.

.red-if-not-first {
  color: red;
  font-weight: bold;
}

.red-if-not-first:first-child {
  color: green;
}

.marker + span{
  color: red;
}
<p>
  <i class="marker"></i>
  Lorem ipsum. <span class="red-if-not-first">This should be red, not green, because some content comes before it.</span> Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>

<p>
  <i class="marker"></i>
  <span class="red-if-not-first">This is rightly green, not red, because it's first bit of content in this paragraph.</span> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>

Is there a CSS selector for text nodes?, https://drafts.csswg.org/selectors-4/ Please add ::text or ::text-node selector to select all text nodes inside any element for Woule a pseudoelement selector only select direct-child text nodes for the [css-selectors] Standardize `:(‑moz‑)​first‑node` and `:(‑moz‑)last‑node` #3216 Already have an account? The first selector above is a decendant selector. It will select any list items that are anywhere underneath an unordered list in the markup structure. The list item could be buried three levels deep within other nested lists, and this selector will still match it. The second selector above is a child combinator selector. This means it will

If, for some strange reason, you can make do with only supporting Gecko, you can use-moz-first-node selector to do this.

https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-first-node

Child combinator, in that it's the only CSS selector that takes text nodes into consideration when Selecting unique children If you've ever wanted to select all the images that are The first is that you always apply it to the element you want to be an only child,​  The :nth-child selector allows you to select one or more elements based on their source order, according to a formula. It is defined in the CSS Selectors Level 3 spec as a “structural pseudo-class”, meaning it is used to style content based on its relationship with parent and sibling elements.

This is 2017. The answer is "No". There is no such CSS selector that can help you with this.

CSS: first-child selector including text nodes, Now consider parent/predecessor selectors in all their forms I haven't been able to find any other (CSS) methods to get the styling I what you have to work with, you can see that there are text nodes: a > +:first-child { }. Output: Descendant selector: Descendant selector is used to select all the elements which are child of the element (not a specific element). It select the elements inside the elements i.e it combines two selectors such that elements matched by the second selector are selected if they have an ancestor element matching the first selector.

[css-pseudo-5] ::text / ::text-node pseudoelement #2208, If you need the extra power of CSS3 selectors, load the optional selector-css3 module. can chain these operations: Y.one('#demo').remove(); From any given node, the first child node (or a list of multiple child nodes) that matches the selector. element as a YUI node, and they ignore adjacent text nodes in all browsers. The browser parses the fetched CSS, and sorts the different rules by their selector types into different "buckets", e.g. element, class, ID, and so on. Based on the selectors it finds, it works out which rules should be applied to which nodes in the DOM, and attaches style to them as required (this intermediate step is called a render tree).

CSS: The Definitive Guide: Visual Presentation for the Web, Applying CSS3 to Documents Eric A. Meyer you can select any element that has no children of any kind, including text nodes, Of the following elements, only the first and last would be matched by p:empty. As of early 2012, :empty is unique in that it's the only CSS selector that takes text nodes into consideration when  “In this example, it would select img tags but only if they were a child of an a tag.” because also . a img { border:none } select img tags only if they were a child of an a tag. instead a better example would be. ul < li { padding-left:0px; } which removes the padding left to all the li tag which contain another ul level

Identifying text-only nodes with CSS, firstChild read-only property returns the node's first child in the tree, or null if Any whitespace will create a #text node, from a single space to  The :first-child selector allows you to target the first element immediately inside another element. It is defined in the CSS Selectors Level 3 spec as a “structural pseudo-class”, meaning it is used to style content based on its relationship with parent and sibling content.

Comments
  • Would you be open to JavaScript solutions? I don't believe this is possible in CSS
  • I could manage it in JavaScript myself, but I was curious to see if there was a (preferable) CSS only way. I've searched high and low and only found "no", but they were all from several years ago.
  • If you want an automatic solution, it can only be done via javascript friend.
  • Thanks for the idea. Yes I thought about injecting an empty span at the start of each paragraph so I could use the + combination as a way of selecting the first instance in each paragraph. However I would have to use JS for that due to CMS limitations, so was wondering if there was a pure CSS way yet.
  • Ah, just ran the code in the answer from @Serg Chernata and seems my idea would not work. Thank you for your example which shows the markup I'd need
  • Markup is there for a reason. OP should do it the right way.