Styling richtlijnen voor componenten ​
Styling in die-core componenten ​
Bij het ontwikkelen van componenten in onze die-core Lit bibliotheek hanteren we specifieke richtlijnen om consistentie, onderhoudbaarheid en herbruikbaarheid te garanderen.
Componenten en styling structuur ​
In die-core volgen we een gestandaardiseerde naamgeving en structuur:
- HTML tag namen beginnen met
dcr-prefix (bv.dcr-notification) - Component klassen gebruiken PascalCase met
Dcrprefix (bv.DcrNotification) - Styling staat in aparte
.scssbestanden (bv.dcr-notification.styles.scss) - Deze
.scssbestanden worden automatisch gecompileerd naar.tsfiles en geïmporteerd als.js
// dcr-notification.ts
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import styles from './dcr-notification.styles.js';
@customElement('dcr-notification')
export class DcrNotification extends LitElement {
static styles = styles;
render() {
return html`
<div class="notification">
<div class="header">
<span class="title">${this.title}</span>
<div class="icon">${this.renderIcon()}</div>
</div>
<div class="content">${this.message}</div>
</div>
`;
}
}Design tokens gebruiken in SCSS ​
In die-core gebruiken we design tokens uit de CDS (Component Design System) bibliotheek:
// dcr-notification.styles.scss
@use '@diekeure/cds-tokens' as cds;
.notification {
border-radius: 4px;
background-color: rgb(cds.get('cds.sys.color.surface-container'));
}
.header {
display: flex;
justify-content: space-between;
padding: 12px;
color: rgb(cds.get('cds.sys.color.on-surface'));
}
.title {
font-weight: 600;
}
.icon {
height: 20px;
width: 20px;
color: rgb(cds.get('cds.sys.color.primary'));
}Deze tokens worden in de compilatiefase omgezet naar CSS variabelen:
/* Gecompileerde uitvoer */
.notification {
border-radius: 4px;
background-color: var(--cds-sys-color-surface-container, 255, 218, 212);
}Semantische classnamen ​
In die-core gebruiken we semantische classnamen die het doel of de functie van een element beschrijven, niet hoe het eruitziet:
// Goede semantische naamgeving in .styles.scss
.notification {
/* ... */
}
.header {
/* ... */
}
.content {
/* ... */
}
.icon {
/* ... */
}Beknopte en duidelijke naamgeving ​
Dankzij Shadow DOM in Lit componenten kunnen we beknopte namen gebruiken zonder risico op conflicten:
// Eenvoudige, duidelijke naamgeving in .styles.scss file
.header {
/* ... */
}
.title {
/* ... */
}
.icon {
/* ... */
}Waarom geen utility classes in die-core? ​
We vermijden utility classes zoals .flex, .m-bs-xs, of .icon-right in die-core om verschillende redenen:
Probleempunten van utility classes in componenten ​
Mixing paradigms: Het gebruik van utility classes zoals
icon-rightenlabel-smallin een componentenbibliotheek mengt twee verschillende architecturale benaderingen (utility CSS vs. component-based CSS)Poor semantics: Classes die presentatiedetails beschrijven (positie, grootte) in plaats van doel maken code minder onderhoudbaar en moeilijker te begrijpen
Component independence: In een Lit componentenbibliotheek moet elke component zelfstandig zijn met betekenisvolle classnamen die de domeinlogica weerspiegelen
Shadow DOM considerations: Lit componenten gebruiken Shadow DOM, waardoor utility classes een onlogische keuze zijn binnen het encapsulatie-model
Gefragmenteerde styling: Utility classes beschrijven typisch slechts één CSS-eigenschap, wat leidt tot gefragmenteerde styling binnen componenten:
- Een class als
label-mediumbeschrijft enkel het font, maar zegt niets over de kleur of andere eigenschappen - Een class als
icon-rightregelt alleen de positie, maar niet de grootte of kleur van het icoon - Dit vereist meerdere classes op één element, wat het moeilijk maakt om de volledige styling van een component te begrijpen
- Een class als
Drift naar multi-property utility classes: Het is verleidelijk om utility classes uit te breiden met meer eigenschappen dan hun naam suggereert:
scss/* Begint als een positie-class, maar groeit naar veel meer */ .icon-right { margin-left: auto; /* Dit past bij de naam */ width: 24px; /* Maar dit gaat over dimensie, niet positie */ height: 24px; /* Ook dimensie */ color: red; /* Kleur heeft niets met positie te maken */ cursor: pointer; /* Interactie-eigenschap */ }Dit maakt de class onvoorspelbaar en in strijd met de naam, wat leidt tot verwarring en bugs.
Moeilijk te onderhouden: Bij wijzigingen in het ontwerp moet je meerdere utility classes aanpassen in plaats van één semantische class:
html<!-- Moeilijk te onderhouden: meerdere utility classes --> <span class="label-medium icon-right text-primary m-bs-xs">Status</span> <!-- Beter te onderhouden: één semantische class --> <span class="status-label">Status</span>
Voorbeelden van onjuiste en juiste naamgeving ​
/* NIET doen in die-core .styles.scss bestanden: */
.label-medium {
/* ... */
}
.label-small {
/* ... */
}
.icon-right {
/* ... */
}
/* WEL doen: */
.label {
/* ... */
}
.icon {
/* ... */
}
.status {
/* ... */
}Verschil met Campus ​
In ons Campus platform hanteren we een andere benadering voor styling:
Utility-first approach in Campus ​
Campus maakt gebruik van een utility-first CSS benadering met gestandaardiseerde classes:
<!-- Voorbeeld van utility classes in Campus -->
<div class="flex justify-between items-center p-xs surface-container corner-m">
<h3 class="body-large weight-semibold">Cursus details</h3>
<button class="pi-xs p-b-2xs primary corner-m">Bewerken</button>
</div>Waarom utility classes WEL werken in Campus ​
In Campus zijn utility classes juist een goede keuze om verschillende redenen:
Page layouts en UI componenten: Campus bevat hoofdzakelijk pagina-layouts en UI-componenten buiten Shadow DOM, waar utility classes effectief zijn voor snelle ontwikkeling
Consistente utility framework: De utility classes in Campus zijn onderdeel van een vast utility framework binnen CDS, wat zorgt voor consistentie en voorspelbaarheid
Angular compound components: Voor compound components in Angular (buiten Shadow DOM) bieden utility classes flexibiliteit zonder de overhead van nieuwe CSS te schrijven
Snelle iteratie: Campus interfaces vereisen vaak snelle iteratie en aanpassingen, waarbij utility classes efficiënter werken dan het steeds bijwerken van component-specifieke stijlen
Geen Shadow DOM encapsulatie: Zonder Shadow DOM is er een duidelijke scheiding tussen pagina-layout en componenten, waardoor utility classes makkelijker te beheren zijn
Voordelen in Campus context ​
In Campus biedt deze utility-first aanpak voordelen:
- Ontwikkelsnelheid: Snelle UI-ontwikkeling zonder steeds nieuwe CSS te schrijven
- Consistentie: Vooraf gedefinieerde waarden zorgen voor een consistent ontwerp
- Schaalbaarheid: Makkelijk aan te passen en uit te breiden voor grote applicaties
Hoe te kiezen tussen die-core en Campus stijl ​
Gebruik deze richtlijnen om te bepalen welke stijl je moet toepassen:
| Context | Aanbevolen aanpak |
|---|---|
| die-core component | Semantische classnamen in .styles.scss bestanden met CDS tokens |
| Campus UI | Utility classes voor snelle ontwikkeling |
| Aangepaste componenten in Campus | Hybride: semantische basisstructuur met utility classes voor verfijning |
Praktische voorbeelden ​
die-core component (correct) ​
// dcr-status-badge.ts
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import styles from './dcr-status-badge.styles.scss';
@customElement('dcr-status-badge')
export class DcrStatusBadge extends LitElement {
static styles = styles;
render() {
return html`
<div class="badge">
<span class="icon">${this.renderIcon()}</span>
<span class="text">${this.status}</span>
</div>
`;
}
}// dcr-status-badge.styles.scss
@use '@diekeure/cds-tokens' as cds;
.badge {
display: inline-flex;
align-items: center;
border-radius: 4px;
padding: 4px 8px;
background-color: rgb(cds.get('cds.sys.color.primary-container'));
}
.icon {
margin-right: 4px;
color: rgb(cds.get('cds.sys.color.primary'));
}
.text {
font-size: 14px;
color: rgb(cds.get('cds.sys.color.on-primary-container'));
}Campus voorbeeld (utility-first) ​
<div class="flex items-center surface-container-low pi-2xs p-b-3xs corner-s primary-text">
<span class="m-ie-2xs"><i class="fas fa-info-circle"></i></span>
<span class="label-medium">Status informatie</span>
</div>Conclusie ​
Bij het ontwikkelen van componenten in die-core, focus op semantische, betekenisvolle classnamen in je .styles.scss bestanden die het doel van elementen beschrijven. Vermijd utility classes of presentatie-gerichte naamgeving zoals .icon-right of .label-small. Gebruik in plaats daarvan CDS design tokens via de @use '@diekeure/cds-tokens' as cds; import.
Door deze richtlijnen te volgen, creëren we een consistente, onderhoudbare componentenbibliotheek die gemakkelijk te begrijpen en te gebruiken is door alle ontwikkelaars in het team.