Documentation

Learn how to use VanillaHTML to build semantic, accessible websites

Getting Started

VanillaHTML is made up of three CSS files that work together:

reset.css
A modern CSS reset (by Andy Bell) that removes browser default styles so every element starts from a consistent baseline.
vanillaHTML.css
The core stylesheet. It contains CSS variables for theming, dark mode support, and all the element styles wrapped in a @layer vanillaHTML block.
global.css
Your own stylesheet for overrides and custom classes. Because VanillaHTML uses a CSS layer, any styles you write in global.css will automatically take priority — no !important needed.

Installation

Copy or download the CSS files from Github and link them in your HTML:

<link rel="stylesheet" href="./vanillaHTML.css" />
<link rel="stylesheet" href="./reset.css" />
<link rel="stylesheet" href="./global.css" />

How CSS Layers Work

VanillaHTML wraps its styles in @layer vanillaHTML { ... }. CSS layers have lower priority than un-layered styles, so anything you write in global.css will override VanillaHTML without specificity battles. This means you can start with VanillaHTML's defaults and progressively customize as you learn more CSS.

Page Structure

Landmark elements that define your page layout

Every HTML page should use semantic landmark elements to define its structure. These elements help screen readers and search engines understand your content. VanillaHTML styles all of them automatically.

<header>
The top of the page. Contains navigation and branding. Maps to the banner landmark role.
<nav>
Site navigation links. Maps to the navigation landmark role.
<main>
The primary content of the page. There should only be one per page. Maps to the main landmark role.
<section>
A thematic grouping of content with a heading. VanillaHTML gives sections a border and card-like layout.
<footer>
The bottom of the page. Contains secondary navigation, about info, and credits. Maps to the contentinfo landmark role.

Example Structure

<body>
  <header>
    <nav>
      <ul>
        <li><a href="./index.html">Home</a></li>
        <li><a href="./about.html">About</a></li>
      </ul>
    </nav>
  </header>
  <main>
    <section>
      <header>
        <hgroup>
          <h1>Page Title</h1>
          <p>Subtitle</p>
        </hgroup>
      </header>
      <div>Content goes here</div>
    </section>
  </main>
  <footer>...</footer>
</body>

Headings & Text

Typography elements for structuring content

Headings create a document outline that assistive technology uses to navigate your page. Always use headings in order — don't skip from <h1> to <h3>.

Headings

Heading 1

Use once per page as the main title

Heading 2

Major sections within the page

Heading 3

Sub-sections within an h2

Heading 4

Sub-sections within an h3

<hgroup>
  <h1>Heading 1</h1>
  <p>Use once per page as the main title</p>
</hgroup>

<hgroup>
  <h2>Heading 2</h2>
  <p>Major sections within the page</p>
</hgroup>

Inline Text Elements

<strong> — indicates important text.
<em> — indicates emphasized text.
<b> — bold text without added importance.
<small> — side comments, fine print.
<mark> — highlighted/marked text.
abbr — abbreviations (hover to see the title).
H2O — <sub> for subscript.
x2<sup> for superscript.

<strong>Important text</strong>
<em>Emphasized text</em>
<b>Bold text</b>
<small>Fine print</small>
<mark>Highlighted text</mark>
<abbr title="Abbreviation">abbr</abbr>
H<sub>2</sub>O
x<sup>2</sup>

Links

Anchor elements for navigation and references

The <a> element creates hyperlinks. VanillaHTML styles links with an underline and removes default borders.

This is an external link (opens in a new tab)

When linking to external sites, use target="_blank" with rel="noopener" to prevent the new page from accessing your page's window.opener object.

<!-- Internal link -->
<a href="./about.html">About Page</a>

<!-- External link -->
<a href="https://example.com" target="_blank" rel="noopener">
  External Site
</a>

Lists

Ordered, unordered, menus, and description lists

Unordered List

Use <ul> when the order of items doesn't matter.

  • First item
  • Second item
  • Third item
<ul>
  <li>First item</li>
  <li>Second item</li>
  <li>Third item</li>
</ul>

Ordered List

Use <ol> when the sequence matters.

  1. Step one
  2. Step two
  3. Step three
<ol>
  <li>Step one</li>
  <li>Step two</li>
  <li>Step three</li>
</ol>

Menu

The <menu> element is a semantic alternative to <ul> for toolbars and navigation groups. VanillaHTML uses it in the footer.

<menu>
  <li><a href="./index.html">Home</a></li>
  <li><a href="./about.html">About</a></li>
</menu>

Description List

Use <dl> for term-definition pairs. VanillaHTML adds a bottom border to terms and a triangle marker to definitions.

Semantic HTML
Using HTML elements according to their intended meaning.
Accessibility
Designing websites that everyone can use, including people with disabilities.
<dl>
  <dt>Semantic HTML</dt>
  <dd>Using HTML elements according to their intended meaning.</dd>
  <dt>Accessibility</dt>
  <dd>Designing websites that everyone can use.</dd>
</dl>

Tables

A simple structure to easily see your table data

Tables should only be used for tabular data — never for layout. VanillaHTML styles tables with alternating row colors, borders, and responsive overflow handling.

Example Table
PROS CONS
  • Easier to see what you are doing as a beginner
  • Makes use of Semantic HTML
  • Responsive
  • No class names for easy overwrites
  • Default form inputs look good
  • Tables come pre styled for rapid development
  • Opinionated styles
  • Delay Learning CSS
Here's another row just to look at! The CSS contains some properties that do not have baseline support yet.
Progressive Enhancement: Use an updated version of Chrome for the best experience.
And this is a table footer!
<table>
  <caption>Example Table</caption>
  <thead>
    <tr>
      <th scope="col">PROS</th>
      <th scope="col">CONS</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>...</td>
      <td>...</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2">Footer content</td>
    </tr>
  </tfoot>
</table>

Use scope="col" on <th> elements to indicate they are column headers. This helps screen readers associate data cells with their headers.

Forms

CSS-only validation, basic styling, cursor updates

VanillaHTML styles form elements with sensible defaults: text inputs get proper padding and borders, buttons get hover and active states, and validation uses CSS-only color feedback (green for valid, orange for invalid, red for focused required fields).


Choose your favorite monster

Do you agree?
CSS-Only Form Validation


Press Submit to see an example <button> press.

Form Source Code

<form onsubmit="return false;">
  <div>
    <label for="movie">Favorite Show?</label>
    <br />
    <input type="text" name="movie" placeholder="Bobs Burgers" />
  </div>

  <fieldset>
    <legend>Choose your favorite monster</legend>
    <input type="radio" id="kraken" name="monster" value="K" />
    <label for="kraken">Kraken</label>
  </fieldset>

  <div>
    <label for="rate">Rating</label>
    <input type="range" name="rate" min="0" max="100" />
  </div>

  <fieldset>
    <legend>Do you agree?</legend>
    <input type="checkbox" id="agree" name="agree" />
    <label for="agree">Agree</label>
  </fieldset>

  <label for="childhood">Tell me:</label>
  <textarea name="childhood"></textarea>

  <label for="color">Favorite Color</label>
  <input type="color" />

  <fieldset>
    <legend>CSS-Only Validation</legend>
    <label for="email">Email<sup>*</sup></label>
    <input required type="email" name="email" />
    <label for="password">Password<sup>*</sup></label>
    <input required minlength="12" type="password" name="password" />
  </fieldset>

  <button type="submit">Submit</button>
</form>

Blockquotes & Citations

Quoting text with proper attribution

Use <blockquote> for extended quotations. VanillaHTML wraps blockquotes in a dark container with automatic curly quotes. Use <cite> for the source.

Never gonna make you cry, Never gonna say goodbye,

- Rick Astley, Never Gonna Give You Up

<div>
  <blockquote cite="https://example.com">
    <p>The quoted text goes here.</p>
  </blockquote>
  <p>
    - Author Name,
    <cite><a href="https://example.com">Source Title</a></cite>
  </p>
</div>

Details & Summary

Collapsible content without JavaScript

The <details> element creates a disclosure widget that the user can open and close. The <summary> element provides the visible heading. This is one of the best examples of HTML doing the work that many developers reach for JavaScript to accomplish.

HTML and CSS Only...
No JavaScript required.
<details>
  <summary>Click to expand</summary>
  <div>Hidden content revealed on click.</div>
</details>

Asides

Callouts, notes, and alerts

The <aside> element represents content that is tangentially related to the main content. VanillaHTML styles asides as callout boxes with a left border. Add role="alert" for a red danger-style variant.

<!-- Default aside -->
<aside>
  A helpful note or tip.
</aside>

<!-- Alert variant -->
<aside role="alert">
  Warning: something needs attention!
</aside>

Code

Displaying code inline and in blocks

Use <code> for inline code snippets. VanillaHTML gives them a contrasting background and border. For multi-line code blocks, wrap <code> inside <pre> (preformatted text).

Inline example: the console.log() function prints output to the browser console.

<!-- Inline code -->
<p>Use the <code>console.log()</code> function.</p>

<!-- Code block -->
<pre><code>function greet(name) {
  return "Hello, " + name;
}</code></pre>

Images & Figures

Displaying images with captions and proper alt text

Use <img> to embed images. Every image must have an alt attribute that describes the image for screen readers and when images fail to load. Wrap images in <figure> with a <figcaption> when they need a visible caption.

<!-- Simple image -->
<img src="photo.jpg" alt="A description of the photo" />

<!-- Image with caption -->
<figure>
  <img src="chart.png" alt="Bar chart showing monthly sales" />
  <figcaption>Monthly sales data for 2025</figcaption>
</figure>

Alt text tips: Be specific and concise. Describe what the image shows, not what it is. For decorative images, use an empty alt="" so screen readers skip them.

Theming

CSS variables for customizing the look

VanillaHTML uses CSS custom properties (variables) for all colors. You can override any variable in your own stylesheet to create a custom theme. The main variables are defined in :root inside vanillaHTML.css.

/* Override in your global.css */
:root {
  --background: #1a1a2e;
  --text: #eee;
  --surface-dark: #16213e;
  --color-accent: coral;
}

Shades

A grayscale palette from black to white, available as CSS variables.

--shade-0
rgb(0, 0, 0)
--shade-5
rgb(5, 5, 5)
--shade-25
rgb(25, 25, 25)
--shade-50
rgb(50, 50, 50)
--shade-75
rgb(75, 75, 75)
--shade-100
rgb(100, 100, 100)
--shade-125
rgb(125, 125, 125)
--shade-150
rgb(150, 150, 150)
--shade-175
rgb(175, 175, 175)
--shade-200
rgb(200, 200, 200)
--shade-225
rgb(225, 225, 225)
--shade-250
rgb(250, 250, 250)
--shade-255
rgb(255, 255, 255)

Colors

Status colors used for validation, alerts, and accents.

--color-danger
rgb(255, 0, 0)
--color-caution
rgb(255, 165, 0)
--color-success
rgb(0, 128, 0)

Dark Mode

Automatic theme switching based on system preference

VanillaHTML includes built-in dark mode support using the prefers-color-scheme media query. When a user's operating system is set to dark mode, the semantic color variables are automatically swapped — backgrounds become dark, text becomes light, and surfaces invert.

/* How it works in vanillaHTML.css */
@media (prefers-color-scheme: dark) {
  :root {
    --background: #232323;
    --text: var(--shade-255);
    --surface-light: var(--shade-50);
    --surface-dark: var(--shade-225);
    --text-inverse: var(--shade-0);
  }
}

To customize dark mode, override the same variables inside the same media query in your global.css:

/* In your global.css */
@media (prefers-color-scheme: dark) {
  :root {
    --background: #0d1117;
    --surface-dark: #161b22;
    --color-accent: #58a6ff;
  }
}

Because VanillaHTML uses semantic variable names like --text and --background (instead of literal color names), the entire design adapts automatically. You only need to define your palette once for light mode and once for dark mode.