Home > Web Front-end > CSS Tutorial > More Real-World Uses for :has()

More Real-World Uses for :has()

Christopher Nolan
Release: 2025-03-09 11:51:12
Original
269 people have browsed it

More Real-World Uses for :has()

CSS's :has() pseudo-class is undoubtedly one of my favorite new features of CSS, and I believe many participants in the State of CSS survey agree with this. This ability to "invert" selectors gives us unexpectedly powerful capabilities.

The reason why it is called "more powerful" is because many smart developers have published many amazing clever ideas, such as:

  • Jen Simmons' "Use :has() as CSS Parent Selector and More"
  • Bramus' "Implementing a Number of Query for "Element Islands" with the same Class" using CSS :has()
  • Bramus' "Setting Parent Element Styles Based on Number of Children"
  • Manuel Matuzović's "Using the Combinator in :has()"
  • Austin Gil's "Four Ways to Make Your HTML Forms Excellent"
  • Zoran Jambor's "Video: :has() Practical Cases"
  • Jhey Tompkins's ":has(): Family Selector"

This article is not an authoritative guide for :has(), nor is it a duplication of existing content. I just want to share some of the ways I most likely use :has() in my daily work…of course, the premise is that the browser support is good enough. (Firefox is the last browser to persevere, but it will be supported soon.)

Once the browser support is perfect, I will definitely use it everywhere :has(). Here are some real cases I have built recently, and I thought to myself, “How simple will this be once :has() is fully supported!”

Avoid operating outside JavaScript components

Have you ever built an interactive component that sometimes needs to influence the style of the page elsewhere? In the following example, <nav></nav> is a mega menu, opening it changes the color of the content above.

I feel like I always need to do this kind of thing.

This specific example is the React component I made for a website. I had to use document.querySelector(...) outside the React section of the "touch" page and toggle a class on <header></header>, <main></main>, or other components. This is not the end of the world, but it does feel a little awkward. Even in a complete React website (such as Next.js website), I had to choose between managing the menuIsOpen state on a higher component tree or performing the same DOM element selection - which is not quite React-style. With :has(), the problem is solved:

header:has(.megamenu--open) {
  /* 如果包含具有类“.megamenu--open”的元素,则以不同的方式设置 header 样式 */
}
Copy after login
Copy after login

My JavaScript component no longer needs to deal with other parts of the DOM!

Better table stripes user experience

Adding alternating row "stripes" to a table can improve the user experience. They help your eyes track the rows you are currently in when scanning the table.

But in my experience, this doesn't work well on tables with only two or three rows. For example, if your table has three rows in <tbody> and you "stripe" each "even" row, you may end up with only one stripe. This is not worthy of this pattern and may make the user wonder what is special about that highlighted line. Using Bramus Using <code>:has() The technique of applying styles based on the number of child elements, we can apply table stripes when there are more than three rows:

Want more advanced features? You can also decide to do this only if the table has at least a specific number of columns:

header:has(.megamenu--open) {
  /* 如果包含具有类“.megamenu--open”的元素,则以不同的方式设置 header 样式 */
}
Copy after login
Copy after login

Remove conditional class logic from template

I often need to change the page layout based on what is on the page. Taking the following grid layout as an example, the location of the main content will change the grid area according to whether the sidebar exists.

This may depend on whether the sibling page is set in the CMS. I usually use template logic to conditionally add BEM modifier classes to the layout wrapper to fit both layouts. The CSS may look like this (responsive rules and other content are omitted for brevity):

table:has(:is(td, th):nth-child(3)) {
  /* 只有在有三列或更多列时才执行操作 */
}
Copy after login

Of course, from a CSS perspective, this is absolutely fine. But this does make the template code a little messy. Depending on your template language, adding a bunch of classes conditionally can become very ugly, especially if you have to do the same with many child elements.

Compare this with a method based on :has():

/* m = 主要内容 */
/* s = 侧边栏 */
.standard-page--with-sidebar {
  grid-template-areas: 's s s m m m m m m m m m';
}
.standard-page--without-sidebar {
  grid-template-areas: '. m m m m m m m m m . .';
}
Copy after login

Honestly, from a CSS perspective, this is not much better. But in my opinion, removing the conditional modifier class from the HTML template is a good gain.

It's easy to think of the micro design decisions of :has() - when images are included in the card, for example - but I think it's also very useful for these macro layout changes.

Better specific management

If you read my previous articles, you will know that I am a persistent in specificity. If you are like me and don't want specific scores to surge when adding :has() and :not() to the entire style, be sure to use :where().

This is because the specificity of :has() is based on the most specific element of in its parameter list. So if you include something like ID in it (I don't know why!) your selector will be hard to overwrite in the cascade.

On the other hand, the specificity of

is always zero and will never increase the specificity score. :where()

/* m = 主要内容 */
/* s = 侧边栏 */
.standard-page:has(.sidebar) {
  grid-template-areas: 's s s m m m m m m m m m';
}
.standard-page:not(:has(.sidebar)) {
  grid-template-areas: '. m m m m m m m m m . .';
}
Copy after login
Bright future

These are just some of the features I can't wait to use in a production environment. CSS-Tricks Almanac also provides some examples. What are you looking forward to using

? What real cases have you encountered that would be the perfect solution? :has()

The above is the detailed content of More Real-World Uses for :has(). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template