Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: How to target ::slotted siblings in Shadow DOM root?

I know that the spec currently only allows compound selectors for ::slotted, i.e. ::slotted(my-first + my-second) is not allowed, but should something like this be working?

::slotted(x-first) + ::slotted(x-second) { /* css */ }

Is there any way to target slotted siblings (other than with global css)? And if not, where would I file such a request? Thanks.

like image 674
spbks Avatar asked Apr 05 '18 17:04

spbks


People also ask

How to use slot in shadow DOM?

Named slots Let's see how slots work on a simple example. In the shadow DOM, <slot name="X"> defines an “insertion point”, a place where elements with slot="X" are rendered. Then the browser performs “composition”: it takes elements from the light DOM and renders them in corresponding slots of the shadow DOM.

How do I select a slot in CSS?

The ::slotted() CSS pseudo-element represents any element that has been placed into a slot inside an HTML template (see Using templates and slots for more information). This only works when used inside CSS placed within a shadow DOM.

What is advanced CSS selector?

Advanced selectors refer to CSS selectors that do something more complex than selecting a tag, class, or ID. This includes selecting a type of tag within another tag, or selecting an element with a certain ID or class, but only when the mouse is hovering over it.

What is a compound selector in CSS?

A compound selector is a sequence of simple selectors that are not separated by a combinator, and represents a set of simultaneous conditions on a single element. Simple selectors are all the little bits – a class, a tag, an ID, etc. Those can be combined in various ways.


2 Answers

Sure you can select siblings of slots / slotted.

The thing you can not do is select a element which has been slotted and is not a top-level node.

Select siblings:

slot[name=<slotname>] ~ <selector>

Select slotted top-level node

::slotted(<compound-selector>)

A compound-selector contains a tag/class/id/name etc. but must not have any combinators. Like <space> for example.

.myClass OK

<anyTag>[<anyAttribute>[=<anyValue>]] OK

.<myClass> > .<anotherClass> NO

Examples

var element = document.querySelector('.templateMe');
var shadow = element.attachShadow({mode: 'open'});
var template = document.querySelector('.myTemplate');
shadow.appendChild(template.content.cloneNode(true));
<template class="myTemplate">
  <style type="text/css">
    ::slotted([slot=slot1]) { /* slot1 every slotted element - YES */
      color: red;
    }
    
    slot[name=slot1] { /* slot1 itself - YES */
      text-decoration: underline;
    }
    
    slot[name=slot1] + .siblingA { /* slot1 siblingA (direct sibling) - YES */
      color: green;
    }
    
    slot[name=slot1]  ~ .siblingB { /* slot1 siblingB (any sibling) - YES */
      color: orange;
    }
    
    slot[name=slot2]::slotted(.selectMeA) { /* slot2 TOP-LEVEL CHILD (slotted) - YES */
      color: purple;
    }
    
    slot[name=slot2]::slotted(.selectMeB) { /* slot2 NOT TOP-LEVEL CHILD - NO */
      font-weight: bold;
    }
    
    slot[name=slot2]::slotted(.selectMeC[name=myName]) { /* slot2 TOP-LEVEL CHILD (slotted) - YES */
      color: khaki;
    }
    
    slot[name=slot2] + .siblingC { /* slot2 sibling - YES */
      color: blue;
    }
    
  </style>
  <div>
    <slot name="slot1"></slot>
    <div class="siblingA">Sibling A of Slot 1</div>
    <div class="siblingB">Sibling B of Slot 1</div>
  </div>
  <hr/>
  <div>
    <slot name="slot2"></slot>
    <div class="siblingC">Sibling C of Slot 2</div>
  </div>
</template>

<div class='templateMe'>
  <span slot="slot1">Im in Solt 1</span>
  <span slot="slot2" class="selectMeA">
    Im in Solt 2, im selectable.
    <div class='selectMeB'>
      NOT selectable (because no top level node of slotted)!
    </div>
  </span>
  <span slot="slot2" class="selectMeC" name="myName">Im in Solt 2 too and selectable!</span>
</div>

More here.

slotted elements (coming from light DOM), ::slotted(selector) allows to select slotted elements themselves, but not their children.

like image 119
SirPilan Avatar answered Sep 21 '22 17:09

SirPilan


DOM that is placed into a slot is supposed to be controlled by the CSS that owns that DOM and not by the Custom Element.

The Web Component it allowed very minor CSS control over the DOM that is placed into your Slot. Pretty much just the top level elements (And things that are auto inherited by child nodes.)

This was a conscious decision and will probably never change.

like image 36
Intervalia Avatar answered Sep 22 '22 17:09

Intervalia