Re: [w3c/webcomponents] Support Custom Pseudo-elements (#300)

> I thought the same thing reading the initial draft.

I anticipated this reaction, and I probably should have been more explicit about what it's doing:  `::theme()` *is exactly the same, mechanically, as `@apply`*.  Literally, modulo some unimportant corners of the functionality, the two are doing *precisely* the same thing - letting you target a component arbitrarily far down in the shadow hierarchy.

It's `::part()` that's new and restrictive, compared to `@apply` - it's also the more common case, and better for avoiding shooting yourself in the foot.  Foot-shooting is much easier with `::theme()`, but it's also more obvious; if you didn't realize that `@apply` was *precisely* the same amount of foot-shooty, it's just because it was better at hiding its problems from plain sight. ^_^

> I wouldn't want the outcome of dropping @apply for ::part(). My understanding is that both are candidates for standardization still and that neither supersedes the other--is that right? I think each style option: custom properties, @apply with custom property sets, and named ::parts are differently useful and each could be individually selected for a component based on what's most appropriate or combined together facilitate different levels of customization.

No, not really; they're attacking the exact same problem space, and don't even have differing ergonomics to fall back on (like, say, `@mixin` and `@extend` do in Sass).

Ultimately, `@apply` is a bit of a dirty hack.  It shifts CSS machinery into other parts of CSS, and in so doing loses a lot of functionality:

* By using property names instead of selectors, you lose the ability to use pseudo-classes and pseudo-elements. You instead have to reinvent them yourself, manually, by creating additional variant property names and manually applying them to the selectors in question.
* By using property values instead of declaration blocks, you lose the cascade.  There can be precisely *one* winner who gets to set the whole block of properties (whoever wins the cascade for the custom property itself); you can't have a more specific selector set/override some of the properties without wiping out the whole thing and starting fresh.

`@apply` happened to be a relatively easy hack to define, is all, building directly on existing machinery. (Tho there were some really annoying niggling problems with transitions and animations that we had to work out, which complicates the implementation a decent bit.)  I invented it and promoted it because the earlier attempts to define `::part()` were never nailed down by anyone, and there were a number of important mechanics questions that hadn't been answered (which `@apply` answered automatically, by virtue of piggybacking on the existing custom property machinery).  Now that I think I've worked out all those issues with `::part()`, tho, I'm happy to support it as a substantially better approach to solving the styling problem.

The only loss is that `@apply` can also be used to style elements in the same light dom, while `::part()` is explicitly only for elements in a shadow.  But this usage suffers from the same problems I cited above; it's much better to just expose selector hooks for the elements you want to target and use CSS like normal.  (Which is precisely what `::part()` is doing - giving shadows the ability to expose selector hooks for their elements when they want it.)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/300#issuecomment-279031387

Received on Friday, 10 February 2017 18:49:30 UTC