Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS pseudo-selector for h1-h6? #1008

Open
pmaxhogan opened this issue Feb 6, 2017 · 17 comments
Open

CSS pseudo-selector for h1-h6? #1008

pmaxhogan opened this issue Feb 6, 2017 · 17 comments

Comments

@pmaxhogan
Copy link

I frequently find myself writing CSS like this:

h1, h2, h3, h4, h5, h6{
     ...
}

It annoys me that I have to type h1, h2, h3, h4, h5, h6 so much. But it gets worse:

article h1, article h2, article h3, article h4, article h5, article h6{
     ...
}

or even

article h1.bold:hover, article h2.bold:hover, article h3.bold:hover, article h4.bold:hover, article h5.bold:hover, article h6.bold:hover{
     ...
}

Wouldn't it be nice to just type

:heading{
     ...
}

or

article :heading{
     ...
}

or

article :heading.bold:hover{
     ...
}

:heading just matches h1-h6. It would be easy to implement for browser vendors and easy to polyfill. But extremely helpful.

Having a heading selector like :heading would be AWESOME!

@notoriousb1t
Copy link

notoriousb1t commented Feb 6, 2017

Peanut gallery here. :heading seems ultra specific. Maybe we would be better served by a tag selector? Something like

/h[0-6]/ {
   font-weight: bold;
}

With custom tags in html, there is a good use case for prefixed elements

<react-list-view></react-list-view>

would be selected by

/react-*/ {
   font-weight: bold;
}

@SelenIT
Copy link
Collaborator

SelenIT commented Feb 7, 2017

There is the CSS Custom Selectors proposal (it even has its PostCSS plugin) which would solve this exact issue and much more. But doesn't :matches(h1, h2, h3) from Selectors level 4 already solve the main problem here (code duplication)?

@pmaxhogan
Copy link
Author

See #1010

@fantasai fantasai added the selectors-4 Current Work label Mar 30, 2017
@fantasai fantasai added selectors-5 and removed selectors-4 Current Work labels Jan 1, 2018
@annevk
Copy link
Member

annevk commented Feb 23, 2018

whatwg/html#3499 contains a :heading/:heading() pseudo-class selector proposal. @fantasai wrote that Selectors should maybe define that given that other host languages might have utility for it too. If it's successful for HTML that seems reasonable to me.

@tabatkins
Copy link
Member

But doesn't :matches(h1, h2, h3) from Selectors level 4 already solve the main problem here (code duplication)?

No, because HTML has ways of assigning heading levels that go beyond tagnames - h1 nested inside of sectioning elements automatically becomes a second/third/etc level heading, as appropriate. (Plus, :heading really is pretty dramatically shorter to type than :matches(h1, h2, h3, h4, h5, h6), and is a pretty common thing to want to style.)

@Crissov
Copy link
Contributor

Crissov commented Feb 23, 2018

Would :heading match any of <caption>, <figcaption>, <label>, <legend> as well?

@tabatkins
Copy link
Member

Nah, none of those are "headings" in HTML's semantics. They're labels for some content, which serve a similar purpose, but aren't the same thing.

@inoas
Copy link

inoas commented Feb 23, 2018

Is /h[0-6]/ actually a valid selector (not to my knowledge)
But if it is not, why not make that a valid selector?

@tomhodgins
Copy link

@inoas are there any other HTML tag names, other than H1–6 where a regex-like selector like that would make sense?

If you're wanting to select tags by partial tag name like that, though CSS selectors won't currently do it, you can do this with XPath using a selector like: //*[substring-after(name(), "h") > 0]

Demo: https://codepen.io/tomhodgins/pen/ybgMpN

@tabatkins
Copy link
Member

It's not a valid selector, but it's also a remarkably complex feature for something as limited as "match this family of tagnames". LIke @tomhodgins says, there's very little call for substring-matching on tagname; insofar as we do want such a thing, prefix/suffix-matching like XPath provides probably provides 90%+ of the desired functionality.

But such a thing wouldn't even work here, because part of the point of a heading-level selector is that it works off of the HTML outline algorithm, not the tagname.

@Crissov
Copy link
Contributor

Crissov commented Feb 23, 2018

Hm. Then I guess a related :caption selector would match the elements I mentioned and headings that are the top level in a <section>.

Iʼm not sure what to do with <th> though.

@annevk
Copy link
Member

annevk commented Oct 11, 2019

@emilio raised an interesting concern that I don't have a good solution for. If you have

:heading(1) { ... }
:heading(2) { ... }
:heading(3) { ... }

and then for some reason you end up with a level 4 heading on your page, the ideal "failure mode" is that it'll render the same as 3.

Maybe instead what you want is heading-level as a variable that can be used by calc() or some such.

Thoughts?

Unless there's a relative clear answer here I'm inclined to leave this feature out of whatwg/html#3499 and save that for a future iteration.

cc @hober

@annevk
Copy link
Member

annevk commented Oct 11, 2019

@js-choi's idea in whatwg/html#3500 might be another way out here, but that looks quite involved as well.

@emilio
Copy link
Collaborator

emilio commented Oct 11, 2019

An alternative idea is saying that :heading(n) matches if the heading level is less than or equal to n.

@AmeliaBR
Copy link
Contributor

AmeliaBR commented Oct 12, 2019

An alternative idea is saying that :heading(n) matches if the heading level is less than or equal to n.

I wouldn't want that to be the default behavior, but if this selector is adopted, I think it does make sense to add a second syntax that supports inequalities. It could be harmonized with the syntax being discussed in #4140 for nth-child() family of selectors:

  • heading(3) for only level-3 headings
  • heading(n <= 3) for level 1, 2, or 3
  • heading(n > 3) for level 4, 5, 6, (and beyond)

(Edit: and now I see that this is the exact proposal from the HTML issue linked by Anne)

@AndreasKarz
Copy link

@inoas are there any other HTML tag names, other than H1–6 where a regex-like selector like that would make sense?

If you're wanting to select tags by partial tag name like that, though CSS selectors won't currently do it, you can do this with XPath using a selector like: //*[substring-after(name(), "h") > 0]

Demo: https://codepen.io/tomhodgins/pen/ybgMpN

Don't work with Selenium :-(

@a-a-GiTHuB-a-a
Copy link

%heading works…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests