Skip to content

child elements usage in shadow dom

Is there any constraint that’s preventing <thead>, <tbody>, <tr> and so on to be slotted in shadow DOM?

Given the following example:

<script>
class Table extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({mode: 'open'}).innerHTML = `
            <table>
                <thead>
                    <slot name="header"></slot>
                </thead>
                <tbody>
                    <slot name="row"></slot>
                </tbody>
            </table>
        `;
    }
}
window.customElements.define('data-table', Table);
</script>
<data-table>
    <tr slot="header">
        <th>header1</th>
    </tr>
    <tr slot="row">
        <td>cell1</tr>
    </tr>
</data-table>

renders into the following structure:
enter image description here

The workaround would be to use templates and insert template content with JS in slotchange event handler, but I would like to avoid that since the cloned content would end up in shadow DOM and it will not be possible to override styles from outside of the custom element.

Answer

As stated in the comment this is currently not possible according to Custom Elements spec v1.
The spec limits tags of <table> to a set of <tbody>, <thead> and so on plus <script> and <template>.
Browser vendors are reluctant to incorporating changes in their HTML parser https://github.com/WICG/webcomponents/issues/59.
Guess the only solution for now is to use a mesh of divs with a bunch of aria-* attributes.