I wonder why I have to follow "Tech Twitter" to find out the good news, so I'm the one to write a short post here on dev.to to celebrate a new CSS ...
For further actions, you may consider blocking this person and/or reporting abuse
A really good introducing post to explain :has() (pseudo-class selector) and very useful.
Thanks!
Months later, after many people used to argue that there was no real world use case for
has:
, suddenly "TechTwitter" is full of posts about this great newhas:
property and that everyone should definitely try it and open up for the new possibilities.Must have been some great CSS conference that I missed unfortunately, but still happy that CSS is moving forward and still (or again) fascinating web designers and developers.
Be aware that you might not have a browser to test parent selectors early in 2022 yet. Safari updates currently don't ship or install on older Apple operating systems, and Gnome Web, although based on a WebKitGTK, which I understand to be a based on a fork of AppleWebkit, did not support parent selectors in WebKitGTK 2.34.3 yet either, and neither did Vivaldi and Google-Chrome as of February 2022.
Can you please share more of the code surrounding your use case? Because it seems like the only thing you add to the parent is
width: 100%
, and the rest you are nesting in ah1
selector anyways.A trick I use for CMS generated HTML (i.e. everything without classes) is to use a
:not([class])
selector. Then anything else, e.g. an unordered list or hyperlinks in a nav menu, just need any class added (or manually override the styles).Here is an example (similar markup from a demo shop, with h2 headings. The top-level
cms-section.cms-section-default
only differ by theirpos-n
position classes which have no benefit compared tonth-child
.Any other distinction, even the content id's, can only be made on a descendent level.
The structure is as follows:
Here is a screenshot as well
Thanks, but sorry I still don't see the value here.
Your CSS only applied
width: 100%
in the:has
selector, which adiv
would have by default as a block level element.Otherwise, if targeting the
h2
orp
, you could do that with descendent selectors or the:not([class])
as I suggested in my previous comment.Perhaps a better example could be for forms or something, where you could combine with the
:invalid
pseudo-class or similar to change the parentdiv
styles:Thanks for the form example!
Still don't see how you would have done it with
not
when all thediv
elements are undistinguishable by their class names. Of course, a div should be a block level element by default. You are lucky you didn't have to deal with the existing CSS. Using descendant selectors was what I did in the end, still didn't find it elegant or robust, probably it will break after the next framework update.Better way would be if the customers content editors would choose different types of block templates which could then be given distinct class names.
Complex code should always arise suspicion that something might be conceptually wrong by design and could be solved at the problem's root cause. That's what I meant by "hotfixing a hotfix" in CSS (oh, and don't even start to count the number of
!important
in the existing style sheets).Sorry, I didn't make that clear. The
:not([class])
would be for targeting the paragraphs or headings that come from the CMS or whatever, where you don't have the ability to add or target classes.e.g.
The lead paragraph would be black, inheriting the color from the body.
So the not selector makes them act like global element styles that you opt out of by simply adding a class to the HTML element (even a blank string).
The assumption is that anything you want custom styling for that isn't regular body copy content (from a CMS or similar), you probably have control over the HTML and would normally be adding classes to style them anyways.
But anyways, this is obviously a whole other conversation! 🙂
Updated my article quoting Byungwoo Lee, Eric Meyer, Chris Coyier and Jonathan Snook on performance issues of parent selectors and how the Blink team finally solved them.
Included jQuery code as it's still the only working polyfill I found.
Anyone know a vanilla JS solution?
Last time I checked, this was still a working draft. It doesn't make sense to implement this for any browser as long as the details are still not set in stone.
I'm waiting for this feature too. Had a use case for it yesterday and had to reside to a workaround instead. :(
As I understand, the implementation details have been fixed now, unless the working proof of concept reveals any flaw that has been overlooked until now. But how to evaluate if nobody used it in real life?
I will use this as a kind of progressive-enhancement addition to the every-other-browser fallback code once I get my hands on a browser that actually supports
:has
, but neither my real Apple devices (an iPhone 6+ and a MacBook from 2010) nor GnomeWeb (which I hoped to be some kind of "Safari for Linux") allow me to test it right now. I don't have a new MacBook, no Hackintosh macOS in a VM, and I don't want to pay for BrowserStack only to test an upcoming feature that's not even supported by Chrome yet either.Still don't understand that Apple restricts browsers on older operating systems when they don't even ship their own browser in the latest version. At least this is one thing Microsoft got right with a new Edge, after making all the negative experience they were able to gather after years of trying to get rid of outdated Internet Explorer versions.
Agree, that it's probably to early to use parent selectors in real life, even two months after originally celebrating the news.
Thanks @lukeshiru ! That looks very useful. So we can use
has
in css and addquerySelectorAllWithHas
as a progressive enhancement for any browser without has support.Another update: added an actual use case I found in my git history, as many people seemed to have a hard time imagining any useful scenario for
:has()
apart from the simple MDN example.