Maison >interface Web >tutoriel CSS >Les composants Web HTML facilitent l'amélioration progressive et l'encapsulation CSS!
L'article perspicace de Jeremy Keith l'année dernière m'a présenté les composants Web HTML, une révélation qui a changé mon approche du développement Web. Son point clé résonnait profondément: bien que vous puisse obtenir les mêmes résultats avec la manipulation DOM et la manipulation des événements, les composants Web offrent une solution plus robuste, portable et maintenable, adhérant au principe de responsabilité unique.
Mon idée fausse initiale était que tous les composants Web reposaient uniquement sur JavaScript et Shadow Dom. Bien que cela soit possible, une approche supérieure, en particulier pour les défenseurs progressifs d'amélioration, tire parti des capacités HTML inhérentes aux composants Web. Ils sont fondamentalement HTML. Les travaux récents d'Andy Bell fournissent un contexte supplémentaire sur l'amélioration progressive (bien qu'en dehors de la portée de cet article).
Explorons trois exemples présentant des caractéristiques clés: l'encapsulation CSS et les possibilités d'amélioration progressive, sans dépendance JavaScript obligatoire pour la fonctionnalité de base. JavaScript sera utilisé pour améliorer l'expérience, mais la fonctionnalité de base reste intacte même sans elle. Ces exemples, ainsi que leur code source, sont disponibles dans ma bibliothèque de composants de chauffeur Web (livre de contes) sur GitHub.
<webui-disclosure></webui-disclosure>
Inspiré par le tutoriel de Chris Ferdinandi sur la construction de composants Web à partir de zéro à l'aide d'un modèle de divulgation, cet exemple développe sa démo.
Le noyau est HTML. Les composants Web permettent des noms d'éléments personnalisés; Ici, <webui-disclosure></webui-disclosure>
contient un bouton pour afficher / masquer le texte dans un <div>. </div>
<webui-disclosure data-bind-click-outside="" data-bind-escape-key=""> Show / Hide <div data-content=""> <p>Content to be shown/hidden.</p> </div> </webui-disclosure>
avec JavaScript Disabled, le bouton (caché via l'attribut hidden
) est invisible et le contenu s'affiche. Cela démontre une amélioration progressive simple. Le contenu est accessible indépendamment du javascript.
Cela étend la démo de Ferdinandi en ajoutant la fermeture via la touche ESC ou clique à l'extérieur de l'élément (en utilisant data-attribute
s). L'élément personnalisé est défini:
customElements.define('webui-disclosure', WebUIDisclosure);
Les noms d'éléments personnalisés utilisent un idéal pointillé (par exemple, <my-component></my-component>
). Bien que le tableau de bord sépare généralement les mots, il n'est pas strictement requis.
L'utilisation de TypeScript est bénéfique pour la prévention des erreurs, mais pour la simplicité, la structure du module JavaScript est:
class WebUIDisclosure extends HTMLElement { constructor() { super(); this.trigger = this.querySelector('[data-trigger]'); this.content = this.querySelector('[data-content]'); this.bindEscapeKey = this.hasAttribute('data-bind-escape-key'); this.bindClickOutside = this.hasAttribute('data-bind-click-outside'); if (!this.trigger || !this.content) return; this.setupA11y(); this.trigger?.addEventListener('click', this); } setupA11y() { // Add ARIA props/state to button. } handleEvent(e) { // 1. Toggle visibility of content. // 2. Toggle ARIA expanded state on button. } connectedCallback() { document.addEventListener('keyup', (e) => { // Handle ESC key. }); document.addEventListener('click', (e) => { // Handle clicking outside. }); } disconnectedCallback() { // Remove event listeners. } }
Les écouteurs d'événements sont gérés dans constructor()
et connectedCallback()
(comme expliqué par Hawk Ticehurst). Bien qu'il ne soit pas essentiel pour les fonctionnalités de base, le JavaScript améliore l'UX et l'accessibilité (ajoutant aria-expanded
et aria-controls
). Cela présente une amélioration progressive. Aucun CSS supplémentaire n'est nécessaire; Le style est hérité.
<webui-tabs></webui-tabs>
Cet exemple met en évidence l'encapsulation CSS et l'amélioration progressive dans un composant à onglet.
La structure HTML:
<webui-tabs> <div data-tablist=""> <a data-tab="" href="https://www.php.cn/link/7426f79c9a7f5af0a6cc457b2a7fb195">Tab 1</a> <a data-tab="" href="https://www.php.cn/link/60430f4a984aa0a534e027339a7580a7">Tab 2</a> <a data-tab="" href="https://www.php.cn/link/9d4f684ba088d28ad1c2ae7d0aee496a">Tab 3</a> </div> <div data-tabpanel=""> <p>1 - Lorem ipsum dolor sit amet consectetur.</p> </div> <div data-tabpanel=""> <p>2 - Lorem ipsum dolor sit amet consectetur.</p> </div> <div data-tabpanel=""> <p>3 - Lorem ipsum dolor sit amet consectetur.</p> </div> </webui-tabs>
CSS est encapsulé:
webui-tabs { [data-tablist] { /* Default styles without JavaScript */ } [data-tab] { /* Default styles without JavaScript */ } [role='tablist'] { /* Style role added by JavaScript */ } [role='tab'] { /* Style role added by JavaScript */ } [role='tabpanel'] { /* Style role added by JavaScript */ } }
Les styles par défaut ([data-tablist]
, [data-tab]
) sont appliqués indépendamment de JavaScript. Les styles avec role
les attributs ne sont ajoutés que lorsque JavaScript est activé, fournissant une amélioration progressive. Les styles sont portée à <webui-tabs></webui-tabs>
, empêchant les conflits. Les sélecteurs de descendants simples peuvent remplacer des méthodologies complexes comme le bem.
Les feuilles de styles peuvent être importées via JavaScript (consommé uniquement si JavaScript est disponible):
import styles from './styles.css'; class WebUITabs extends HTMLElement { constructor() { super(); this.adoptedStyleSheets = [styles]; } } customElements.define('webui-tabs', WebUITabs);
Alternativement, les styles en ligne peuvent être injectés à l'aide de Shadow Dom:
class WebUITabs extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ` <!-- styles go here --> `; } } customElements.define('webui-tabs', WebUITabs);
Le DOM "Light" (contenu entre les balises de composants) hérite des styles globaux. Le Dom Shadow nécessite des styles internes. L'article de Dave Rupert clarifie comment les styles externes interagissent avec l'ombre Dom.
L'amélioration progressive est réalisée avec JavaScript:
class WebUITabs extends HTMLElement { constructor() { super(); // ... (querySelector, etc.) ... this.createTabs(); this.tabTriggers.forEach((tabTrigger, index) => { tabTrigger.addEventListener('click', (e) => { this.bindClickEvent(e); }); tabTrigger.addEventListener('keydown', (e) => { this.bindKeyboardEvent(e, index); }); }); } createTabs() { // 1. Hide all tabpanels initially. // 2. Add ARIA props/state to tabs & tabpanels. } bindClickEvent(e) { e.preventDefault(); // Show clicked tab and update ARIA props/state. } bindKeyboardEvent(e, index) { e.preventDefault(); // Handle keyboard ARROW/HOME/END keys. } } customElements.define('webui-tabs', WebUITabs);
JavaScript ajoute des rôles Aria et une navigation au clavier, améliorant l'accessibilité. Sans JavaScript, le comportement par défaut (liens vers des panneaux) reste accessible.
<webui-ajax-loader></webui-ajax-loader>
Cet exemple, entièrement généré par JavaScript à l'aide de Shadow Dom, n'est rendu que lorsque JavaScript est activé. Il est utilisé pour indiquer des états de chargement pour les demandes AJAX.
Le HTML est simplement:
<webui-ajax-loader></webui-ajax-loader>
le javascript:
class WebUIAjaxLoader extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <svg part="svg" role="img"><title>loading</title> <circle cx="50" cy="50" r="47"></circle></svg> `; } } customElements.define('webui-ajax-loader', WebUIAjaxLoader);
L'attribut part
permet de styliser le SVG de l'extérieur du composant en utilisant le ::part
Pseudo-Selector:
webui-ajax-loader::part(svg) { // Shadow DOM styles for the SVG... }
Les propriétés personnalisées CSS peuvent être utilisées:
<webui-disclosure data-bind-click-outside="" data-bind-escape-key=""> Show / Hide <div data-content=""> <p>Content to be shown/hidden.</p> </div> </webui-disclosure>
L'amélioration progressive est inhérente; Le chargeur n'apparaît que lorsque JavaScript est pris en charge.
Les composants Web HTML hiérarchisent HTML, en utilisant JavaScript uniquement en cas de besoin pour les fonctionnalités améliorées et l'encapsulation. Ils fournissent une approche puissante pour construire des applications Web robustes, maintenables et accessibles.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!