name: html description: Writes and reviews semantic, accessible HTML and template markup that stays readable and low-noise. Use when creating or refactoring HTML or Svelte templates, cleaning up div soup, choosing better elements, improving form markup, fixing heading or landmark structure, or replacing custom controls with native HTML. metadata: category: Frontend & Accessibility tags: - html - semantics - accessibility - forms - markup
HTML
Write HTML that is semantic, accessible, maintainable, and easy to scan. Prefer simple structure, meaningful elements, and minimal wrapper noise.
Core Principle
Use the most appropriate HTML element for the content and interaction. Do not apply best practices mechanically.
When to Use This Skill
Use this skill when:
- writing raw HTML or template markup
- refactoring noisy or wrapper-heavy markup
- improving semantics, landmarks, or heading structure
- fixing form labeling and control choice
- deciding between
div,section,article,ul, and other structural elements - replacing custom interactions with better native HTML
- cleaning up Svelte component markup without changing its behavior
Do not use this skill for:
- pure CSS architecture decisions
- JavaScript behavior design unless the HTML choice is the root issue
- marketing copy or content strategy
- deep framework-specific state or reactivity changes unrelated to markup structure
Decision Order
When writing or reviewing markup:
- choose the element that best matches the content or interaction
- prefer native HTML behavior before custom behavior
- remove wrappers that add no structural value
- ensure labels, headings, landmarks, and image handling are correct
- add ARIA only when native HTML cannot express the needed behavior
Template Safety
When the markup lives inside Svelte or another HTML-like template language:
- treat the file as template markup, not as a plain standalone HTML document
- preserve framework syntax such as
{#if},{#each},{:else},{@html},bind:,class,style:, event attributes, and special elements like<svelte:head> - do not replace components or capitalized tags with native elements unless the task explicitly asks for that change
- improve the HTML around directives and blocks without breaking bindings, keys, control flow, or component boundaries
- apply full-document rules like
<!doctype html>,html,head, andbodyonly when the file is actually a document shell - in Svelte, treat compiler accessibility warnings as useful guardrails and do not add
svelte-ignorecomments casually
Rules
1. Prefer Semantic Elements
- Use semantic tags whenever they accurately match the content:
headermainsectionarticlenavasidefooterbuttonformlabel
- Do not use
divwhen a semantic element is clearly better - Do not force a semantic element where a plain container is more accurate
2. Structure Content by Meaning
- HTML should describe content structure, not visual appearance
- Choose elements based on what the content is
- Do not choose elements based on default browser styles
- Do not invent extra structure just to satisfy a rule
3. Keep Nesting Shallow
- Avoid unnecessary wrappers
- Prefer flatter, easier-to-read markup
- Every extra layer should have a real structural, behavioral, or styling purpose
4. Heading Hierarchy Must Make Sense
- Use one clear
h1for the page or main view - Follow a logical heading order:
h1h2h3
- Do not skip heading levels without reason
- Do not use headings just to create large text
5. Accessibility Is Required
- Always use proper labels for form controls
- Use
buttonfor actions andafor navigation - Add meaningful
alttext to informative images - Use ARIA only when native HTML cannot solve the problem
- Do not add unnecessary ARIA
6. Prefer Native HTML Behavior
- Use built-in HTML features before custom solutions
- Prefer:
buttondetailssummarydialoginputselectfieldsettable
- Avoid rebuilding native controls with generic elements
7. Write Readable Markup
- Keep formatting consistent
- Use clear indentation
- Keep attributes readable
- Break lines when markup becomes hard to scan
- Optimize for humans reading the source
8. Keep Class Names Purposeful
- Add classes only when needed for styling or scripting
- Do not add classes to every element by default
- Prefer simple, meaningful class names
- Avoid naming based only on presentation when possible
9. Avoid Div Soup
- Do not create long chains of anonymous
divelements - If many wrappers appear, reconsider the structure
- Simplify before adding more containers
- A plain
divis fine when no stronger semantic exists
10. Forms Must Be Explicit
- Every input needs an associated label
- Use
typevalues correctly - Use
namefor submitted fields - Use
fieldsetandlegendfor grouped inputs - Mark required fields with HTML attributes, not only text
- Do not rely on placeholder text as the label
11. Use Lists Only When Content Is Truly a List
- Use
ul/ol/liwhen the content is actually a list:- steps
- menu items
- bullet points
- grouped items where membership in a list is the important meaning
- Do not use list markup just because content repeats
- Repetition alone is not list semantics
Use article when:
- each repeated item can stand on its own
- each item has its own heading, metadata, or actions
- the repeated content is more like cards, posts, results, stories, or entries
Use section when:
- content is grouped by theme or purpose
- the group benefits from its own heading
- the point is thematic grouping, not list membership
Use plain containers when:
- the markup is mainly for layout
- there is no stronger semantic meaning
- list or landmark semantics would be artificial
Avoid:
- wrapping card grids in
ul/liby default - using
lifor any repeated component pattern - forcing semantics onto layout-only structures
12. Keep Content and Behavior Separate
- HTML defines structure
- CSS defines presentation
- JavaScript defines behavior
- Avoid inline styles and plain HTML event handler strings like
onclick="..." - In template languages, do not mistake framework event attributes for plain inline JS
13. Links and Buttons Are Not Interchangeable
- Use
awhen going somewhere - Use
buttonwhen doing something - Never use a clickable
divorspaninstead of a button - Never use a button for plain navigation unless there is a real app-style reason
14. Images Need Intentional Handling
- Use
alt=""for decorative images - Use descriptive
altfor informative images - Provide width and height when possible to reduce layout shift
- Use
figureandfigcaptionwhen the caption is part of the content
15. Metadata Matters
- For full HTML documents, include:
<!doctype html>langonhtmlmeta charset="utf-8"meta name="viewport" content="width=device-width, initial-scale=1"- meaningful
title
- For component files or template fragments, add document metadata only through the framework's proper mechanism, such as
<svelte:head>in Svelte - Add other metadata only when it serves a clear purpose
16. Avoid Semantic Overfitting
- Do not apply rules mechanically
- “Semantic HTML” does not mean using the most specialized element possible everywhere
- The best element is the one that most accurately reflects the content and interaction
- A simple structure with a few plain containers is better than incorrect semantics
17. Landmarks Should Be Meaningful
- Use landmarks like
main,nav,header,footer, andasidewhere they help define page structure - Do not wrap every small subsection in landmark elements
- Landmarks should help orientation, not create noise
18. Prefer Minimal Honest Markup
- Start with the smallest correct structure
- Add elements only when they improve meaning, accessibility, or maintainability
- Do not add wrappers, labels, or semantics just in case
Anti-Patterns
- using
divfor buttons or links - adding ARIA when native HTML already works
- skipping labels on inputs
- using headings for styling only
- deeply nested wrapper elements
- using tables for layout
- plain HTML inline event handler strings like
onclick="..." - rewriting valid Svelte directives or blocks as if they were broken HTML
- adding
html,head, orbodytags inside component files - meaningless class names like
box1,red_text,left_side - wrapping card layouts in
ul/liby default - using semantic elements only because content repeats
- adding extra landmarks with no navigational value
- placeholder text used instead of labels
Heuristics
- can each element justify why it exists?
- is there a semantic element that should replace this
div? - would this still make sense without CSS?
- can a screen reader understand the structure?
- are actions buttons and destinations links?
- is the heading order logical?
- are forms fully labeled and grouped correctly?
- is any ARIA actually necessary?
- is this truly a list, or just repeated content?
- does each repeated item stand alone enough to be an
article? - am I editing a full document, or a component/template fragment?
- would this cleanup break a Svelte directive, binding, block, key, or component boundary?
- am I choosing an element because it is accurate, or because it is a rule I memorized?
Output Guidelines
When writing HTML:
- start with semantic structure first
- keep the markup minimal
- prefer native elements and native behavior
- optimize for readability and maintainability
- remove unnecessary wrappers
- do not add ARIA, classes, or attributes unless they have a clear job
- do not force
ul/li,section, orarticlewhen the semantics are weak - in Svelte or other template files, preserve directives, block syntax, bindings, and special elements
- prefer accurate structure over mechanical best-practice compliance
Example Preferences
Good
- semantic landmarks where they help
- shallow nesting
- explicit labels
- logical headings
- minimal wrappers
- native controls
articlefor standalone repeated entriesul/olonly for actual lists- plain containers when semantics are minimal
Bad
- div soup
- clickable non-interactive elements
- vague structure
- helper text replacing proper semantics
- extra wrappers for no reason
- custom controls when native HTML works
- using list markup for every repeated card
- over-structuring simple layouts
- semantic overfitting