Re: [csswg-drafts] [css-shadow-parts-1] feedback from devs (#3467)

# ::part feedback + thoughts


Below are thoughts, questions, and general feedback from the SLDS Framework team regarding the currently implemented in Chrome. We're experimenting a little further with slots and some more complex examples, so I expect we'll add a couple other questions with examples.

## Feedback

### Access control

It would be very useful if it was possible to limit access to CSS rules for a defined part. The purpose is to limit the styling API of a component by only allowing certain things to be overridden or to lock down certain things that should never be overridden.

In the example below “part='title'” is defined but only “color” and “background-color” can be overridden, all other rules would be ignored.

We envision allow all by default with the possibility to allow or deny specific lists of CSS rules.

```
<x-foo>
    <h2 part="title" part-allow="color, background-color">Access control</h2>
    <slot></slot>
</x-foo>
```

```
x-foo::part(title) {
    color: purple; // allowed
    bacgkround-color: grey; // allowed
    height: 100%; // denied
}
```

In the example below “part='title'” is defined but “color” and “background-color” are locked, all other rules would apply and override the component's default styles.

```
<x-foo>
    <h2 part="title" part-deny="color, background-color">Access control</h2>
    <slot></slot>
</x-foo>
```

```
x-foo::part(title) {
    color: purple; // denied
    background-color: grey; // denied
    height: 100%; // allowed
}
```



### Limited ::theme selector

The current description of the *::theme* selector is perhaps a bit too broad for real world usage. However the ability to access any *::part* within the context of a component, without elaborate `exportparts=` chains would be much easier to work with in the context of a design system.

In the example below, a theme context is defined for `**x-foo**` with the prefix of “`foo-`*”*. This would grant access to all child parts that match the name within the declared theme's context. This scoping limits the reach of *::theme* while avoiding the potentially complex *exportparts=* chains. Particularly when there's deep composition of components not owned by a single team.

```
<x-foo theme="foo-">
    <x-bar></x-bar>
    <x-oof></x-oof>
</x-foo>


// x-bar definition
<x-bar>
    <p part="metadata">Posted on: 2019-01-10</p>
</x-bar>

// x-oof definition
<x-oof>
    <svg part="icon"></svg>
</x-oof>
```

```
x-foo::theme(foo-metadata) {
    color: grey;
    font-style: italic;
}
```



### Web Component default *exportparts=*

When building a custom web component via composition not having to explicitly specify `exportparts=` would improve the experience.

The example below presents a possible solution where, at component creation, `exportparts=` is defined.

```
class BarElement extends HTMLElement {
  constructor() {
    super();
    
    const shadowRoot = this.attachShadow({mode: 'closed'});
    
    shadowRoot.innerHTML = `
        <h1 part="header">Headline</h1>
        <p part="metadata">Posted on: 2019-01-10</p>
        <div part="content">...</div>
    `;

    if (!this.hasAttribute('exportparts'))
        this.setAttribute('exportparts', 'header, metadata, content');
  }
}

customElements.define('bar-element', BarElement);
```

```
<x-foo>
    <!-- iteration of bar-elements -->
    <!-- since no manual "exportparts=" was specified on each instance
         the defaults are exported -->
    <bar-element></bar-element>
    <bar-element></bar-element>
    ...
</x-foot>
```

```
x-foo::part(header) {
    color: green;
}
```



## Questions

### Dynamic *exportparts=*

Would it be possible to dynamically set the value of `exportparts=`?
The below example show some pseudo-code to illustrate the question.

```
<x-foo>
    <h1>Component headline</h1>
    
    <template for:each={items} for:item="item" for:index="idx">
        <x-item exportparts="item-header: foo-item-header-{idx}"></x-item>
    </template>
</x-foo>
```



### *::before* and *::after* pseudo elements

It appears the `::before` and `::after` pseudo elements/selectors do not function with *::part*. Is this intentionally blocked, if so why? If not are there plans to add this functionality in the future?

```
// add an asterisk prefix to the title part
x-foo::part(title)::before {
    content: '*';
    color: red;
    margin-right: 0.25rem;
}
```


-- 
GitHub Notification of comment by stefsullrew
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3467#issuecomment-453678965 using your GitHub account

Received on Friday, 11 January 2019 22:35:50 UTC