matcha.css

matcha.css

Drop-in semantic styling library in pure CSS.

matcha.css is a pure CSS library designed to style HTML elements similarly to a default browser stylesheet, eliminating the need for users to manually patch their documents.

Ideal for fast prototyping, static HTML pages, Markdown-generated documents, and developers seeking to streamline their workflow without delving into CSS intricacies and want to make use of the full range of available HTML elements.

  • No build steps
  • No dependencies
  • No JavaScript
  • No configuration needed
  • No refactoring required
  • ~8.79kB gzipped (can be further reduced)

🍵 Fun Fact: This very page is styled using matcha.css!

Why choose matcha.css?

Agnostic
Works seamlessly with any document and covers a broader range of HTML elements compared to similar libraries. It remains unobtrusive by leveraging CSS pseudo-elements and offers extensive browser support.
Reversible
Simply include its <link rel="stylesheet"> to get started, and remove it whenever necessary without the need for document refactoring or cleanup.
Semantic
Adapts styling based on elements hierarchy, providing intuitive behaviors such as implicit submenus when nesting <menu> elements, required field indicator (*) when a <label> is paired with <input required>, etc.
Customizable
Brew your own build using our custom builder to select specific features and reduce the final build size according to your project's needs.
Open-source
Released under the MIT License, freely available at github.com/lowlighter/matcha.

Usage

To utilize matcha.css, just include the following line in the <head> section of your document. It's that simple!

<link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css">

Assets are hosted on Vercel but matcha.css is also available on npm and CDN services that distributes npm packages such as JSdelivr.

All published versions are available in the /v/ directory. By default, the main branch is served.

À la carte

Each subdirectory available in github.com/lowlighter/matcha/styles is also served directly from this website. For example, if you only wish to include the @syntax-highlighting styles rather than using the default build or a custom one, you could use:

<link rel="stylesheet" href="https://matcha.mizu.sh/styles/@syntax-highlighting/mod.css">

However note that unless you provide your own CSS variables, you will most likely need to include the @root package as it contains all matcha.css variables definition.

All mod.css files are also aliased to their respective parent directories for convenience, which means you can also use:

<link rel="stylesheet" href="https://matcha.mizu.sh/@syntax-highlighting.css">

Preset builds

matcha.css provides preset builds for added convenience. If you need a specific set of features, you can also use the custom builder.

  • Default ~8.79kB
    • All semantic styling and extra features except @istanbul-coverage.
    • <link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css">
  • Lite ~5.56kB
  • Utility classes ~3.42kB
    • @root and @utilities.
    • <link rel="stylesheet" href="https://matcha.mizu.sh/matcha.utilities.css">
  • Istanbul coverage ~1.92kB

🛠️ Create a custom build

Utilize the form below to obtain a custom build of matcha.css.

For more intricate customization, consider forking and directly patching it. Note that matcha.css never utilizes !important rules, ensuring ease of style overriding if necessary.

Customize CSS variables
Colors and backgrounds
Colors Backgrounds Example usage
Name Light Dark Name Light Dark
--default --bg-default default text color and background color
--contrast --bg-contrast used to constrast with --default
--subtle --bg-subtle <progress> and <meter> backgrounds, etc.
--muted --bg-muted .disabled, <caption>, <blockquote>, etc.
--accent --bg-accent :hover, .selected, <a>, <button>, etc.
--active --bg-active :active, :focus, etc.
--variant --bg-variant
--success --bg-success :user-valid, <ins>, <meter>'s optimum value, etc.
--attention --bg-attention <meter>'s sub-optimum value, etc.
--severe --bg-severe
--danger --bg-danger :user-invalid, <del>, <meter>'s sub-sub-optimum value, <button type="reset">, etc.
Font related variables
Layouts

These variables are only revelant when using a layout from @layouts extra feature.

Miscellaneous
Name Light Dark Example usage
Color Alpha Color Alpha
--backdrop dialog::backdrop, --shadow, etc.
--bd-muted <td>, <th>, <article>, <blockquote>, <fieldset>, <input>, <select>, <textarea>, etc.
Customization
Miscellaneous
Preview

