16

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.

Intervalia
  • 10,248
  • 2
  • 30
  • 60
spbks
  • 845
  • 3
  • 10
  • 18

2 Answers2

19

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.

SirPilan
  • 4,649
  • 2
  • 13
  • 26
  • 2
    Thanks for your detailed answer. In your example, what I was looking for would have been: `slot[name=slot2]::slotted(.selectMeA + .selectMeC)`, which, if I understand you correctly, is not possible, although both are top level children. – spbks Jun 30 '18 at 08:15
  • thats correct since you are using `+` which is a combinator – SirPilan Jun 30 '18 at 09:55
  • 4
    I've tried `::slotted(.selectMeA) + ::slotted(.selectMeC)` but this is not wirking aswell. `::slotted` seems to be the end of the line. – SirPilan Jun 30 '18 at 10:06
  • 2
    Anyone know if this is how this was done for a reason, or if combinators might work in the future but don't yet? I want them – wesruv Feb 28 '20 at 18:27
5

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.

Intervalia
  • 10,248
  • 2
  • 30
  • 60
  • Thanks, I have also read that the decision to disallow complex selectors with ::slotted had to do with performance when targeting *descendents*. Therefore I had hoped that there was a way to target slotted *siblings*, since those *are* top level elements. – spbks Apr 08 '18 at 21:38