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

display: contents with nth-child and other pseudo-classes #11647

Closed
FrameMuse opened this issue Feb 4, 2025 · 3 comments
Closed

display: contents with nth-child and other pseudo-classes #11647

FrameMuse opened this issue Feb 4, 2025 · 3 comments
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. selectors-4 Current Work

Comments

@FrameMuse
Copy link

FrameMuse commented Feb 4, 2025

I was playing around display: contents and it seemed to be working fine until I applied nth-child selector. Shortly, it takes into account elements with display: contents as normal elements, which breaks nth-child matching.

Example

Where there are multiple .card elements, each one being wrapped into div with display: contents.

.card:nth-child(2n):not(:last-child)::before {
  content: "";
  // ...
}

Maybe I misunderstood something, though I think it should work as well since display: contents should display an element as if it's not there, right?

@FrameMuse FrameMuse changed the title display: contents with nth-child display: contents with nth-child and other pseudo-classes Feb 4, 2025
@Loirooriol
Copy link
Contributor

:nth-child() is purely based on the DOM, and display: contents only affects the box tree, not the DOM tree.

That would introduce all kinds of circularities, see https://wiki.csswg.org/faq#selectors-that-depend-on-layout

<style>div:has(:first-child) > span { display: contents }</style>
<div><span></span></div>

If this considers the span to be the 1st child, then display: contents applies which would prevent it from being the 1st child according to your proposal, and thus display: contents would stop applying and it would become the 1st child again, and so on.

@Loirooriol Loirooriol added Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. selectors-4 Current Work security-needs-resolution Issue the security Group has raised and looks for a response on. and removed security-needs-resolution Issue the security Group has raised and looks for a response on. labels Feb 4, 2025
@FrameMuse
Copy link
Author

FrameMuse commented Feb 5, 2025

I see the problem.

Though this example won't work, even though my rationale says it should:

<style>span:first-child { background: red }</style>
<div style="display: contents"><span></span></div>
<div style="display: contents"><span></span></div>

To avoid circularities, display: contents can be omitted if presented within a dom-based selector, which would solve the problem.

However you mentioned that display: contents is about the box tree, in this case, it makes sense.


Explanation why I needed that I was looking for a way to contain elements within another element so that it would persist in the DOM, but won't be interacting in ANY way as if it's not there at all. So far I wasn't so lucky, I found only
  • all: inherit - but works poorly with layouts (flex, grid)
  • display: contents - but it's only about tree boxes
  • DocumentFragment - but it's not attached to the dom

sigh


Found a related topic: whatwg/dom#736

@Loirooriol
Copy link
Contributor

so that it would persist in the DOM, but won't be interacting in ANY way as if it's not there at all

You can't have that. If you change the DOM, then all things that are based on the DOM (like CSS selectors) will see the change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. selectors-4 Current Work
Projects
None yet
Development

No branches or pull requests

2 participants