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

Styling default slot content with ::slotted #631

Closed
JanMiksovsky opened this issue Mar 21, 2017 · 6 comments
Closed

Styling default slot content with ::slotted #631

JanMiksovsky opened this issue Mar 21, 2017 · 6 comments

Comments

@JanMiksovsky
Copy link

I've come across a case where a component wants to style default slot content with ::slotted, but cannot do so.

For reference, default slot content are direct slot children, which are used if no light DOM nodes are assigned to the shadow host:

<slot>
  <div>I'm default slot content</div>
</slot>

Such default nodes are returned in calls to assignedNodes({ flatten: true }). (They are not returned in calls to assignedNodes(), which seems weird to me, but that's a separate point.)

The puzzle is why the div above can't be styled with the ::slotted selector. This use case is important for a component that wants to provide consistent styling for both default slot content and explicitly assigned nodes.

See http://jsbin.com/cuvetul/edit?html,output for a demo whose behavior is consistent in both Blink and WebKit, and yet counter to what I would expect. My reasoning:

  1. The algorithm to find flattened slotables includes a step which states, "If slotables is the empty list, then append each slotable child of slot, in tree order, to slotables." As I read this, it means the slot's children are counted as flattened, assigned nodes.
  2. Invoking assignedNodes({ flatten: true }) on a slot with no explicitly assigned nodes returns the default slot content. This is consistent with the above point.
  3. The ::slotted spec says, "The ::slotted() pseudo-element represents the elements assigned, after flattening, to a slot."
  4. Using ::slotted styles all flattened nodes assigned to a slot, which is consistent with the above point, but not the slot's default nodes, which is surprising.

(Disclaimer: I've done my best to locate what I believe are the most current specs, and interpret them to the best of my ability. That said, web specs usually melt my small brain. People with bigger brains may be able to interpret the above specs differently.)

I'm hitting this issue in a real-world Shadow DOM component that wants to apply consistent styling to a slot's assigned nodes in all cases.

If there's agreement that ::slotted should apply to all of a slot's flattened assigned nodes, so that ::slotted and assignedNodes({ flatten: true }) can gain the close correspondence implied by the specs, then I'd be happy to file bugs against WebKit and Blink.

@rniwa
Copy link
Collaborator

rniwa commented Mar 21, 2017

This indeed seems counterintuitive. This might be just implementation bugs in both WebKit and Blink given the spec text.

@hayatoito
Copy link
Contributor

Good catch. Yeah, I think this is not a spec bug. This should be considered as an implementation bug.

The following is a brief history:

  1. We defined ::slotted to consider assignedNodes({ flatten: true }), instead of assignedNodes(), in the spec. That was intentionally done.
  2. Blink implemented ::slotted
  3. After that, we introduced the concept of fallback contents of slots, and we extended the meaning of assignedNodes({ flatten: true }) to consider slot's children too in the spec, without any considering its impact for ::slotted. See slot element's fallback contents is never used #317
  4. It looks Blink forgot to update the implementation of ::slotted to consider slot's fallback contents. :(

Regarding the spec, although we have not considered anything about an impact for ::slotted, in #317, I am +1 for the status quo of the spec.

If it is okay, I'll file a bug in Blink and close this spec bug.

@hayatoito
Copy link
Contributor

hayatoito commented Mar 22, 2017

I've filed a bug for Blink: https://bugs.chromium.org/p/chromium/issues/detail?id=703984
I think it is okay to close this spec bug.
If someone has a further opinion for the current spec, please let us know that.

@rniwa
Copy link
Collaborator

rniwa commented Mar 22, 2017

Filed a WebKit bug in https://bugs.webkit.org/show_bug.cgi?id=169948 as well.

@JanMiksovsky
Copy link
Author

Thanks!

@jonathantneal
Copy link

While this has been closed for some time, I’m currently have this same issue, and I have been getting directed here from search.

I did not see any resolution from the browser vendors, so if it helps others in a similar predicament, I am using the following workaround:

:not([name])::slotted(*) {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants