How to Target All <H> Tags with a Single Selector

Can I target all H tags with a single selector?

The new :is() CSS pseudo-class can do it in one selector.

For example, here's how you could target all headings inside a container element:

.container :is(h1, h2, h3, h4, h5, h6)
{
color: red;
}

Most browsers now support :is(), but keep in mind that most browsers made before 2020 didn't support it without a prefix, so be careful about using this if you need to support older browsers.

In some cases, you may instead want to use the :where() pseudo-class, which is very similar to :is() but has different specificity rules.

Using less to target all h tags

Just like in the linked answer, there're plenty of ways (e.g. using extend, loops, parent selector or unnamed rulesets).

For your last snippet the best fit would be a mixin with ruleset as parameter (aka unnamed/detached ruleset):

// define:
.headings(@style) {
h1, h2, h3, h4, h5, h6 {
@style();
}
}

// use:
.something {
.headings({
color: red;
});
}

How to target direct text and not text within tags?

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 selector for multiple sub-elements

Modern Option

Note: it may not be compatible with older browsers:

.live_grid :is(h1,h2,h3,h4,h5) {
/* style here */
}

See here for more information about :is(): https://developer.mozilla.org/en-US/docs/Web/CSS/:is

Standard Option:

If you want to style all the headers in that class, you have to do it like this (which could also be done without the line breaks). Notice each selector has .live_grid in it:

.live_grid h1,
.live_grid h2,
.live_grid h3,
.live_grid h4,
.live_grid h5,
.live_grid h6 {
/* style here */
}

When you comma separate things, they're independent of each other - hence the need to reference the class again.

For example:

#myDiv1, .live_grid, #myDiv2 {
color: blue;
}

This would set the text-color for everything in the #myDiv1 element, everything in the #myDiv2 element, and everything in the .live_grid element to having text color blue.

This also explains the reason your CSS is matching all the headers - you're referencing them individually, separated by commas - there is no selector for their containing element(s).


CSS pre-processor option

Or, you can always go with something like LESS or SASS which allows you to write nested rules something like this:

#live_grid {
h1, h2, h3, h4, h5, h6 {
/* style here */
}
}

Custom class option

Lastly, you could add a class to all of your headers and just refer to that class:

<-- HTML -->
<h1 class="custom-header">Title of Blog Post</h1>
<h2 class="custom-header">Subtitle of Blog Post about Pizza</h2>

/* CSS */
.custom-header {
/* style here */
}

Select all the h tag inside a class

No, since attribute selectors work only on, well, attributes. You can't use a regular expression or something similar for element names. Certain systems like LESS or SASS enable you to write such expressions with less code, however there is no such thing in native CSS.



Related Topics



Leave a reply



Submit