El elemento <slot>
de HTML define una ranura (slot), generalmente en un DOM encapsulado (Shadow DOM).
El elemento <slot>
es un marcador de posición (placeholder) dentro de un componente web creado usando la especificación de Shadow DOM, en el que puedes insertar tu propio marcado. Esto te permite crear y combinar árboles DOM separados.
Sintaxis
El elemento <slot>
se escribe como <slot name=""</slot>
(la etiqueta de cierre es obligatoria), donde name
es el nombre de la ranura.
Otros elementos pueden hacer referencia al nombre de este elemento <slot>
con el atributo slot
.
Como esto:
<slot name="miSlot">...</slot>
...
<span slot="miSlot">...</span>
Ejemplo
Aquí tienes un ejemplo para demostrarlo.
<!-- 1. Plantilla -->
<template>
<h1><slot name="heading"></slot></h1>
<dl>
<dt><slot name="term-1"></slot></dt>
<dd><slot name="description-1"></slot></dd>
<dt><slot name="term-2"></slot></dt>
<dd><slot name="description-2"></slot></dd>
<dt><slot name="term-3"></slot></dt>
<dd><slot name="description-3"></slot></dd>
</dl>
<style>
h1 {
font-size: 1.2em;
font-family: sans-serif;
color: darkorange;
}
dl {
border-left: 3px solid darkorange;
padding-left: 1em;
}
dt { font-weight: bold; }
dd { color: darkslategray; }
</style>
</template>
<!-- 2. Contenido -->
<div>
<span slot="heading">Términos Web</span>
<span slot="term-1">HTML</span>
<span slot="description-1">Lenguaje de Marcado de Hipertexto</span>
<span slot="term-2">CSS</span>
<span slot="description-2">Hojas de Estilo en Cascada</span>
<span slot="term-3">SQL</span>
<span slot="description-3">Lenguaje de Consulta Estructurada</span>
</div>
<div>
<span slot="heading">Términos Médicos</span>
<span slot="term-1">FA</span>
<span slot="description-1">Fibrilación Auricular</span>
<span slot="term-3">RCP</span>
<span slot="description-3">Reanimación Cardiopulmonar</span>
<span slot="term-2">HAP</span>
<span slot="description-2">Hipertensión Arterial Pulmonar</span>
</div>
<!-- 3. Script -->
<script>
var dlTemplate = document.querySelector('template').content;
var divs = document.querySelectorAll('div');
divs.forEach(function(div){
div.attachShadow({ mode: 'open' }).appendChild(
dlTemplate.cloneNode(true))
});
</script>
No te desanimes por la cantidad de código. Podemos dividirlo en tres partes:
- Plantilla: El elemento
template
se utiliza para declarar fragmentos de HTML que pueden ser clonados e insertados en el documento mediante un script. Su contenido no se renderiza hasta que se añade al documento mediante un script. Esta es la parte que contiene los elementos<slot>
. Actúan como marcadores de posición para el contenido que se va a insertar. - Contenido: Esta parte contiene el contenido que se inserta donde están los elementos
<slot>
en la plantilla. Así que en este caso los elementosspan
terminarán donde están los elementos<slot>
. Cada elementospan
hace referencia a un elemento<slot>
específico a través de su atributoslot
. Por ejemplo,span slot="term-1"
hace referencia aslot name="term-1"
. - Script: Esta es la parte que inserta el contenido en el Shadow DOM según lo definido por el elemento
template
.
Así que en este caso, está tomando el contenido de los elementos span
, y aplicándolo a dos listas de definición y sus respectivos encabezados.
Aquí está con una vista previa:
See the Pen Slot-HTML by Alex (@htmldesdecero) on CodePen.
Estilos
Una de las cosas interesantes de este enfoque, es que cualquier CSS que incluyas en el elemento template
solo se aplica al árbol del Shadow DOM. No afectará al resto de la página.
Vamos a modificar el ejemplo anterior para demostrar a qué me refiero:
<template>
<h1><slot name="heading"></slot></h1>
<dl>
<dt><slot name="term-1"></slot></dt>
<dd><slot name="description-1"></slot></dd>
<dt><slot name="term-2"></slot></dt>
<dd><slot name="description-2"></slot></dd>
<dt><slot name="term-3"></slot></dt>
<dd><slot name="description-3"></slot></dd>
</dl>
<style>
h1 {
font-size: 1.2em;
font-family: sans-serif;
color: darkorange;
}
dl {
border-left: 3px solid darkorange;
padding-left: 1em;
}
dt { font-weight: bold; }
dd { color: darkslategray; }
</style>
</template>
<div>
<span slot="heading">Términos Web</span>
<span slot="term-1">HTML</span>
<span slot="description-1">Lenguaje de Marcado de Hipertexto</span>
<span slot="term-2">CSS</span>
<span slot="description-2">Hojas de Estilo en Cascada</span>
<span slot="term-3">SQL</span>
<span slot="description-3">Lenguaje de Consulta Estructurada</span>
</div>
<h1>Términos Médicos</h1>
<dl>
<dt>FA</dt>
<dd>Fibrilación Auricular</dd>
<dt>RCP</dt>
<dd>Reanimación Cardiopulmonar</dd>
<dt>HAP</dt>
<dd>Hipertensión Arterial Pulmonar</dd>
</dl>
<script>
var dlTemplate = document.querySelector('template').content;
var divs = document.querySelectorAll('div');
divs.forEach(function(div){
div.attachShadow({ mode: 'open' }).appendChild(
dlTemplate.cloneNode(true))
});
</script>
En este ejemplo, la primera lista se inserta con el elemento <slot>
pero la segunda lista no.
See the Pen Slot-CSS-HTML by Alex (@htmldesdecero) on CodePen.
En este ejemplo, he puesto explícitamente los términos médicos en su propia lista de definición. También he movido el encabezado a su propio elemento h1
.
Esto da como resultado que la segunda lista no tenga estilo. Esto se debe a que los únicos estilos que estoy declarando están dentro del elemento template
, lo que significa que solo se aplican a los elementos HTML que están dentro de ese árbol del Shadow DOM.
Por el contrario, si muevo los estilos fuera del elemento template
, esos estilos solo se aplican a la segunda lista, y la primera lista se queda sin estilo:
<style>
h1 {
font-size: 1.2em;
font-family: sans-serif;
color: darkorange;
}
dl {
border-left: 3px solid darkorange;
padding-left: 1em;
}
dt { font-weight: bold; }
dd { color: darkslategray; }
</style>
<template>
<h1><slot name="heading"></slot></h1>
<dl>
<dt><slot name="term-1"></slot></dt>
<dd><slot name="description-1"></slot></dd>
<dt><slot name="term-2"></slot></dt>
<dd><slot name="description-2"></slot></dd>
<dt><slot name="term-3"></slot></dt>
<dd><slot name="description-3"></slot></dd>
</dl>
</template>
<div>
<span slot="heading">Términos Web</span>
<span slot="term-1">HTML</span>
<span slot="description-1">Lenguaje de Marcado de Hipertexto</span>
<span slot="term-2">CSS</span>
<span slot="description-2">Hojas de Estilo en Cascada</span>
<span slot="term-3">SQL</span>
<span slot="description-3">Lenguaje de Consulta Estructurada</span>
</div>
<h1>Términos Médicos</h1>
<dl>
<dt>FA</dt>
<dd>Fibrilación Auricular</dd>
<dt>RCP</dt>
<dd>Reanimación Cardiopulmonar</dd>
<dt>HAP</dt>
<dd>Hipertensión Arterial Pulmonar</dd>
</dl>
<script>
var dlTemplate = document.querySelector('template').content;
var divs = document.querySelectorAll('div');
divs.forEach(function(div){
div.attachShadow({ mode: 'open' }).appendChild(
dlTemplate.cloneNode(true))
});
</script>
See the Pen Slot-CSS-HTML-2 by Alex (@htmldesdecero) on CodePen.
Atributos
Se pueden añadir atributos a un elemento HTML para proporcionar más información sobre cómo debe aparecer o comportarse el elemento.
El elemento <slot>
acepta los siguientes atributos.Atributo Descripción name
Nombre del espacio/ranura del árbol shadow.
Atributos globales
Los siguientes atributos son estándar en todos los elementos HTML. Por lo tanto, puedes utilizar estos atributos con la etiqueta <slot>
, así como con todas las demás etiquetas HTML.
accesskey
autocapitalize
class
contenteditable
data-*
dir
draggable
hidden
id
inputmode
is
itemid
itemprop
itemref
itemscope
itemtype
lang
part
slot
spellcheck
style
tabindex
title
translate
Para obtener una explicación completa de estos atributos, consulta Atributos globales de HTML 5.
Manejadores de eventos
Los atributos de contenido del manejador de eventos te permiten invocar un script desde dentro de tu HTML. El script se invoca cuando ocurre un determinado “evento”. Cada atributo de contenido del manejador de eventos trata un evento diferente.
onabort
onauxclick
onblur
oncancel
oncanplay
oncanplaythrough
onchange
onclick
onclose
oncontextmenu
oncopy
oncuechange
oncut
ondblclick
ondrag
ondragend
ondragenter
ondragexit
ondragleave
ondragover
ondragstart
ondrop
ondurationchange
onemptied
onended
onerror
onfocus
onformdata
oninput
oninvalid
onkeydown
onkeypress
onkeyup
onlanguagechange
onload
onloadeddata
onloadedmetadata
onloadstart
onmousedown
onmouseenter
onmouseleave
onmousemove
onmouseout
onmouseover
onmouseup
onpaste
onpause
onplay
onplaying
onprogress
onratechange
onreset
onresize
onscroll
onsecuritypolicyviolation
onseeked
onseeking
onselect
onslotchange
onstalled
onsubmit
onsuspend
ontimeupdate
ontoggle
onvolumechange
onwaiting
onwheel
La mayoría de los atributos de contenido del manejador de eventos pueden utilizarse en todos los elementos HTML, pero algunos manejadores de eventos tienen reglas específicas sobre cuándo pueden utilizarse y a qué elementos son aplicables.