Werk de componentstatus bij wanneer een keuze ervoor moet zorgen dat bedieningselementen, tekst en gedrag consistent blijven. Overschrijf CSS wanneer je alleen de presentatie wilt aanpassen. Deze handleiding gebruikt een lokale tegelpreview in Safari op de Mac om te laten zien hoe je beide aanpakken kiest en controleert.
De taak voor de lezer is concreet: pas een kleine webpagina aan die je zelf hebt gemaakt, zodat de vormknoppen synchroon blijven en de decoratieve stijl makkelijk te bewerken is. Componentstatus is hier een JavaScript-object dat door de eigen updatefunctie van de pagina wordt beheerd. Er wordt geen framework of productspecifieke bewerkingsfunctie verondersteld.
Welke wijzigingen horen in de componentstatus?
Begin met de vraag wat na de wijziging met elkaar moet overeenkomen. Als het selecteren van een ronde tegel een selectievakje, de preview en een beschrijving moet bijwerken, geef die keuze dan één eigenaar in de status. Leid vervolgens alle drie de resultaten daarvan af. Dit is een implementatieaanbeveling: zo wordt de relatie tussen een keuze en de weergegeven resultaten expliciet.
Een CSS-aangepaste eigenschap zoals --tile-size heeft een andere functie. Deze levert een waarde aan declaraties die ernaar verwijzen met var(). Aangepaste eigenschappen doen mee in de cascade en worden normaal gesproken overgeërfd; hun gedrag volgt de CSS-regels, ook wanneer JavaScript ze instelt. De CSS Custom Properties-specificatie definieert dit contract.
Gebruik deze besliswijzer voordat je iets bewerkt:
| Gevraagde wijziging | Voorkeurseigenaar | Reden in dit voorbeeld |
|---|---|---|
| De lezer selecteert een ronde of vierkante tegel | Componentstatus | Het selectievakje, de beschrijving en de vorm moeten overeenkomen |
| De lezer kiest een tegelgrootte | Componentstatus, weergegeven in CSS | De schuifregelaar, beschrijving en afmetingen delen één waarde |
| Elke tegel moet een andere decoratieve kleur hebben | Stylesheetdeclaratie | Er hoeft geen geselecteerde waarde of tekst te worden bijgewerkt |
| De preview heeft meer ruimte eromheen nodig | Stylesheetdeclaratie | Dit verandert de indeling rond de tegel |
| Er is tijdelijk een andere afmeting nodig voor inspectie | Lokale CSS-overschrijving | Het is een visueel experiment dat je daarna weer verwijdert |
Het onderscheid hangt af van de taak. In deze preview hoort kleur bij CSS, omdat het vaste decoratie is. Als je later een kleurkiezer en een beschrijving van de geselecteerde kleur toevoegt, behandel die selectie dan als status en geef het visuele effect ervan weer. Maak niet twee waarden voor dezelfde keuze die onafhankelijk van elkaar kunnen worden bewerkt.
Systeemknoppen hebben ook hun eigen status. Lees voor een selectievakje de huidige eigenschap checked. Het HTML-attribuut checked bepaalt of het vakje standaard is aangevinkt en houdt geen latere gebruikerswijzigingen bij. Dit onderscheid wordt beschreven in MDN's referentie voor de checkbox-eigenschap.
Bouw één zelfstandige preview op je Mac
Gebruik een editor voor platte tekst om het volgende volledige document op te slaan als tile-preview.html en open het daarna in Safari. Behoud de .html-extensie. Het voorbeeld bevat de CSS en JavaScript, gebruikt systeemlettertypen en tekent een eenvoudige geometrische tegel zonder externe bestanden.
De stylesheet staat in de head van het document. HTML definieert het element style als een manier om CSS in te sluiten en maakt onderscheid tussen interne stijlen die op zichzelf staan en stylesheets die naar aanvullende bronnen verwijzen. Door dit voorbeeld zelfstandig te houden, blijven de invoerwaarden voor de stijl duidelijk. Zie de secties over stijl en scripting in de HTML Standard.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tile preview</title>
<style>
body {
font-family: system-ui, sans-serif;
margin: 2rem;
color: #222;
background: #fff;
}
label { display: block; margin-block: 1rem; }
.preview { padding: 24px; background: #eee; }
.tile {
width: 80px;
height: 80px;
border-radius: 0;
width: var(--tile-size, 80px);
height: var(--tile-size, 80px);
border-radius: var(--tile-radius, 0);
background-color: #547899;
}
</style>
</head>
<body>
<h1>Tile preview</h1>
<label>
<input id="round" type="checkbox"> Round tile
</label>
<label>
Tile size
<input id="size" type="range" min="40" max="160"
step="1" value="80">
</label>
<button id="reset" type="button">Reset choices</button>
<p id="summary"></p>
<div class="preview">
<div id="tile" class="tile" aria-hidden="true"></div>
</div>
<script>
const state = { rounded: false, size: 80 };
const round = document.getElementById('round');
const size = document.getElementById('size');
const summary = document.getElementById('summary');
const tile = document.getElementById('tile');
const reset = document.getElementById('reset');
function render() {
round.checked = state.rounded;
size.value = String(state.size);
tile.style.setProperty('--tile-size', `${state.size}px`);
tile.style.setProperty('--tile-radius', state.rounded ? '50%' : '0');
summary.textContent = `Tile A: ${state.rounded ? 'round' : 'square'}, ${state.size}px.`;
}
function update(patch) {
const next = { ...state, ...patch };
if (typeof next.rounded !== 'boolean' ||
!Number.isInteger(next.size) ||
next.size < 40 || next.size > 160) {
throw new RangeError('Use a boolean and a size from 40 to 160.');
}
Object.assign(state, next);
render();
}
round.addEventListener('change', () => {
update({ rounded: round.checked });
});
size.addEventListener('input', () => {
update({ size: Number(size.value) });
});
reset.addEventListener('click', () => {
update({ rounded: false, size: 80 });
});
render();
</script>
</body>
</html>
De hier gebruikte stijlfunctie is gedocumenteerd: element.style.setProperty() schrijft een inline-declaratie, waaronder een aangepaste eigenschap. Eigenschapsnamen gebruiken de CSS-spelling, zoals --tile-size. Zie MDN's referentie voor setProperty.
Probeer Ronde tegel te selecteren, Tegelformaat naar een andere waarde te schuiven en Keuzes resetten te kiezen. De eerste twee acties moeten zowel de vorm als de beschrijving bijwerken; resetten moet een vierkant van 80 pixels herstellen. In dit programma roept het toewijzen van alleen een veld in state niet render() aan. Voer wijzigingen uit via update(), zodat validatie en weergave samen plaatsvinden.
De update- en weergavelogica is in Node gecontroleerd met nagebootste bedieningselementen en een nagebootst stijlobject voor beginwaarden, gewijzigde waarden, ongeldige formaten en resetten. Die controles zijn geslaagd; ze tonen niet aan hoe de pagina in een browser wordt weergegeven. Gebruik de zichtbare controles hierboven om het bestand in Safari te controleren.
Wanneer moet je een CSS-declaratie overschrijven?
Voor een blijvende decoratieve wijziging bewerk je de opgeslagen stylesheet. Verander bijvoorbeeld de background-color van .tile in een andere CSS-kleur of pas de padding van .preview aan. Voor geen van beide wijzigingen is in dit programma een nieuw statusveld nodig, omdat geen ervan een geselecteerde keuze vertegenwoordigt.
Voor een tijdelijk experiment schakel je de inspector van Safari in via Safari → Instellingen… → Geavanceerd → Toon functies voor webontwikkelaars. Open Ontwikkel → Toon Web Inspector of druk op Option-Command-I. Dit zijn de gedocumenteerde Mac-stappen in de inspectorhandleiding van WebKit.
Open het voorbeeld en voer het volgende volledige codefragment uit in de console. Het verandert tijdelijk de kleur van de tegel en biedt daarna een functie om die overschrijving te verwijderen:
const previewTile = document.getElementById('tile');
if (!previewTile) throw new Error('Open tile-preview.html first.');
previewTile.style.setProperty('background-color', '#8069a6');
function restoreTileColor() {
previewTile.style.removeProperty('background-color');
}
// Run restoreTileColor() when finished comparing colors.
Door deze inline-declaratie te verwijderen, bepaalt de overgebleven cascade de kleur opnieuw. De kleurdeclaratie in de stylesheet wordt hierdoor niet verwijderd. De verwijdermethode wordt beschreven in MDN's referentie voor removeProperty. Wil je in dit voorbeeld een gekozen kleur behouden na het herladen, bewerk en bewaar dan de CSS-broncode.
Houd tijdelijke overschrijvingen uit de buurt van waarden die door de renderer worden beheerd. Als je --tile-size handmatig wijzigt, blijft de beschrijving de statuswaarde tonen en vervangt de volgende aanroep van render() je experiment. Wijzig de grootte via de knop of updatefunctie als de hele component dezelfde waarde moet weergeven.
Waarom lijkt een overschrijving soms niets te doen?
Breng eerst het pad van de waarde in kaart voordat je de selectorspecificiteit verhoogt. Een declaratie kan geldig zijn en toch verliezen in de cascade, of verwijzen naar een aangepaste eigenschap die de winnende declaratie niet meer gebruikt.
- Controleer het doel. Bevestig dat je het element hebt geselecteerd dat de vorm weergeeft.
- Controleer de invoer. In het voorbeeld moet de grootte een geheel getal tussen 40 en 160 zijn. Ongeldige updates geven een fout voordat de status wordt gewijzigd.
- Controleer wat de waarde gebruikt. De afmetingen van de tegel gebruiken
var(--tile-size). Een winnende directe declaratie voorwidthkan die waarde omzeilen voor de breedte, terwijl de hoogte er nog steeds van afhankelijk is. - Controleer de prioriteit. Vergelijk toepasselijke declaraties, importantie, lagen en specificiteit.
- Controleer de volgende interactie. Als de wijziging verdwijnt nadat je een knop hebt verschoven, bekijk dan wat
render()schrijft.
Normale inline-declaraties hebben voorrang op normale regels in stylesheets van de auteur. Importantiedeklaraties, animaties en transities beïnvloeden echter de bredere volgorde. Een latere declaratie wint niet automatisch en een specifiekere selector kan niet elk conflict oplossen. MDN's handleiding voor de cascade beschrijft deze voorwaarden.
Maak ook onderscheid tussen inline-waarden en berekende waarden. element.style geeft inline-stijlen weer; een lege inline-waarde betekent dus niet dat het element geen stijl heeft. getComputedStyle() leest de berekende waarden nadat de actieve stylesheets zijn toegepast. Zie MDN's referentie voor style en de referentie voor getComputedStyle.
Voer dit volledige diagnosefragment uit in de console van de voorbeeldpagina:
const inspectedTile = document.getElementById('tile');
if (!inspectedTile) throw new Error('Open tile-preview.html first.');
console.table({
inlineSizeToken: inspectedTile.style.getPropertyValue('--tile-size'),
inlineWidth: inspectedTile.style.getPropertyValue('width'),
resolvedWidth: getComputedStyle(inspectedTile).width,
resolvedHeight: getComputedStyle(inspectedTile).height
});
Direct nadat je het ongewijzigde voorbeeld hebt geopend, zijn de verwachte waarden een inline-grootte-token van 80px, een lege inline-breedte en berekende afmetingen van 80px. Dit laat zien hoe een inline aangepaste eigenschap een stylesheetdeclaratie kan aanleveren zonder een inline-declaratie voor width te maken.
Welke beperkingen van browsers en bronnen zijn van belang?
Volgens MDN zijn CSS-aangepaste eigenschappen sinds april 2017 breed beschikbaar in browsers. Dat betekent niet dat elke oudere browser ze ondersteunt. Het voorbeeld bevat gewone afmetingsdeclaraties vóór de declaraties voor var(), zodat de tegel statisch wordt weergegeven als aangepaste eigenschappen niet beschikbaar zijn. Zie MDN's referentie voor aangepaste eigenschappen.
De terugvalwaarde binnen var(--tile-size, 80px) biedt geen compatibiliteit met een browser die aangepaste eigenschappen niet kan interpreteren. Ook worden niet alle aangeleverde tokens ermee gevalideerd: een gedefinieerde waarde zoals blue wordt niet vanzelf een geldige breedte doordat er een terugvalwaarde bestaat. Deze beperkingen worden toegelicht in MDN's handleiding voor aangepaste eigenschappen.
Als een oudere doelbrowser geen aangepaste eigenschappen ondersteunt, kun je als alternatief de renderer aanpassen zodat deze met setProperty() gewone inline-declaraties voor width, height en border-radius schrijft. Behoud dezelfde statusvalidatie en synchronisatie van bedieningselementen. Dit verandert de afspraken voor het weergeven, dus verwijder conflicterende schrijfacties van de renderer en controleer de doelbrowser in plaats van uit te gaan van identieke ondersteuning.
Voor deze lokale preview is de praktische keuze duidelijk: gebruik de status voor vorm- en groottekeuzes, geef die keuzes weer via een kleine set CSS-invoerwaarden en houd decoratie in de stylesheet. Test na elke wijziging een interactie met een knop en voer daarna een reset uit. De preview, bedieningselementen en beschrijving moeten dezelfde geselecteerde waarden blijven weergeven.
Bronnen
- CSS Custom Properties for Cascading Variables Module Level 1 — W3C CSS Working Group
- HTML Standard: The style element — WHATWG
- HTMLInputElement: checked property — MDN Web Docs
- CSSStyleDeclaration: setProperty() method — MDN Web Docs
- Enabling Web Inspector — WebKit
- CSSStyleDeclaration: removeProperty() method — MDN Web Docs
- Introduction to the CSS cascade — MDN Web Docs
- HTMLElement: style property — MDN Web Docs
- Window: getComputedStyle() method — MDN Web Docs
- Custom properties (--*): CSS variables — MDN Web Docs
- Using CSS custom properties (variables) — MDN Web Docs