问题
In webcomponents, we have two type of slots (named slots and default slots). We can easily style named slots by using syntax slot[name]::slotted(*)
. But is there any way that we can style default slots because they don't have any name associated?
The code is something like this and i'm using Angular Elements.
<div class="topbar-item">
<slot class="icon" name="icon"></slot>
<span class="text">
<slot></slot> <-- This is the slot i want to add styles, only if the slot has some data assigned. (need to add margin-left)
</span>
</div>
回答1:
Found a little workaround until someone finds a better way. We can use slotchange event to make sure whether any items attached to the slot or not. In this way.
HTML
<slot (slotchange)="onSlotChanged($event)"></slot>
JS/TS
onSlotChanged($event) {
const slotHasData = $event.target.assignedNodes().length > 0;
// Is event.target.assignedNodes().length return more than 0, it has nu of items attached to the slot
}
回答2:
It is a misconception slotted content is MOVED to slots in shadowDOM
It is NOT!;
It remains invisible in lightDOM and is REFLECTED to its SLOT in shadowDOM
That means you can apply styles after content has been slotted (mouseover in the code below)
Or.. to style UNnamed slots, you style the UNnamed content in lightDOM:
customElements.define("my-element", class extends HTMLElement {
connectedCallback() {
let template = document.getElementById(this.nodeName);
this.attachShadow({
mode: 'open'
}).appendChild(template.content.cloneNode(true));
}
})
my-element div {
background: lightcoral;
padding: 1em;
margin-top:.5em;
}
my-element div:hover {
background: lightgreen;
}
h1{
background:lightblue;
color:black;
margin:0;
}
h1:hover {
color: red;
}
<template id=MY-ELEMENT>
<style>
:host {
display: block;
padding:.5em;
background:green;
}
::slotted(*){
color:white;
}
div{
border:1px dashed black;
}
</style>
<div>
<slot name=title></slot>
<slot></slot>
</div>
</template>
<my-element>
<div>Custom Elements Rule!</div>
<h1 slot=title>Hello World!</h1>
<div>What a wonderfull day!</div>
</my-element>
Note! how all unnamed content goes into the (one) unnamed SLOT
回答3:
You can just use the :not()
pseudo-class:
<style>
...
slot:not([name])::slotted(*) {
...
}
...
</style>
来源:https://stackoverflow.com/questions/61237010/styling-default-slot-in-webcomponents