Webbkomponenter – en introduktion
Under resten av kursen bygger du dina gränssnitt som webbkomponenter: egna HTML-element som paketerar struktur, stil och beteende i en återanvändbar enhet. Den här artikeln ger dig en överblick. Detaljerna kommer under de närmaste veckorna, så här räcker det att du förstår idén och känner igen begreppen.
Tidsåtgång: Ungefär 10 minuter.
Problemet webbkomponenter löser
Section titled “Problemet webbkomponenter löser”HTML har en fast uppsättning element: <p>, <button>, <img> och så vidare. Så fort du vill ha
något mer, till exempel en språkväljare med flaggor eller ett kort som visar en användare, måste
du bygga det av befintliga element plus CSS och JavaScript. Utan någon struktur hamnar den koden
lätt utspridd över hela applikationen.
Med webbkomponenter kan du i stället skapa ett eget element, till exempel <user-card>, och använda
det som vilket annat element som helst. All kod som hör till kortet ligger samlad i komponenten.
Fyra standarder under ett paraplynamn
Section titled “Fyra standarder under ett paraplynamn”“Webbkomponenter” är inte en egen standard utan ett samlingsnamn för flera standarder som används tillsammans:
- Custom elements låter dig registrera ett eget element och koppla det till en klass.
- Shadow DOM ger elementet ett eget, inkapslat DOM-träd. CSS i komponenten läcker inte ut, och sidans CSS läcker inte in.
- HTML templates (
<template>) innehåller markup som inte visas direkt men kan klonas, till exempel varje gång en komponent skapas. - ES-moduler är inte en del av webbkomponentstandarderna i strikt mening, men det naturliga sättet att paketera och ladda dem. Dem har du redan läst om i artikeln om webbläsaren som körmiljö.
Ett första eget element
Section titled “Ett första eget element”Ett custom element är en klass som ärver från HTMLElement och registreras med
customElements.define():
customElements.define('hello-message', class extends HTMLElement { connectedCallback() { this.textContent = 'Hej från ett eget element!' } })Efter det kan elementet användas i HTML:
<hello-message></hello-message>connectedCallback() anropas av webbläsaren när elementet läggs in i dokumentet. Det är en av
flera livscykelmetoder du lär dig mer om i kursvecka 10. Där kommer du också att lägga innehållet i
elementets shadow DOM i stället för att skriva direkt i textContent, men principen är densamma.
Klassen behöver inget namn, eftersom den bara används som argument till define(). Det minskar
risken att du kopierar en komponentfil och glömmer att byta namn på klassen.
Fråga: vilka namn är giltiga?
Section titled “Fråga: vilka namn är giltiga?”Vilka av följande strängar kan du skicka som första argument till customElements.define()?
'hello''hello-message''Hello-Message''x-1''font-face'
Bara 'hello-message' och 'x-1' är giltiga.
'hello'saknar bindestreck. Alla inbyggda HTML-element saknar bindestreck, och standarden lovar att det förblir så. Kravet på ett bindestreck garanterar därför att ditt element aldrig krockar med ett framtida inbyggt element.'Hello-Message'innehåller versaler, vilket inte är tillåtet. Namnet ska vara i kebab-case, med bara gemener.'font-face'har bindestreck, men tillhör en kort lista reserverade namn som redan används av äldre SVG- och MathML-standarder.
Ett ogiltigt namn ger ett SyntaxError när define() anropas.
Fråga: vad händer med <hello-message />?
Section titled “Fråga: vad händer med <hello-message />?”Anta att du är van vid JSX eller XML och därför skriver elementet med ett avslutande snedstreck:
<hello-message /><p>Det här stycket kommer efter.</p>Hur tolkar webbläsaren det?
I HTML är snedstrecket bara tillåtet på så kallade void-element, som <img /> och <br />, och
även där ignoreras det. <hello-message /> tolkas därför som en starttagg utan sluttagg, och
<p>-elementet hamnar inuti <hello-message>. När connectedCallback() sedan sätter
textContent skrivs stycket över och försvinner från sidan.
Skriv alltid ut sluttaggen: <hello-message></hello-message>.
Kan du ärva från andra element än HTMLElement?
Section titled “Kan du ärva från andra element än HTMLElement?”Inbyggda element är också klasser. Ett <img>-element är ett HTMLImageElement, som ärver från
HTMLElement. Du kan dock inte skapa ett inbyggt element med new: new HTMLImageElement() ger
felet Illegal constructor. I stället skapar du det med document.createElement('img'), något du
får använda mycket från och med nästa vecka.
Det ligger nära till hands att vilja ärva från HTMLButtonElement för att få en
egen knapp med allt beteende från en vanlig knapp.
Standarden har en mekanism för det, så kallade customized built-in elements, där elementet används
som <button is="fancy-button">. Safari har dock valt att inte implementera den, och det finns inga
tecken på att det kommer att ändras. I praktiken betyder det att du alltid ärver från HTMLElement,
och att din komponent själv innehåller de inbyggda element den behöver, till exempel en <button>
i sin shadow DOM.
Vad har hänt sedan inspelningarna?
Section titled “Vad har hänt sedan inspelningarna?”Inspelningarna från 2021 nämner att webbkomponenter inte hade fullt stöd i alla webbläsare några år tidigare. I dag fungerar custom elements, shadow DOM och templates i alla moderna webbläsare, och standarderna har fortsatt att utvecklas. Några exempel, som du inte behöver i kursen men kan stöta på när du söker information:
- Deklarativ shadow DOM (
<template shadowrootmode="open">) gör det möjligt att skriva en komponents shadow DOM direkt i HTML, till exempel när sidan genereras på en server. Baseline sedan 2024. - Formulärkopplade element (
ElementInternals) låter ett eget element delta i ett<form>på samma sätt som ett<input>, med värde och validering. - Delade stilmallar (
adoptedStyleSheets) låter många komponenter dela samma CSS-objekt i stället för att varje komponent får en egen kopia.
Även ramverken har närmat sig standarden. React stöder sedan version 19 custom elements fullt ut, så webbkomponenter kan användas i React-applikationer, och flera ramverk, bland annat Svelte, Vue och Angular, kan kompilera sina komponenter till custom elements.
Varför webbkomponenter i den här kursen?
Section titled “Varför webbkomponenter i den här kursen?”- Det är webbstandarder. Det du lär dig fungerar i alla webbläsare utan bibliotek eller byggsteg och blir inte inaktuellt när nästa ramverk kommer.
- Det bygger på det du redan kan. En komponent är en klass, med konstruktor, metoder och arv, precis som i kursveckorna 6 och 7.
- Det ger struktur. JavaScript tvingar inte fram något särskilt sätt att organisera kod. Komponenter ger dig ett tydligt mönster att följa, och samma tänkande känner du igen när du senare lär dig ett ramverk.
Vägen framåt
Section titled “Vägen framåt”| Kursvecka | Innehåll |
|---|---|
| 9 | DOM och HTML templates, grunden komponenterna bygger på |
| 10 | Custom elements och shadow DOM på riktigt |
| 11 | Händelser, och hur komponenter kommunicerar med omvärlden |
| 13 | Komposition: komponenter som består av andra komponenter |
Vill du redan nu prova kan du använda studiefrågorna i veckans översikt tillsammans med en AI-assistent. Låt den förklara varje rad kod den föreslår.
Vidare läsning
Section titled “Vidare läsning”- Web Components på MDN.
- Using custom elements på MDN.