4 votes

Comment sélectionner des éléments personnalisés sous-classés avec CSS

Considérez ce qui suit :

class MyElem extends HTMLElement {};
customElements.define('my-element', MyElem);

class MyMoreSpecificElem extends MyElem {};
customElements.define('my-more-specific-element', MyMoreSpecificElem);

Dans le langage de l'héritage des objets, les instances de la seconde classe ont une relation 'est-un' avec la première : un MyMoreSpecificElem est un MyElem.

Cette relation est capturée en JavaScript :

let subclassInstance = document.querySelector('my-more-specific-element');
let parentClass = document.querySelector('my-element').constructor;

subclassInstance instanceof parentClass; // true

Mais je ne vois pas de moyen de sélectionner tous les MyElem (y compris la sous-classe MyMoreSpecificElem) en utilisant des sélecteurs CSS. Un sélecteur d'étiquette ne ciblerait que la superclasse ou la sous-classe, et tous les sélecteurs de description de relation que je connais (par exemple, ~, >) concernent la position dans le document, pas la hiérarchie de classe.

Je veux dire, bien sûr, je peux ajouter une classe CSS dans le constructeur et sélectionner par cela, l'appel à super garantirait même que les instances de la sous-classe pourraient être sélectionnées de cette manière. Mais c'est compliqué. Existe-t-il un moyen de le faire en CSS pur?

1voto

user1253074 Points 11

Pourquoi ne pas ajouter soit une valeur className ou un attribut qui sera défini à la fois pour la classe de composant de base et pour toutes les sous-classes de composants. Ensuite, votre CSS peut être défini en fonction de cette valeur de className ou attribut.

class MyBaseEl extends HTMLElement {
  connectedCallback() {
    this.classList.add('my-base-el');
    this.innerHTML = 'Base El';
  }
}

customElements.define('my-base-el', MyBaseEl);

class MySubEl extends MyBaseEl {
  connectedCallback() {
    super.connectedCallback();
    this.innerHTML = 'Sub El';
  }
}

customElements.define('my-sub-el', MySubEl);

.my-base-el {
  background-color: #FF0;
  display: block;
  outline: 1px dashed black;
}

Cela utilise une valeur className pour permettre au CSS d'accéder à tous les éléments qui sont MyBaseEl ou une sous-classe.

Ou comme ceci :

class MyBaseEl extends HTMLElement {
  connectedCallback() {
    this.setAttribute('my-base-el', '');
    this.innerHTML = 'Base El';
  }
}

customElements.define('my-base-el', MyBaseEl);

class MySubEl extends MyBaseEl {
  connectedCallback() {
    super.connectedCallback();
    this.innerHTML = 'Sub El';
  }
}

customElements.define('my-sub-el', MySubEl);

[my-base-el] {
  background-color: #FF0;
  display: block;
  outline: 1px dashed black;
}

Cela utilise un attribut pour permettre au CSS d'accéder à tous les éléments qui sont MyBaseEl ou une sous-classe.

MISE À JOUR

La seule autre façon de définir CSS pour plusieurs balises d'éléments est de connaître lesquels sont-ils et faire fonctionner le CSS pour tous comme ceci :

my-base-el, my-sub-el, my-other-sub-el, the-third-sub-el {
  background: #000;
  color: #fff;
}

Mais, si quelqu'un d'autre peut créer des sous-classes supplémentaires alors vous devrez ajouter à la liste.

MISE À JOUR 2

Pourquoi ne pas simplement définir le :host dans la classe de base et lui faire utiliser une variable CSS pour les styles que vous souhaitez que l'utilisateur puisse modifier. Ensuite, tout héritera de ce CSS :host et s'affichera comme vous le souhaitez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X