CSS no funciona correctamente en los Elementos HTML Personalizados.
He estado intentando crear un Elemento HTML personalizado al extender la clase HTMLElement
. Intento añadirle estilo vinculando un archivo CSS que se encuentra en el mismo directorio que mis otros dos archivos: index.html
y custom.css
.
Carpeta principal:
- index.html
- custom.css
- custom.js
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="nofollow" type="text/css" href=''>
</head>
<body>
<script src="./custom.js"></script>
<smooth-button text="Botón suave" no-1="1" no-2="2"></smooth-button>
</body>
</html>
custom.css
:
smooth-button{
display: block;
color: blue;
background-color: orange;
}
custom.js
:
class SmoothButton extends HTMLElement{
constructor(){
super();
this.shadow = this.attachShadow({mode: "open"})
}
connectedCallback(){
this.render();
}
render(){
this.SumOfNo1AndNo2 = null;
if(this.getAttribute("no-1")!=null && this.getAttribute("no-2")!=null){
this.SumOfNo1AndNo2 = parseInt(this.getAttribute("no-1")) +
parseInt(this.getAttribute("no-2"));
}
else{
console.log("Atributo inválido.")
}
this.shadow.innerHTML = `<button>` + this.getAttribute("text") + " " + this.SumOfNo1AndNo2
+ `</button>`
}
}
customElements.define("smooth-button", SmoothButton);
Con esto, obtengo un botón como se esperaba, con el texto, pero el estilo se aplica al elemento en su conjunto y no a los elementos de los que está hecho. ¿Cómo puedo aplicar los estilos por separado a cada uno de sus elementos (solo un button
por ahora) con un archivo CSS externo? Estoy utilizando CSS externo porque es de alguna manera mejor según lo que leí aquí.
davy.ai
Para aplicar estilos por separado a cada elemento del elemento personalizado, puedes utilizar la característica de shadow DOM. En el constructor de tu clase
SmoothButton
, ya has adjuntado un shadow root utilizando el métodoattachShadow()
con la opción{mode: "open"}
.Ahora, lo único que tienes que hacer es crear una etiqueta
style
dentro del shadow root y poner tus reglas CSS personalizadas dentro de ella. Así es como puedes modificar tu claseSmoothButton
para lograr esto:En esta clase
SmoothButton
modificada, hemos creado un elementostyle
utilizandodocument.createElement('style')
y hemos establecido su contenido como tus reglas CSS personalizadas utilizandostyle.textContent
. Luego, hemos añadido este elementostyle
al shadow root utilizandothis.shadow.appendChild(style)
.Por último, hemos creado el elemento
button
y lo hemos añadido al shadow root utilizandothis.shadow.appendChild(button)
. Ahora, los estilos se aplicarán únicamente al elementobutton
y no al elemento personalizado en su totalidad.