8

Is there a way to only target the direct text within a <h1>-Tag?

Here is an example on what I want to do:

<h1>I want to select this text with a css selector <small>but not this text</small></h1>

This does not seem to work:

h1:not(small)

Is it even possible?

Michael Benjamin
  • 265,915
  • 79
  • 461
  • 583
JiiB
  • 1,230
  • 1
  • 9
  • 23

3 Answers3

6

h1:not(small)

Your selector h1:not(small) doesn't work because it says this:

Target all h1 elements that are not small elements.

It's that same as using the h1 selector by itself.


h1 :not(small)

You would have been closer with h1 :not(small), which says:

Target all descendants of an h1 except small elements.

Boom! Exactly what you want.

Except that text contained directly inside an element (i.e, text with no tags around it) becomes an anonymous element. And anonymous elements are not selectable by CSS.

h1 :not(small) {
  color: orange;
}
<h1>This text is contained directly inside the container. It is not selectable by CSS. It is an anonymous element. <small>This text is inside a small element</small></h1>

<hr>

<h1><span>This text is contained in a span. It is selectable by CSS</span> <small>This text is inside a small element</small></h1>

CSS Parent Selector

For the small element to be excluded it would have to identify itself as a child of the h1.

But there is no parent selector in CSS.


Solution: Two selectors

You need two selectors to make this work:

  • The first sets the style on the parent.
  • The second overrides the first on the child.

h1 {
  color: orange;
}

h1 > small {
  color: black;
}
<h1>I want to select this text with a css selector <small>but not this text</small></h1>

More Information

Michael Benjamin
  • 265,915
  • 79
  • 461
  • 583
1

This is the closest it gets to retaining the style without any css that has been implemented by the parent div. This feature hasn't been fully integrated in all browsers, but it should work for some. Hope, it helps.

Browser support -

enter image description here

What's being done here?

The small tag is retaining its original CSS without being affected by the other styles. You can apply this on any of the child elements whose style you want to preserve.

small {
  all: initial;
  * {
    all: unset;
  }
}
h1 {
    color: #ff0000;
}
<h1>I want to select this tex with a css selector <small>but not this text</small></h1>
  • I can't see how this answers the question asked. This does one thing: selecting any child of `h1` that is not a `h1` itself. It doesn't exclude the `span` from adopting its parents styles... – agrm Nov 27 '17 at 17:11
  • Updated, check it again if it satisfies your query now. @agrm –  Nov 27 '17 at 17:16
  • Just something to keep in mind, this answer doesn't work on [a few browsers](https://caniuse.com/#feat=css-all). (as of the time of this comment) – zvava Nov 27 '17 at 17:42
0

Apply styles to h1 however you want, then, revert those changes in small, for example, if you only want to change the color you would use this code;

h1 { color: red; }
h1 small { color: initial; }

Or, if you have multiple style changes;

h1 {
    color: red;
    font-weight: italic;
    text-transform: uppercase;
}

h1 small {
    color: initial;
    font-weight: initial;
    text-transform: initial;
}

Please note that the initial CSS value can be used on every browser, except for IE and Opera Mini. View this page for more information

zvava
  • 91
  • 1
  • 2
  • 14