Preview your custom build to ensure it fits your taste.

  • Brew matcha!

    Ready to brew your custom matcha? Click the button below to get started!

    🕵️ Preview a Website

    Feel free to use the form below to preview any website using matcha.css.

  • ☑️ Supported browsers

    matcha.css is meticulously crafted to ensure compatibility with all modern browsers.

    Methodology:
    1. Generate matcha.css stylesheet.
    2. Generate report table using jsr.io/@libs/bundle, which performs the following tasks:
      1. Retrieves the browsers list using browserslist.
      2. Parses the stylesheet using csstree.
      3. Checks the support of each CSS feature across browser versions using MDN browser compatibility data.
      4. Generates a summary <table> for easy reference.
    Notes:
    • Browser list adheres to defaults (> 0.5%, last 2 versions, Firefox ESR, not dead).
    • The first row displays the overall support for each browser.
    • Please note that the auto-generated table may contain minor inaccuracies due to the complexity of mapping CSS features against compatibility data.
    • Thus, browsers scoring 90% and above are considered fully supported.

    You can toggle verbosity to display additional information, such as specific CSS features and rules reported as partially supported or unsupported.

    • Unsupported feature
    • Partially supported feature
    • Prefixed supported feature
    • Unknown feature
    Chrome
    92%

    mask-clip: *;
    mask-clip: dashed;
    mask-clip: solid transparent;
    mask-clip: solid;
    mask-clip: transparent;
    mask: center center/no-repeat;
    mask-image: url();
    :user-valid
    :user-invalid
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Edge
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Safari
    94%

    text-size-adjust: *;
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Firefox
    94%

    text-size-adjust: *;
    :has
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Opera
    95%

    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Android Chrome
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    iOS Safari
    92%

    text-size-adjust: *;
    user-select: all;
    :user-valid
    :user-invalid
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Samsung Internet
    91%

    mask-clip: *;
    mask-clip: dashed;
    mask-clip: solid transparent;
    mask-clip: solid;
    mask-clip: transparent;
    mask: center center/no-repeat;
    :user-valid
    :user-invalid
    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Opera Mobile
    95%

    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Android Browser
    93%

    mask-clip: *;
    mask-clip: dashed;
    mask-clip: solid transparent;
    mask-clip: solid;
    mask-clip: transparent;
    text-align: center;
    text-align: right;
    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    Android Firefox
    95%

    text-size-adjust: *;
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    125
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    125
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    17.5
    94%

    text-size-adjust: *;
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    126
    95%

    text-size-adjust: *;
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    109
    95%

    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    125
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    17.5
    94%

    text-size-adjust: *;
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    24
    91%

    mask-clip: *;
    mask-clip: dashed;
    mask-clip: solid transparent;
    mask-clip: solid;
    mask-clip: transparent;
    mask: center center/no-repeat;
    :user-valid
    :user-invalid
    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    80
    95%

    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    125
    93%

    mask-clip: *;
    mask-clip: dashed;
    mask-clip: solid transparent;
    mask-clip: solid;
    mask-clip: transparent;
    text-align: center;
    text-align: right;
    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    126
    95%

    text-size-adjust: *;
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    124
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    124
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    17.4
    94%

    text-size-adjust: *;
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    125
    95%

    text-size-adjust: *;
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    108
    95%

    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    17.4
    94%

    text-size-adjust: *;
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    23
    91%

    mask-clip: *;
    mask-clip: dashed;
    mask-clip: solid transparent;
    mask-clip: solid;
    mask-clip: transparent;
    mask: center center/no-repeat;
    :user-valid
    :user-invalid
    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    123
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    123
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    124
    95%

    text-size-adjust: *;
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    107
    95%

    mask-image: url();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    17.3
    94%

    text-size-adjust: *;
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    122
    96%

    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    115
    94%

    text-size-adjust: *;
    :has
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    16.6-16.7
    94%

    text-size-adjust: *;
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    109
    91%

    mask-clip: *;
    mask-clip: dashed;
    mask-clip: solid transparent;
    mask-clip: solid;
    mask-clip: transparent;
    mask: center center/no-repeat;
    mask-image: url();
    :user-valid
    :user-invalid
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()
    15.6-15.8
    92%

    user-select: all;
    text-size-adjust: *;
    :user-valid
    :user-invalid
    backdrop-filter: blur();
    :-moz-meter-optimum
    :-moz-meter-sub-optimum
    :-moz-meter-sub-sub-optimum
    repeat()

    Sectioning

    <html> Document root

    • :root sets CSS variables.
    • @media (prefers-color-scheme) sets mode based on user's preferences.
      • [data-color-scheme="light"] forces light mode.
      • [data-color-scheme="dark"] forces dark mode.

    Note that [data-color-scheme] can be applied to any element to selectively force a color scheme.

    <body> Document body

    Has default font and padding.

    • > header:first-child has negative lateral margins that cancel parent padding.
    • > footer:last-child has negative lateral margins that cancel parent padding.

    <main> Main section

    Has a bottom margin.

    <section> Section

    Is responsive.

    Has a bottom margin.

    Has right-aligned text.

    <aside> Aside

    Floats to the right in --muted color with a left border.

    • .left floats to the left and has a right border instead.
  • *Elements below have borders for illustration purposes.

    <header>

    Tales of the last Lorekeeper

    The paintings that cover the walls of this tower... These are the history of humanity and of nature itself. They're the tales that have been passed down by my ancestors for thousands of years.

    Thousands of years ago, in the primal age long lost, the world was overflowing with natural energy. People could do nothing. The only choice was to watch as disaster upon disaster swept over them.

    It was in such a time that a great many meteoroids poured from the darkness of space, from a place higher even than the heavens.

    <footer>

    — Zinnia
    See code
    <section>
      <header>
        
        <h3>Tales of the last Lorekeeper</h3>
      </header>
      <p>
        The paintings that cover the walls of this tower...
        These are the history of humanity and of nature itself.
        They're the tales that have been passed down by my ancestors for thousands of years.
      </p>
      <aside>
        
        <p>
          The people had a wish—a memory from a thousand years before...
        </p>
      </aside>
      <p>
        Thousands of years ago, in the primal age long lost, the world was overflowing with natural energy.
        People could do nothing.
        The only choice was to watch as disaster upon disaster swept over them.
      </p>
      <p>
        It was in such a time that a great many meteoroids poured from the darkness of space, from a place higher even than the heavens.
      </p>
      <footer>
        
        <i class="muted">— Zinnia</i>
      </footer>
    </section>

    <article> Article

    In flex-columns with margins and borders.

    • > * is border-box sized with full width.
    • > header:first-child has a bottom margin.
    • > footer:last-child has a top margin and a right-aligned text.
  • Treecko

    Treecko has small hooks on the bottom of its feet that enable it to scale vertical walls. This Pokémon attacks by slamming foes with its thick tail.

    #0252

    Torchic

    Torchic sticks with its Trainer, following behind with unsteady steps. This Pokémon breathes fire of over 1,800 degrees F, including fireballs that leave the foe scorched black.

    #0255

    Mudkip

    The fin on Mudkip's head acts as highly sensitive radar. Using this fin to sense movements of water and air, this Pokémon can determine what is taking place around it without using its eyes.

    #0258
    See code
    <article>
      <header>
        <h1>
          <img src="https://www.pokepedia.fr/images/c/c0/Miniature_0252_RS.gif" alt>
          Treecko
        </h1>
      </header>
      <p>
        Treecko has small hooks on the bottom of its feet that enable it to scale vertical walls. This Pokémon attacks by slamming foes with its thick tail.
      </p>
      <footer class="muted">
        #0252
      </footer>
    </article>
    <article>
      <header>
        <h1>
          <img src="https://www.pokepedia.fr/images/5/55/Miniature_0255_RS.gif" alt>
          Torchic
        </h1>
      </header>
      <p>
        Torchic sticks with its Trainer, following behind with unsteady steps. This Pokémon breathes fire of over 1,800 degrees F, including fireballs that leave the foe scorched black.
      </p>
      <footer class="muted">
        #0255
      </footer>
    </article>
    <article>
      <header>
        <h1>
          <img src="https://www.pokepedia.fr/images/5/56/Miniature_0258_RS.gif" alt>
          Mudkip
        </h1>
      </header>
      <p>
        The fin on Mudkip's head acts as highly sensitive radar. Using this fin to sense movements of water and air, this Pokémon can determine what is taking place around it without using its eyes.
      </p>
      <footer class="muted">
        #0258
      </footer>
    </article>

    matcha.css applies styling to <article> elements designed to seamlessly integrate with a parent container set to display: flex.

    <hr> Horizontal Rule

    In --muted color.


  • See code
    <hr>

    Navigation

    Has a bottom border.

    • > li > a lose their default style.
    • > li.selected is in --accent color with a bottom border.
    • > li.disabled is in --muted color.

    Nesting a <menu> will create a submenu.

    • > li:has(> menu)::after appends a downwards triangle ().
    • > li > menu > li.selected has a left border rather than a bottom one.

    <li> List item

    Has left padding.

  • *This menu contains additional scripting that is not part of matcha.css.

  • Viennoiseries
  • Croissant
  • Éclair
  • Tartelettes
  • Aux mûres
  • Aux framboises
  • Aux fraises
  • Pain au chocolat
  • Macarons
  • Pain perdu
  • See code
    <menu>
      <li>
        Viennoiseries
        <menu>
          <li>Croissant</li>
          <li>Éclair</li>
          <li>
            Tartelettes
            <menu>
              <li>Aux mûres</li>
              <li>Aux framboises</li>
              <li class="disabled">Aux fraises</li>
            </menu>
          </li>
          <li>Pain au chocolat</li>
        </menu>
      </li>
      <li class="selected">Macarons</li>
      <li class="disabled">Pain perdu</li>
    </menu>

    Display depends on content.

    Displayed as breadcrumbs.

    • ol > li > a::after appends a slash (/).
    • ol > li:last-child is in --default color and in semi-bold.
  • See code
    <nav>
      <ol>
        <li><a href="#">Viennoiseries</a></li>
        <li><a href="#">Tartelettes</a></li>
        <li><a href="#">Aux mûres</a></li>
      </ol>
    </nav>

    Displayed as navigation list.

    • ul > li:hover has a left border.
    • ul > li.selected is in --default color and in semi-bold.
    • ul > li.disabled is in --muted color.
  • See code
    <nav>
      <ul>
        <li>
          <a href="#">Viennoiseries</a>
          <ul>
            <li><a href="#">Croissant</a></li>
            <li><a href="#">Éclair</a></li>
            <li>
              <a href="#">Tartelettes</a>
              <ul>
                <li><a href="#">Aux mûres</a></li>
                <li><a href="#">Aux framboises</a></li>
                <li class="disabled"><a href="#">Aux fraises</a></li>
              </ul>
            </li>
            <li><a href="#">Pain au chocolat</a></li>
          </ul>
        </li>
        <li class="selected"><a href="#">Macarons</a></li>
        <li class="disabled"><a href="#">Pain perdu</a></li>
      </ul>
    </nav>

    Displayed as navigation menu.

  • See code
    <nav>
      <menu>
        <li>
          <a href="#">Viennoiseries</a>
          <menu>
            <li><a href="#">Croissant</a></li>
            <li><a href="#">Éclair</a></li>
            <li>
              <a href="#">Tartelettes</a>
              <menu>
                <li><a href="#">Aux mûres</a></li>
                <li><a href="#">Aux framboises</a></li>
                <li class="disabled"><a href="#">Aux fraises</a></li>
              </menu>
            </li>
            <li><a href="#">Pain au chocolat</a></li>
          </menu>
        </li>
        <li class="selected"><a href="#">Macarons</a></li>
        <li class="disabled"><a href="#">Pain perdu</a></li>
      </menu>
    </nav>

    Headings

    <hgroup> Heading group

    Has a left border.

  • Edge of the abyss

    The 1st layer is the most shallow section of the Abyss, right below the town of Orth.

    See code
    <hgroup>
      <h1 id="hgroup-example"><a href="#">Edge of the abyss</a></h1>
      <p>The 1<sup>st</sup> layer is the most shallow section of the Abyss, right below the town of Orth.</p>
    </hgroup>

    <h{1..6}> Heading

    Font size proportional to heading level. First two levels are usually displayed with a bottom border. Last level is displayed in --muted color.

    • [id]
      • > a lose their default style.
      • > a:hover automatically prepend a --muted hash (#) (using ::after pseudo-element) and a bottom border.
  • See code
    <h1 id="h1-example"><a href="#">Forest of Temptation</a></h1>
    <h2 id="h2-example"><a href="#">Great Fault</a></h2>
    <h3 id="h3-example"><a href="#">The Goblets of Giants</a></h3>
    <h4 id="h4-example"><a href="#">Sea of Corpses</a></h4>
    <h5 id="h5-example"><a href="#">The Capital of the Unreturned</a></h5>
    <h6 id="h6-example"><a href="#">The Final Maelstrom</a></h6>

    Flow

    <p> Paragraph

    Has bottom margin.

    • :last-child has no bottom margin.
    • img is middle-aligned vertically.
  • All creatures want to believe in something bigger than themselves. They cannot live without blind obedience. And to escape the pressure of that trust, those in whom faith is placed in turn look for someone higher than themselves. And then those people in turn look for someone even stronger.

    That is how all Kings are born.

    That is how all Gods are born.

    See code
    <p>
      All creatures want to believe in something bigger than themselves.
      They cannot live without blind obedience.
      And to escape the pressure of that trust, those in whom faith is placed in turn look for someone higher than themselves.
      And then those people in turn look for someone even stronger.
    </p>
    <p>
      That is how all Kings are born.
    </p>
    <p>
      That is how all Gods are born.
    </p>

    <blockquote> Quotation block

    In --muted color with a left border.

    • > cite:last-child is left padded without an underline and is prefixed by a long em dash ().
  • Serial Experiments Lain

    I think that my little girl has, perhaps, become obsessed with the Wired. It's just an advanced medium for communication. Don't get it confused with the real world.

    Mr. Iwakura
    See code
    <blockquote>
      <h3>Serial Experiments Lain</h3>
      <p>
        I think that my little girl has, perhaps, become obsessed with the Wired.
        It's just an advanced medium for communication.
        Don't get it confused with the real world.
      </p>
      <cite>Mr. Iwakura</cite>
    </blockquote>

    <pre> Preformatted text

    In monospaced font with a background and a bottom margin.

    • :last-child has no bottom margin.
    • > code lose their default style.
  • (defun print-world (world generations)
      (let ((lim (world-size world))
            (current (world-current world)))
        (dotimes (y lim)
          (dotimes (x lim)
            (if (zerop (bit current y x))
                (princ " ")
                (princ "*")))
          (terpri))
        (format t "~&~d Generations, ~d Organisms."
                generations (world-numdots world))))
    See code
    <pre><!--
       --><code>(<span class="hljs-name">defun</span> print-world (<span class="hljs-name">world</span> generations)
      (<span class="hljs-name">let</span> ((<span class="hljs-name">lim</span> (<span class="hljs-name">world-size</span> world))
        (<span class="hljs-name">current</span> (<span class="hljs-name">world-current</span> world)))
    (<span class="hljs-name">dotimes</span> (<span class="hljs-name">y</span> lim)
      (<span class="hljs-name">dotimes</span> (<span class="hljs-name">x</span> lim)
        (<span class="hljs-name">if</span> (<span class="hljs-name">zerop</span> (<span class="hljs-name">bit</span> current y x))
            (<span class="hljs-name">princ</span> <span class="hljs-string">" "</span>)
            (<span class="hljs-name">princ</span> <span class="hljs-string">"*"</span>)))
      (<span class="hljs-name">terpri</span>))
    (<span class="hljs-name">format</span> <span class="hljs-literal">t</span> <span class="hljs-string">"~&amp;~d Generations, ~d Organisms."</span>
            generations (<span class="hljs-name">world-numdots</span> world))))</code><!--
     --></pre>

    matcha.css provides syntax highlighting classes that respect @media (prefers-color-scheme) and are fully compatible with highlight.js library.

    <figure> Figure

    Flex-wrap with space-around alignment.

    <figcaption> Figure caption

    Text centered in --muted color.

  • Éternara's Elite Four
    Damien Spectra Glacia Aragon
    See code
    <figure>
      <figcaption>
        Éternara's <a href="https://www.pokepedia.fr/Conseil_4#Conseil_4_d'%C3%89ternara" target="_blank">Elite Four</a>
      </figcaption>
      <img loading="lazy" src="https://www.pokepedia.fr/images/2/2c/Damien-ROSA.png" height="150" alt="Damien">
      <img loading="lazy" src="https://www.pokepedia.fr/images/f/fc/Spectra-ROSA.png" height="150" alt="Spectra">
      <img loading="lazy" src="https://www.pokepedia.fr/images/7/75/Glacia-ROSA.png" height="150" alt="Glacia">
      <img loading="lazy" src="https://www.pokepedia.fr/images/f/f9/Aragon-ROSA.png" height="150" alt="Aragon">
    </figure>

    Collapsibles

    <details> Details disclosure

    Has borders.

    • [open] > summary has a background.

    <summary> Details disclosure summary

    In --accent color.

    • :hover is underlined.
  • Death Note — How to use it
    1. The human whose name is written in this note shall die.
    2. This note will not take effect unless the writer has the person's face in their mind when writing his/her name. Therefore, people sharing the same name will not be affected.
    3. If the cause of death is written within the next 40 seconds of writing the person's name, it will happen.
    4. If the cause of death is not specified, the person will simply die of a heart attack.
    5. After writing the cause of death, details of the death should be written in the next 6 minutes and 40 seconds.
    See code
    <details open>
      <summary>Death Note — How to use it</summary>
      <ol>
        <li>The human whose name is written in this note shall die.</li>
        <li>This note will not take effect unless the writer has the person's face in their mind when writing his/her name. Therefore, people sharing the same name will not be affected.</li>
        <li>If the cause of death is written within the next 40 seconds of writing the person's name, it will happen.</li>
        <li>If the cause of death is not specified, the person will simply die of a heart attack.</li>
        <li>After writing the cause of death, details of the death should be written in the next 6 minutes and 40 seconds.</li>
      </ol>
    </details>

    Modals

    <dialog> Dialog modal

    Has capped size, box shadows, and borders with rounded corners. ::backdrop is displayed when dialog.showModal() is called.

    • > header:first-child has a bottom border.
      • > :is(h1, h2) have reduced font size.
    • > footer:last-child has a top border.
      • > form[method="dialog"] has no background, padding, or margin.
  • *This dialog contains additional scripting that is not part of matcha.css (it will remain open even after being closed).

    WANTED — Dead or Alive

    Gol D. Roger
    ฿5,564,800,000

    Kono sakuhin ha fiction dethunode jitsuzaisuru jinbutsu dantai sonota no soshiki to doitsu no meishou ga gekichu ni toujyou shitatoshitemo jitsuzai na monotoha issai mukankeideth.

    See code
    <dialog open>
      <header>
        <h2>WANTED — Dead or Alive</h2>
      </header>
      <p>
        <b><strong>Gol D. Roger</strong></b><br>
        <b>฿5,564,800,000</b>
      </p>
      <p>
        Kono sakuhin ha fiction dethunode jitsuzaisuru jinbutsu dantai sonota no soshiki to doitsu no meishou ga gekichu ni toujyou shitatoshitemo jitsuzai na monotoha issai mukankeideth.
      </p>
      <footer>
        <form method="dialog">
          <button type="button">Fullscreen</button>
          <button type="submit">Close</button>
        </form>
      </footer>
    </dialog>
    It is advised to use <form method="dialog"> which makes the browser natively close the dialog box without any JavaScript when it is submitted.

    Anchors

    <a> Anchor link

    In --accent color without any text decoration.

    • :hover is underlined.
    • :active is in --active color.
  • See code
    List of <a href="https://en.wikipedia.org/wiki/Communes_of_the_Somme_department" target="_blank">Communes of the Somme department</a>.

    Abbreviations

    <abbr> Abbreviation

    In --muted color with a dotted underline.

    • [title] is in --accent color.
    • [data-title] is in --accent color.
      • :hover displays a tooltip with content set to [data-title] value (using ::after pseudo-element).
  • Bay of the Authie.

    Bay of the Somme.

    See code
    <p>
      Bay of the <abbr>Authie</abbr>.
    </p>
    <p>
      Bay of the <abbr data-title="The Somme is a river in Picardy, France">Somme</abbr>.
    </p>

    Since tooltips generated by browsers are not stylable, [data-title] attribute needs to be used instead of [title] to use CSS tooltips created by matcha.css.

    Styling and emphasis

    <b> Bold

    In bold.

  • Fort-Mahon-Plage
    See code
    <b>Fort-Mahon-Plage</b>

    <i> Italic

    In italic.

  • Crécy-en-Ponthieu
    See code
    <i>Crécy-en-Ponthieu</i>

    <u> Underline

    Is underlined.

    • > u has a double underline.
  • Saint-Valery-sur-Somme

    Fontaine-sur-Somme

    See code
    <p>
      <u>Saint-Valery-sur-Somme</u>
    </p>
    <p>
      <u><u>Fontaine-sur-Somme</u></u>
    </p>

    <s> Strikethrough

    Has a line through.

    • > s has a double line through.
  • Le Crotoy

    Estrées-sur-Noye

    See code
    <p>
      <s>Le Crotoy</s>
    </p>
    <p>
      <s><s>Estrées-sur-Noye</s></s>
    </p>

    <q> Quotation

    In italic and surrounded by guillemets.

  • Noyelles-sur-Mer
    See code
    <q>Noyelles-sur-Mer</q>

    <cite> Citation

    In italic and underlined.

  • Ribemont-sur-Ancre
    See code
    <cite>Ribemont-sur-Ancre</cite>

    <dfn> Definition

    In italic and semi-bold.

  • Rosières-en-Santerre
    See code
    <dfn>Rosières-en-Santerre</dfn>

    <em> Emphasis

    In italic and semi-bold.

  • Neuville-au-Bois
    See code
    <em>Neuville-au-Bois</em>

    <strong> Strong importance

    In italic and bold.

  • Montauban-de-Picardie
    See code
    <strong>Montauban-de-Picardie</strong>

    <small> Smaller text

    In smaller font size.

  • Mers-les-Bains
    See code
    <small>Mers-les-Bains</small>

    Annotations

    <ruby> Ruby

    <rp> Ruby fallback parenthesis

    <rt> Ruby text

    In --muted color.

  • 亚眠(Amiens)
    See code
    <ruby>亚眠<rp>(</rp><rt>Amiens</rt><rp>)</rp> </ruby>

    <sup> Superscript

    In superscript.

  • Cayeux sur-Mer
    See code
    Cayeux <sup>sur-Mer</sup>

    <sub> Subscript

    In subscript.

  • Saulchoy sous-Poix
    See code
    Saulchoy <sub>sous-Poix</sub>

    <mark> Marked text

    In --active color and with a background.

  • Saint-Aubin-Rivière
    See code
    <mark>Saint-Aubin-Rivière</mark>

    <ins> Inserted text

    In --success color with a background and is underlined.

  • Longpré-les-Corps-Saints
    See code
    <ins>Longpré-les-Corps-Saints</ins>

    <del> Deleted text

    In --danger color and with a background and a line through.

  • Montigny-sur-l'Hallue
    See code
    <del>Montigny-sur-l'Hallue</del>

    Computing

    <code> Code

    In monospaced font and with a background.

  • Le Plessier-Rozainvillers
    See code
    <code>Le Plessier-Rozainvillers</code>

    <var> Variable

    In monospaced font in --accent color and with a background.

  • Fort-de-France
    See code
    <var>Fort-de-France</var>

    <kbd> Keyboard

    In monospaced font and with a background.

  • Port-le-Grand
    See code
    <kbd>Port-le-Grand</kbd>

    <samp> Sample output

    In monospaced font and with an outline.

  • Regnière-Écluse
    See code
    <samp>Regnière-Écluse</samp>

    <output> Output

    Has dashed borders.

    The entire content is selected upon click on supported browsers.

  • Hardecour-aux-Bois
    See code
    <output>Hardecour-aux-Bois</output>

    Forms

    <form> Form

    Has rounded corners, a background, and an automatic overflow.

    • code has a ◉ --bg-subtle background.
  • See code
    <form method="get" onsubmit="event.preventDefault()">
      <label>
        Remove OS chip ?
        <small>
          Caution: Handle with Care !<br>
          Removal of OS chip will result in death.
        </small>
        <button type="reset">Confirm</button>
      </label>
    </form>

    <button> Button

    Has borders with rounded corners.

    • :disabled is half-opacity and has a not-allowed cursor.
    • :hover has background.
    • [type="submit"] has --accent borders.
    • [type="reset"] has --danger borders.
  • See code
    <form method="get" onsubmit="event.preventDefault()">
      <button type="button">Button</button>
      <button type="submit">Submit</button>
      <button type="reset">Reset</button>
      <button type="button" disabled>Disabled</button>
    </form>

    Utility color classes from matcha.css can be used to easily change the filling color.

  • See code
    <form method="get" onsubmit="event.preventDefault()">
      <button class="default">Button</button>
      <button class="variant">Button</button>
      <button class="active">Button</button>
      <button class="accent">Button</button>
      <button class="success">Button</button>
      <button class="attention">Button</button>
      <button class="severe">Button</button>
      <button class="danger">Button</button>
    </form>

    <label> Label

    • > small is in --muted color.
      • ::before has content: "\n" to force a line break.
      • ::after has content: "\n" to force a line break.
    • :has(> :is(input, textarea, button)) have a pointer cursor.
    • :has(> :is(input, textarea, select, button):disabled) are in --muted color and have a not-allowed cursor.
    • :has(> :is(input, textarea, select):required) automatically prepend a --danger asterisk (*).
  • See code
    <form method="get" onsubmit="event.preventDefault()">
      <label>
        Why did humans disappear from the world ?
        <small>To whom  does the true voice speak, I ask.</small>
        <select>
          <option>Because of a black disease.</option>
          <option>Because their lives are short.</option>
        </select>
      </label>
      <label>
        How can humans extends their lives ?
        <small>To whom does the true form show itself, I ask.</small>
        <select disabled>
          <option>By separating body from soul.</option>
          <option>By acquiring leaves of the sacred tree.</option>
        </select>
      </label>
      <label>
        What is the destination of souls ?
        <small>I ask.</small>
        <select required>
          <option>They are placed in their corresponding shells.</option>
          <option>They are in the promised land, bursting with light.</option>
        </select>
      </label>
    </form>

    It's advisable to utilize the <label><input></label> pattern so matcha.css can automatically detect whether the <input> is required or not (which is not possible when using the <label for><input> pattern instead).

    <fieldset> Field set

    Has rounded corners.

    <legend> Field set legend

    In semi-bold.

  • Character selection
    See code
    <form method="get" onsubmit="event.preventDefault()">
      <fieldset>
        <legend>Character selection</legend>
        <label>
          <input type="radio" name="fieldset-example" value="2B">
          2B
        </label>
        <label>
          <input type="radio" name="fieldset-example" value="9S">
          9S
        </label>
        <label>
          <input type="radio" name="fieldset-example" value="A2">
          A2
        </label>
      </fieldset>
    </form>

    Utility color classes from matcha.css can be used to easily change the color.

  • Character selection
    See code
    <form method="get" onsubmit="event.preventDefault()">
      <fieldset class="accent">
        <legend>Character selection</legend>
        <label>
          <input type="radio" name="fieldset-example" value="2B">
          2B
        </label>
        <label>
          <input type="radio" name="fieldset-example" value="2P">
          2P
        </label>
      </fieldset>
    </form>

    <input> Input

    Depends on <input type>.

    • :disabled has a muted background and a not-allowed cursor.
  • *No validation except the ones operated by the browser are performed.

    Textual
    Temporal
    Special
    Radio & Checkbox
    Button
    See code
    <form method="get" onsubmit="event.preventDefault()">
      <fieldset>
        <legend>Textual</legend>
        <label>
          Text:
          <input type="text" placeholder="Operator 6O">
        </label>
        <label>
          Number:
          <input type="number" placeholder="1.22474487139">
        </label>
        <label>
          Password:
          <input type="password" placeholder="●●●●●●●●">
        </label>
        <label>
          Email:
          <input type="email" placeholder="no-reply@yorha.org">
        </label>
        <label>
          URL:
          <input type="url" placeholder="https://yorha.org">
        </label>
        <label>
          Telephone:
          <input type="tel" placeholder="167-82-57-83">
        </label>
      </fieldset>
      <fieldset>
        <legend>Temporal</legend>
        <label>
          Datetime local:
          <input type="datetime-local">
        </label>
        <label>
          Date:
          <input type="date">
        </label>
        <label>
          Month:
          <input type="month">
        </label>
        <label>
          Week:
          <input type="week">
        </label>
        <label>
          Time:
          <input type="time">
        </label>
      </fieldset>
      <fieldset>
        <legend>Special</legend>
        <label>
          Range:
          <input type="range">
        </label>
        <label>
          Search:
          <input type="search" placeholder="Lunar tear">
        </label>
        <label>
          Color:
          <input type="color">
        </label>
        <label>
          File:
          <input type="file">
        </label>
      </fieldset>
      <fieldset>
        <legend>Radio &amp; Checkbox</legend>
        <div>
          <label>
            <input type="radio" name="input-radio-example" value="2B">
            2B
          </label>
          <label>
            <input type="radio" name="input-radio-example" value="9S">
            9S
          </label>
          <label>
            <input type="radio" name="input-radio-example" value="A2" checked>
            A2
          </label>
          <label>
            <input type="radio" name="input-radio-example" value="2P" disabled>
            2P
          </label>
        </div>
        <div>
          <label>
            <input type="checkbox" name="input-checkbox-example" value="Nier" checked>
            Nier
          </label>
          <label>
            <input type="checkbox" name="input-checkbox-example" value="Emil">
            Emil
          </label>
          <label>
            <input type="checkbox" name="input-checkbox-example" value="Kainé">
            Kainé
          </label>
          <label>
            <input type="checkbox" name="input-checkbox-example" value="Weiss" disabled>
            Weiss
          </label>
        </div>
      </fieldset>
      <fieldset>
        <legend>Button</legend>
        <label>
          <input type="image" src="https://upload.wikimedia.org/wikipedia/commons/b/b4/Yoko_Taro_cropped.jpg" alt="(Image)">
        </label>
        <label>
          <input type="button" value="Button">
        </label>
        <label>
          <input type="reset" value="Reset">
        </label>
        <label>
          <input type="submit" value="Submit">
        </label>
      </fieldset>
    </form>

    matcha.css provides rules that automatically colors the borders of inputs based on their validation status.

    <select> Selection input

    Has rounded corners.

    • :disabled has a muted background and a not-allowed cursor.
  • See code
    <form method="get" onsubmit="event.preventDefault()">
      <label>
        Select a location:
        <select>
          <optgroup label="Earth">
            <option>City ruins</option>
            <option>Desert</option>
            <option>Forest</option>
            <option disabled>Amusement park</option>
            <option>Alien Mothership</option>
          </optgroup>
          <optgroup label="Moon" disabled>
            <option>Bunker</option>
          </optgroup>
        </select>
      </label>
    </form>

    <textarea> Text area input

    Has rounded corners, and resize is disabled by default.

    • :disabled has a muted background and a not-allowed cursor.
  • See code
    <form method="get" onsubmit="event.preventDefault()">
      <label>
        Remembrance:
        <small>Look at my memory.</small>
        <textarea rows="4">The tree did not feel sadness at this; grief was an emotion beyond its comprehension.
    It did, however, have the distinct feeling that something was missing.
        </textarea>
      </label>
    </form>

    Bars

    <progress> Progress bar

    Has currentColor as filling color.

  • See code
    <progress max="100" value="50"></progress>

    Utility classes from matcha.css can be used to easily change the filling color.

  • See code
    <progress class="variant" max="100" value="14"></progress>
    <progress class="active" max="100" value="28"></progress>
    <progress class="accent" max="100" value="42"></progress>
    <progress class="success" max="100" value="57"></progress>
    <progress class="attention" max="100" value="71"></progress>
    <progress class="severe" max="100" value="85"></progress>
    <progress class="danger" max="100" value="100"></progress>

    <meter> Meter bar

    Has filling color depending on the current value compared to low, high, and optimum values.

  • See code
    <meter min="0" max="100" low="40" high="70" optimum="99" value="33"></meter>
    <meter min="0" max="100" low="40" high="70" optimum="99" value="66"></meter>
    <meter min="0" max="100" low="40" high="70" optimum="99" value="100"></meter>

    Lists

    <dl> Description list

    <dt> Description term

    In semi-bold.

    <dd> Description details

    Has left padding.

  • The Wired
    An ever developing, evolving virtual world similar to the real world's current internet of the early 2000s. It can be accessed through a Navi. It is an interconnected network, similar to Internet/World Wide Web.
    See code
    <dl>
      <dt>The Wired</dt>
      <dd>
        An ever developing, evolving virtual world similar to the real world's current internet of the early 2000s.
        It can be accessed through a Navi.
        It is an interconnected network, similar to Internet/World Wide Web.
      </dd>
    </dl>

    <ul> Unordered list

    <li> List item

    Has left padding.

    • EVA-00: Rei Ayanami
    • EVA-01: Shinji Ikari
    • EVA-02: Asuka Langley Sohryu
    • EVA-03: Tōji Suzuhara
    See code
    <ul>
      <li>EVA-00: Rei Ayanami</li>
      <li>EVA-01: Shinji Ikari</li>
      <li>EVA-02: Asuka Langley Sohryu</li>
      <li>EVA-03: Tōji Suzuhara</li>
    </ul>

    <ol> Ordered list

    <li> List item

    Has left padding.

    1. Adam
    2. Lilith
    3. Tabris
    4. Lilin
    See code
    <ol>
      <li>Adam</li>
      <li>Lilith</li>
      <li>Tabris</li>
      <li>Lilin</li>
    </ol>

    Tables

    <table> Table

    Has collapsed borders.

    If parent has a set width, it has an automatic overflow. If not, it can be wrapped within a .table-responsive container.

    <caption> Table caption

    In --muted color under table.

    <tr> Table row

    If parent is <tbody>:

    • :nth-child(2n) have a background.

    <th> Table header

    Has a background and is text centered in bold.

    <td> Table data

    If parent is <table class="center">:

    • & is text centered.
  • Table of type effectiveness
    ×Defending type
    🍃🔥💧
    Attacking type
    🍃½½21
    🔥2½½1
    💧½2½1
    ½12½
    See code
    <div class="table-responsive">
      <table class="center">
        <caption>Table of type effectiveness</caption>
        <thead>
          <tr><th colspan="2" rowspan="2">×</th><th colspan="4">Defending type</th></tr>
          <tr><th>🍃</th><th>🔥</th><th>💧</th><th></th></tr>
        </thead>
        <tbody>
          <tr><th rowspan="4"><div>Attacking type</div></th><th>🍃</th><td>½</td><td>½</td><td>2</td><td>1</td></tr>
          <tr><th>🔥</th><td>2</td><td>½</td><td>½</td><td>1</td></tr>
          <tr><th>💧</th><td>½</td><td>2</td><td>½</td><td>1</td></tr>
          <tr><th></th><td>½</td><td>1</td><td>2</td><td>½</td></tr>
        </tbody>
      </table>
    </div>

    Media

    <img> Image

    Has rounded corners.

  • Samoyed in Snow
    See code
    <img loading="lazy" src="https://upload.wikimedia.org/wikipedia/commons/d/d6/Lulu_-_Samoyed_in_Snow.jpg" alt="Samoyed in Snow">

    <video> Video

    Has rounded corners.

  • See code
    <video loading="lazy" controls muted poster="//upload.wikimedia.org/wikipedia/commons/thumb/d/da/Paris_lockdown_-_Vimeo.webm/800px--Paris_lockdown_-_Vimeo.webm.jpg">
      <source src="https://upload.wikimedia.org/wikipedia/commons/d/da/Paris_lockdown_-_Vimeo.webm" type="video/mp4">
    </video>

    <iframe> Inline frame

    Has rounded corners without borders.

  • See code
    <iframe loading="lazy" title="example.com" height="420" src="https://example.com" sandbox></iframe>

    Extras


    Layouts

    matcha.css provides the option to incorporate a layout for your document.

    Utilizing a layout may necessitate a refactor of your document. Additionally, if you choose to discontinue using matcha.css in the future, you may need to refactor your document again.

    Simple layout

    Add .layout-simple to an element to enable this layout.

    Required structure:
    Elements marked with * are required

    • .layout-simple*
      • > header:first-of-type
      • > main:only-of-type
      • > aside:nth-of-type(1), > aside:nth-of-type(2)
        • > nav:only-child
          • > ul
      • > footer:last-of-type
    @media (default)
    <header>
    <main>
    @media (min-width: 960px)
    <header>
    <aside>
    <main>
    @media (min-width: 1280px)
    <header>
    <aside>
    <aside>
    <main>

    The @media (default) will hide aside:nth-of-type(1) on small screens, but it can be made visible again by adding a data-expand attribute. To make it collapsible, use a data-expandable attribute instead. The latter accepts a value to customize the text (e.g. ☰ Menu).

    Utilities

    matcha.css provides utility classes for added convenience.

    Utility classes requires that you patch your document to add classes which make it harder to eventually opt-out of matcha.css in the future.

    While not neccessarily a bad thing per se, it does diverge from the original intent of matcha.css which aims to be semantic-based. Use these only if you plan to stay with matcha.css for the long run.

    Colors, border colors and backgrounds

    Use one of the following classes to alter the element's color, border-color and background-color.

    • Color
      • .default is in --default color.
      • .muted is in --muted color.
      • .accent is in --accent color.
      • .active is in --active color.
      • .variant is in --variant color.
      • .success is in --success color.
      • .attention is in --attention color.
      • .severe is in --severe color.
      • .danger is in --danger color.
    • Border color
      • .bd-default has a ◉ --default border.
      • .bd-muted has a ◉ --muted border.
      • .bd-accent has a ◉ --accent border.
      • .bd-active has a ◉ --active border.
      • .bd-variant has a ◉ --variant border.
      • .bd-success has a ◉ --success border.
      • .bd-attention has a ◉ --attention border.
      • .bd-severe has a ◉ --severe border.
      • .bd-danger has a ◉ --danger border.
    • Background
      • .bg-default has a ◉ --bg-default background.
      • .bg-muted has a ◉ --bg-muted background.
      • .bg-accent has a ◉ --bg-accent background.
      • .bg-active has a ◉ --bg-active background.
      • .bg-variant has a ◉ --bg-variant background.
      • .bg-success has a ◉ --bg-success background.
      • .bg-attention has a ◉ --bg-attention background.
      • .bg-severe has a ◉ --bg-severe background.
      • .bg-danger has a ◉ --bg-danger background.
    • Foreground
      • .fg-default has a ◉ --default background.
      • .fg-muted has a ◉ --muted background.
      • .fg-accent has a ◉ --accent background.
      • .fg-active has a ◉ --active background.
      • .fg-variant has a ◉ --variant background.
      • .fg-success has a ◉ --success background.
      • .fg-attention has a ◉ --attention background.
      • .fg-severe has a ◉ --severe background.
      • .fg-danger has a ◉ --danger background.

    Flashs

    Flash blocks can be used to draw attention. They can be combined with any color class.

    • .flash styles the element as a flash block.
    • .flash.foreground styles the element as a flash block with a foreground.
  • Default
    Default foreground
    Muted
    Muted foreground
    Accent
    Accent foreground
    Active
    Active foreground
    Variant
    Variant foreground
    Success
    Success foreground
    Attention
    Attention foreground
    Severe
    Severe foreground
    Danger
    Danger foreground
    See code
    <div class="flash default">Default</div>
    <div class="flash fg-default">Default foreground</div>
    <div class="flash muted">Muted</div>
    <div class="flash fg-muted">Muted foreground</div>
    <div class="flash accent">Accent</div>
    <div class="flash fg-accent">Accent foreground</div>
    <div class="flash active">Active</div>
    <div class="flash fg-active">Active foreground</div>
    <div class="flash variant">Variant</div>
    <div class="flash fg-variant">Variant foreground</div>
    <div class="flash success">Success</div>
    <div class="flash fg-success">Success foreground</div>
    <div class="flash attention">Attention</div>
    <div class="flash fg-attention">Attention foreground</div>
    <div class="flash severe">Severe</div>
    <div class="flash fg-severe">Severe foreground</div>
    <div class="flash danger">Danger</div>
    <div class="flash fg-danger">Danger foreground</div>

    Classes

    While matcha.css is mostly intended to be used along with semantic styling, it still provides a subset of utility classes for added convenience.

    matcha.css does not aim to become a fully-fledged CSS framework.

    Consider using (or switching to) a utility-first CSS framework if you find the provided utility classes lacking or too limited.

    Utilities classes

    • Text weight, style, decoration, transform, align, and font.
      • .bold sets font-weight: bold;
      • .semibold sets font-weight: 600;
      • .italic sets font-style: italic;
      • .underline sets text-decoration: underline;
      • .strikethrough sets text-decoration: line-through;
      • .uppercase sets text-transform: uppercase;
      • .lowercase sets text-transform: lowercase;
      • .capitalize sets text-transform: capitalize;
      • .centered sets text-align: center;
      • .justified sets text-align: justify;
      • .monospace sets font-family: var(--mono);
    • Text size
      • .smaller sets font-size: .85rem;
      • .small sets font-size: .875rem;
      • .normal sets font-size: 1rem;
      • .large sets font-size: 1.25rem;
      • .larger sets font-size: 1.5rem;
    • Positioning
      • .relative sets position: relative;
      • .fixed sets position: fixed;
      • .absolute sets position: absolute;
      • .sticky sets position: sticky;
    • Display
      • .hidden sets display: none;
      • .inline sets display: inline;
        • &.block sets display: inline-block;
        • &.flex sets display: inline-flex;
      • .block sets display: block;
      • .flex sets display: flex;
        • &.row sets flex-direction: row;
        • &.column sets flex-direction: column;
        • &.wrap sets flex-wrap: wrap;
        • &.no-wrap sets flex-wrap: no-wrap;
        • &.reverse
          • &.row sets flex-direction: row-reverse;
          • &.column sets flex-direction: column-reverse;
          • &.wrap sets flex-wrap: wrap-reverse;
      • .contents sets display: contents;
    • Flex display
      • .flex
        • &.start sets justify-content: flex-start;
        • &.end sets justify-content: flex-end;
        • &.center sets justify-content: center;
        • &.space-between sets justify-content: space-between;
        • &.space-around sets justify-content: space-around;
        • &.space-evenly sets justify-content: space-evenly;
        • &.stretch sets justify-content: stretch;
        • &.align-start sets align-items: flex-start;
        • &.align-end sets align-items: flex-end;
        • &.align-center sets align-items: center;
        • &.align-stretch sets align-items: stretch;
      • .grow sets flex-grow: 1;
      • .shrink sets flex-shrink: 1;
    • Overflow
      • .overflow sets overflow: auto;
      • .overflow-x sets overflow-x: auto;
      • .overflow-y sets overflow-y: auto;
      • .no-overflow sets overflow: hidden;
    • Cursor
      • .pointer sets cursor: pointer;
      • .wait sets cursor: wait;
      • .not-allowed sets cursor: not-allowed;
    • User selection
      • .select-all sets user-select: all;
      • .no-select sets user-select: none;
    • Interactivity
      • .events sets pointer-events: auto;
      • .no-events sets pointer-events: none;
    • Sizing and dimensions
      • .width sets width: 100%;
      • .height sets height: 100%;
      • .border-box sets box-sizing: border-box;
      • .content-box sets box-sizing: content-box;
    • Resizing
      • .resize sets resize: both;
      • .resize-x sets resize: horizontal;
      • .resize-y sets resize: vertical;
      • .no-resize sets resize: none;
    • Miscellaneous
      • .no-shadow sets box-shadow: none;
      • .shadow sets box-shadow: var(--shadow);
    • <svg> fill and stroke
      • svg.fill-current sets fill: currentColor;
      • svg.no-fill sets fill: none;
      • svg.stroke-current sets stroke: currentColor;
      • svg.no-stroke sets stroke: none;

    Spacing classes

    The following classes are numbered and the following values are supported in place of *:
    0, .125, .25, .5, .75, 1, 1.25, 1.5, 1.75, 2, 3, 4,

    • Margins
      • .m-* sets margin: *rem;
      • .mx-* sets margin-left: *rem; margin-right: *rem;
      • .my-* sets margin-top: *rem; margin-bottom: *rem;
      • .mt-* sets margin-top: *rem;
      • .mb-* sets margin-bottom: *rem;
      • .ml-* sets margin-left: *rem;
      • .mr-* sets margin-right: *rem;
      • &
        • &.spacing-x-* > * + * sets margin-left: *rem;
        • &.spacing-y-* > * + * sets margin-top: *rem;
    • Paddings
      • .p-* sets padding: *rem;
      • .px-* sets padding-left: *rem; padding-right: *rem;
      • .py-* sets padding-top: *rem; padding-bottom: *rem;
      • .pt-* sets padding-top: *rem;
      • .pb-* sets padding-bottom: *rem;
      • .pl-* sets padding-left: *rem;
      • .pr-* sets padding-right: *rem;

    Synergies

    Including utilities classes offers additional styling to the following:

    Form validation

    matcha.css provides rules that automatically colors the borders of inputs based on their validation status.

    • :user-valid has --success borders.
    • :user-invalid has --danger borders.
  • *No validation except the ones operated by the browser are performed.

    See code
    <form method="get" onsubmit="event.preventDefault()">
      <label>
        URL:
        <small>Type an URL below. If it is valid, it'll appear in <code><span class="success"></span> --success</code> while it'll appear in <code><span class="danger"></span> --danger</code> if not.</small>
        <input required type="url" placeholder="https://example.com">
      </label>
    </form>

    Syntax highlighting

    matcha.css provides syntax highlighting classes that respect @media (prefers-color-scheme) and are fully compatible with highlight.js library.

    Code

  • ;;; *************************************************************************
    ;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
    ;;; All rights reserved.
    
    (defun with-augmented-environment-internal (env functions macros)
      (dolist (f functions)
        (push (list* f 'function (gensym)) env))
      (dolist (m macros)
        (push (list* (car m) 'ccl::macro (cadr m)) env))
      env)
    See code
    <pre><!--
       --><code><span class="hljs-comment">;;; *************************************************************************</span>
    <span class="hljs-comment">;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.</span>
    <span class="hljs-comment">;;; All rights reserved.</span>
    
    (<span class="hljs-name">defun</span> with-augmented-environment-internal (<span class="hljs-name">env</span> functions macros)
      (<span class="hljs-name">dolist</span> (<span class="hljs-name">f</span> functions)
    (<span class="hljs-name">push</span> (<span class="hljs-name">list*</span> f 'function (<span class="hljs-name">gensym</span>)) env))
      (<span class="hljs-name">dolist</span> (<span class="hljs-name">m</span> macros)
    (<span class="hljs-name">push</span> (<span class="hljs-name">list*</span> (<span class="hljs-name">car</span> m) 'ccl:<span class="hljs-symbol">:macro</span> (<span class="hljs-name">cadr</span> m)) env))
      env)</code><!--
      --></pre>

    Diff

  • @@ -7,1 +7,1 @@
    
    +(dolist (f functions)
    -(dolist (m macros)
    See code
    <pre><!--
       --><code><span class="hljs-meta">@@ -7,1 +7,1 @@</span>
    
    <span class="hljs-addition">+(dolist (f functions)</span>
    <span class="hljs-deletion">-(dolist (m macros)</span></code><!--
      --></pre>

    Markdown

  • # NAVI
    
    The **Knowledge Navigator**, or **NAVI** for short, is a series of high-powered computers designed for users to easily access the [Wired](https://lain.wiki/wiki/The_Wired).
    
    While some aren't pretty to look at, they are unmistakably powerful. NAVIs can come in almost any shape or form.
    
    ## List of NAVIs
    
    - Alice's NAVI
    - Lain's NAVI
    
    > This was copied from lain.wiki/wiki/NAVI
    See code
    <pre><!--
    --><code><span class="hljs-section"># NAVI</span>
    
    The <span class="hljs-strong">**Knowledge Navigator**</span>, or <span class="hljs-strong">**NAVI**</span> for short, is a series of high-powered computers designed for users to easily access the [<span class="hljs-string">Wired</span>](<span class="hljs-link">https://lain.wiki/wiki/The_Wired</span>).
    
    While some aren't pretty to look at, they are unmistakably powerful. NAVIs can come in almost any shape or form.
    
    <span class="hljs-section">## List of NAVIs</span>
    
    <span class="hljs-bullet">-</span> Alice's NAVI
    <span class="hljs-bullet">-</span> Lain's NAVI
    
    <span class="hljs-quote">&gt; This was copied from lain.wiki/wiki/NAVI</span></code><!--
    --></pre>

    HTML/XML

  • <main id="navi">
      <div class="ui" data-version="4.0">
        <article>mebious.co.uk</article>
        <article>PHANTOMa</article>
        <!-- ... -->
      </div>
    </main>
    See code
    <pre><!--
    --><code><span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"navi"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ui"</span> <span class="hljs-attr">data-version</span>=<span class="hljs-string">"4.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">article</span>&gt;</span>mebious.co.uk<span class="hljs-tag">&lt;/<span class="hljs-name">article</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">article</span>&gt;</span>PHANTOMa<span class="hljs-tag">&lt;/<span class="hljs-name">article</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- ... --&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></code><!--
    --></pre>

    CSS

  • #navi .ui[data-version="4.0"]:only-child {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      width: 100%;
    }
    See code
    <pre><!--
    --><code><span class="hljs-selector-id">#navi</span> <span class="hljs-selector-class">.ui</span><span class="hljs-selector-attr">[data-version=<span class="hljs-string">"4.0"</span>]</span><span class="hljs-selector-pseudo">:only-child</span> {
      <span class="hljs-attribute">display</span>: flex;
      <span class="hljs-attribute">flex-wrap</span>: wrap;
      <span class="hljs-attribute">justify-content</span>: space-between;
      <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
    }</code><!--
    --></pre>

    Code editor

    matcha.css provides classes that can be used to create a simple code editor with syntax highlighting.

    Required structure:
    Elements marked with * are required.

    • .editor*
      • > textarea*
      • > div.highlight*
  • See code
    <div class="editor">
      <textarea rows="6">// This element is editable and highlights TypeScript code
    import * as mizu from "https://mizu.sh/mizu.js"
    
    const { version } = mizu
    console.log(`🌊 mizu.js version: ${version}`)
    </textarea>
      <div class="highlight"></div>
    </div>
    <script>
    {
      /// <reference lib="dom" />
      const editor = document.currentScript.previousElementSibling
      const textarea = editor.querySelector("textarea")
      const highlight = editor.querySelector(".highlight")
      textarea.addEventListener("input", () => coloration(textarea.value))
      textarea.addEventListener("scroll", function () {
        highlight.scrollTop = this.scrollTop
        highlight.scrollLeft = this.scrollLeft
      })
      function coloration(value) {
        highlight.innerHTML = hljs.highlight(value, { language: "typescript" }).value
      }
      coloration(textarea.value)
      
    }
    </script>

    These extra styles does not actually perform syntax highlighting, it is only for styling the code editor. It is required to include a syntax highlighting library like highlight.js. See the example code above for a simple implementation.

    Use with matcha.css's syntax highlighting classes for a extra synergy!

    Istanbul coverage reports

    matcha.css provides classes that respect @media (prefers-color-scheme) and are compatible with istanbul.js-like coverage reports.

  • 01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
     
     
    x1
     
     
    x8
    x234
    x234
    x78
    x303
    x101
     
     
     
     
     
    x78
     
     
    
    
    
    
    
    
    
    
    
    I
    
    
    
    
    
    
    
    
    
    
    
    
    /**
     * https://github.com/lowlighter/libs
     * @author Simon Lecoq (lowlighter)
     */
    export class Context<T extends record> extends EventTarget {
    
      /** Dispatch event. */
      #dispatch(type: string, detail: Omit<detail, "type">) {
        Object.assign(detail, { type })
        this.dispatchEvent(new Context.Event(type, { detail }))
        if ((type === "set") || (type === "delete") || (type === "call")) {
          this.dispatchEvent(new Context.Event("change", { detail }))
        }
        for (const child of this.#children) {
          if (!Reflect.has(child.#target, detail.path[0] ?? detail.property)) {
            child.#dispatch(type, detail)
          }
        }
      }
    
    }

    Use with matcha.css's syntax highlighting classes for a extra synergy!

    Unstyled

    These elements are listed for completeness but are left unstyled by matcha.css.

    Expand

    Document

    <title> Document title

    <meta> Metadata

    <base> Document base url

    <style> Style

    Generic

    <div> Content division

    <span> Content span

    Sectioning

    <address> Contact address

    Breaks

    <br> Line break

    <wbr> Word break

    <bdi> Bidirectional isolate

    <bdo> Bidirectional override

    Computing

    <data> Data

    <time> Time

    Forms

    <optgroup> Option group

    <option> Option

    <datalist> Data list

    Tables

    <thead> Table head

    <tbody> Table body

    <tfoot> Table foot

    Media

    <audio> Audio player

    <track> Text track

    <svg> Scalable Vector Graphics

    <picture> Picture

    <map> Image map

    <area> Image area

    <source> Media source

    <math> Mathematical markup

    <portal> Portal

    <embed> External content

    <object> External object

    Components

    <template> Content template

    <slot> Content slot

    Scripting

    <canvas> Graphics canvas

    <script> Script

    <noscript> Script fallback text