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-shadow-parts][css-nesting] is & allowed after ::part() #10788

Open
dbaron opened this issue Aug 27, 2024 · 10 comments
Open

[css-shadow-parts][css-nesting] is & allowed after ::part() #10788

dbaron opened this issue Aug 27, 2024 · 10 comments

Comments

@dbaron
Copy link
Member

dbaron commented Aug 27, 2024

I don't think it's clear whether the & selector is allowed after the ::part() pseudo-element. At least, I read what I think are the relevant specs and I couldn't find any wording that gives me a clear answer.

For example, is the following CSS:

:hover {
  ::part(mypart)& {
    text-decoration: underline;
  }
}

equivalent to:

::part(mypart):hover {
  text-decoration: underline;
}

or is it invalid?

@dbaron
Copy link
Member Author

dbaron commented Sep 4, 2024

Based on this test:

<!DOCTYPE HTML>
<style>
  #host {
    padding: 3px;
    width: fit-content;
  }
  #host::part(p):hover {
    color: green;
  }
  :hover {
    #host& {
      background: aqua;
    }
    #host::part(p)& {
      background: lime;
    }
  }
</style>
<div id="host">
</div>
<script>
  let shadow = document.getElementById("host").attachShadow({mode: "open"});
  shadow.innerHTML = `<div part="p">this is the part, hover me</div>`;
</script>

this currently doesn't work in any of Chromium, Gecko, or WebKit.

@cdoublev
Copy link
Collaborator

cdoublev commented Sep 4, 2024

According to this comment, & is a a new "simple" selector (<simple-selector>). So it can only replace <type-selector> | <subclass-selector>, not <pseudo-class-selector> in <pseudo-compound-selector>.

@tabatkins
Copy link
Member

Yeah, per grammar that's not currently allowed. I don't see a big reason to disallow it, tho, since it's morally equivalent to an :is() which is allowed.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-shadow-parts][css-nesting] is & allowed after ::part(), and agreed to the following:

  • RESOLVED: No change to spec. & is not allowed after ::part
The full IRC log of that discussion <dholbert> dbaron: this is getting into fun stuff that I don't have strong opinions about, mixing multiple new features
<dholbert> dbaron: is the & selector after ::part?
<dholbert> dbaron: we have restrictions saying these selectors are allowed, these aren't (after ::part)
<kbabbitt> s/selector after/selector allowed after/
<dholbert> dbaron: should we allow the nesting & selector after part, when it is a selector and is after part, or not
<fantasai> https://github.com//issues/10788#issuecomment-2329279090
<dholbert> fantasai: I'd go with "no" per this comment^
<dholbert> fantasai: we do allow ::is but with restrictions, IIRC
<dholbert> fantasai: the & is pulling in a whole type-selector ... Unless we're wanting to allow type-selector, I don't think it makes sense to allow &
<dholbert> fantasai: proposed resolution: no change to spec, & is not allowed after ::part
<dholbert> RESOLVED: No change to spec. & is not allowed after ::part

@tabatkins
Copy link
Member

I'd like to revisit this. I'm fine if we do end up keeping the resolution, but from the minutes it doesn't look like it was argued very well. The only real comment aside from dbaron's introduction was referring to a comment about the current state of the grammar, and didn't reference my response to that comment.

My point is that #host::part(p):is(:hover, :active) is allowed and perfectly fine, so :hover, :active { #host::part(p)& {...}} is also meaningful and potentially useful. Similarly, #host::part(p):is(div) is allowed (but doesn't match anything; the contextual restriction against type selectors after a pseudo-element causes the :is() to consider its argument invalid), so div { #host::part(p)& {...}} is at least well-defined, if not useful.

@jpzwarte
Copy link

I just ran into this.

This works:

    sl-month-view::part(finish) {
        background: var(--sl-color-success-plain);
        border-radius: 50%;
        color: var(--sl-color-text-inverted);
      }

      sl-month-view::part(finish):hover {
        background: var(--sl-color-success-bold);
      }

This doesn't:

    sl-month-view::part(finish) {
        background: var(--sl-color-success-plain);
        border-radius: 50%;
        color: var(--sl-color-text-inverted);

        &:hover {
          background: var(--sl-color-success-bold);
        }
      }

This is totally not obvious to me (let alone a web dev who does not read csswg issues on github).

@dbaron
Copy link
Member Author

dbaron commented Oct 14, 2024

@jpzwarte the example in #10788 (comment) is not what this issue is about. This issue is about whether you're allowed to write a single selector that contains & after ::part(), such as ::part()&. (I'm looking to see if there's an issue about your issue but I haven't found one yet.)

@dbaron
Copy link
Member Author

dbaron commented Oct 14, 2024

I think your issue is #9702.

@dbaron
Copy link
Member Author

dbaron commented Oct 14, 2024

(That said, there are some comments in #9702 that suggest that &::part() and ::part()& are equivalent... which feels wrong, and seems problematic as a premise for this issue.)

@jpzwarte
Copy link

@dbaron Thanks for pointing it out. I posted in #9702 as well. But if you feel i stand a better chance by creating a new issue i'll do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Friday afternoon
Development

No branches or pull requests

5 participants