Læringsmål
- Skrive semantisk HTML i
.razor-filer (header, main, nav, article). - Forklare box model og bruge margin/padding bevidst.
- Anvende scoped CSS (
.razor.css) uden at lække styles globalt. - Bygge responsive layout med Bootstrap grid eller tilsvarende.
Hvornår investere i markup/CSS? Før I binder tung API-logik — læsbar struktur gør Master/Detail og fejl-states nemmere at style (loading, tom liste, 401-banner).
Tjek dig selv før du går videre
- Du kan forklare forskellen på semantisk HTML og div-soup.
- Du ved hvad scoped CSS (.razor.css) gør.
- Du har besvaret mindst ét quiz-spørgsmål korrekt.
I Blazor er markup stadig HTML. Razor tilføjer kun C#-udtryk (@), direktiver (@page, @inject) og kontrolstrukturer (@if, @foreach).

@code.Semantisk HTML
Skærm læsere og SEO (hvor relevant) profitterer fra meningsfulde tags:
<header>— titel/toolbar for sektion eller side<nav>— navigationslinks (NavMenu)<main>— primært indhold (én per side)<article>— selvstændigt kort (Pokémon-entry)<section>— tematisk gruppe
<main>
<header>
<h1>Pokédex</h1>
<p>Data fra OpgaverAPI</p>
</header>
<section aria-label="Resultater">
@foreach (var p in pokemon)
{
<article class="dex-card">
<h2>@p.Name</h2>
<img src="@p.Sprite" alt="" width="96" height="96" />
</article>
}
</section>
</main>
Brug alt på Pokémon-sprites med meningsfuld tekst — tom alt="" kun hvis billedet er rent dekoration.
Box model
Hvert element er en boks: content → padding → border → margin. box-sizing: border-box (Bootstrap default) gør bredde inkl. padding — nemmere grids.
Box model — visuelt
Yderst margin, så border, padding, og content inderst.
Margin collapse mellem sibling cards kan «ødelægge» vertikal rytme — brug gap i flex/grid (row g-3 i Bootstrap) i stedet for kun margin på hvert kort.
Selectors og typografi
- Klasser (
.dex-card) frem for inline styles — genbrug på tværs af komponenter - Undgå for dybe selectors — svære at overskrive med isolation
- Links: tydelig
:focusfor tastaturbrugere
Hvornår global vs scoped? Tema, fonts og Bootstrap-import i wwwroot/app.css. Kort-specifik layout (LoL rolle-badge) i .razor.css så det ikke påvirker hele appen.
CSS isolation
Filen PokemonCard.razor.css scopes styles til komponenten via attributter Blazor genererer:
/* PokemonCard.razor.css */
.card {
border: 1px solid var(--border, #334);
border-radius: 12px;
padding: 1rem;
}
.card h3 {
font-size: 1.1rem;
margin: 0 0 0.5rem;
}
Global CSS i wwwroot/app.css til tema, fonts og Bootstrap-import.
Elev-fejl → symptom → fix: Deep selector i global CSS rammer MudBlazor-knapper — symptom: demo ser «forkert» ud. Fix: flyt til komponent-scoped fil eller brug BEM-lignende klasser.
Bootstrap grid
<div class="container py-4">
<div class="row g-3">
@foreach (var c in champions)
{
<div class="col-12 col-md-6 col-lg-4">
<article class="card h-100">
<div class="card-body">
<h3 class="card-title">@c.Name</h3>
<p class="card-text">@c.Role</p>
</div>
</article>
</div>
}
</div>
</div>
col-12 = fuld bredde mobil; col-md-6 = to kolonner tablet; col-lg-4 = tre på desktop.
Hvornår grid frem for flex? Når I viser mange ens kort (Pokémon, LoL) i responsivt raster — g-3 gap erstatter manuel margin mellem cards.
@page "/pokemon-kort"
<article class="card">
<h2>@navn</h2>
<img src="@sprite" alt="@navn" width="96" height="96" />
<ul>
@foreach (var t in types)
{
<li>@t</li>
}
</ul>
</article>
@code {
string navn = "Pikachu";
string sprite = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png";
string[] types = ["electric"];
}
Quiz 1
Hvor scopes styles til kun ét Razor-komponent?
Quiz 2
Hvilket element bør wrappe hovedindholdet på en side (accessibility)?
Hvorfor det betyder noget: Dårlig semantik og global CSS gør Pokémon-liste og LoL-grid umulige at vedligeholde i gruppeprojekt.
Sådan fejler det i praksis: Scoped CSS overskrives af global bootstrap uden ::deep — «hvorfor virker min styling ikke?»
Mini-opgave
Lav PokemonBadge.razor med semantisk <article>, scoped CSS til type-farve, tre mock-navne — uden inline styles på root.
Quiz 3
Hvor hører styling til én PokemonCard typisk hjemme?
Læs hos Microsoft
Prøv med API
- Hent data fra Pokémon-demo og tegn et responsivt grid med semantisk HTML.
- Sammenlign med LoL — samme grid, anden DTO.
Baseret på MAGS Blazor-wiki og Microsoft Learn — Blazor.