w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.5k stars 660 forks source link

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

Open dbaron opened 2 months ago

dbaron commented 2 months ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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

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/w3c/csswg-drafts/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 commented 1 month ago

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 commented 2 weeks ago

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 commented 2 weeks ago

@jpzwarte the example in https://github.com/w3c/csswg-drafts/issues/10788#issuecomment-2411945524 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 commented 2 weeks ago

I think your issue is #9702.

dbaron commented 2 weeks ago

(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 commented 2 weeks ago

@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.