Heraldic blazon for Tailwind CSS
In heraldry and heraldic vexillology, a blazon is a formal description of a coat of arms, flag, or similar emblem, from which the reader can reconstruct an accurate image.
Grailwind is a plugin for Tailwind CSS that lets you render coats of arms on your webpages using the ancient language of the heralds.
Note: Grailwind is a light-hearted project at version 0.x, so don't expect perfection. Class names may still change.
Install
Grailwind is a plugin for Tailwind CSS v4.
npm install -D grailwind
Import it after Tailwind in your stylesheet:
@import "tailwindcss"; @import "grailwind";
This adds the heraldic tinctures alongside Tailwind's own colours, so
bg-azure and bg-blue-500 both work.
Strict mode
To commit fully to the bit, import grailwind/strict
instead. The tinctures then replace Tailwind's colours entirely, and
bg-blue-500 no longer exists. This site uses strict mode.
@import "tailwindcss"; @import "grailwind/strict";
Tinctures
Heraldry has two metals and five colours. A tincture on its own sets the background, as
it describes the field in blazon:
<div class="azure">. Everywhere else, use Tailwind's usual prefixes:
text-or, border-sable, and so on.
orgold, metal
argentsilver, metal
gulesred
azureblue
vertgreen
purpurepurple
sableblack
The rule of tincture
Never put a metal on a metal or a colour on a colour, so the design can be read from a distance. Grailwind doesn't enforce this (yet).
The shield
escutcheon gives an element a shield shape. Size it however you like, e.g.
escutcheon w-40.
The top is the chief and the bottom is the base. Left and right are from the point of view of the person holding the shield. Dexter is their right, which is the left as you look at it, and sinister is their left, which to you is the right. It couldn't be simpler.
You'll meet these words in the order of tinctures, in classes like
bend-sinister, and in the named points for placing
charges.
Dividing the field
One class paints a divided field. Any two different tinctures work. The first tincture named goes on the dexter side or in chief.
Dividing for layout
per-pale, per-fess and quarterly divide an
element into equal parts, one child element per part, in blazon order. They're grids, so
they also work for laying out a page. The top of this page uses
md:per-pale.
Bordure
bordure-or, or any other tincture, adds a border.
Ordinaries
The ordinaries are bold geometric shapes drawn over the field. Add a tincture to name
one: fess-or, cross-gules.
Combining
An element can have one ordinary plus a chief. With a chief, the other ordinary and any charges are drawn in the field below it. Ordinaries can go over any field, including a divided one.
Fimbriation
Charges
Charges are child elements inside a charges container, coloured with a
tincture class.
Built-in charges
mulletroundelannuletlozengebilletcrescentfleur-de-lisRoundels have their own names by tincture, so these need no tincture class:
bezantOr
plateArgent
torteauGules
hurtAzure
pelletSable
Arrangement
In a line
in-pale, in-fess and in-bend
put two or three charges in a vertical, horizontal or diagonal line.
Between
between places charges around the ordinary on the shield, whichever it is.
On
on places charges along the ordinary on the shield, whichever it is.
At a named point
Heraldry names nine points on the shield. Put one on a charge to place it there, as in in dexter chief a mullet.
in-dexter-chiefdexter chiefin-chiefmiddle chiefin-sinister-chiefsinister chiefin-honour-pointhonour pointin-fess-pointfess pointin-nombril-pointnombril pointin-dexter-basedexter basein-basemiddle basein-sinister-basesinister base
Sizing
Each arrangement picks a sensible size. To change it, use
charge-size-* with a percentage of the shield's width:
charge-size-15, or any length, like charge-size-[2rem]. On the
charges
container it sizes every charge. On a single charge, just that one.
Your own charges
Any element inside charges gets placed, so you can bring your own.
charge-[url(…)] uses your SVG as a mask, so a tincture class colours it.
The URL is resolved relative to your built stylesheet, and the image must come from the
same site or be served with CORS headers.
An <img> keeps the image's own colours, like a charge
proper.
All together
A divided field, an ordinary, a chief, a bordure, and charges on, between and in chief.
Accessibility
A shield is a picture made of empty elements. Give it a text alternative, ideally its blazon:
<div class="escutcheon azure fess-or" role="img"
aria-label="Azure, a fess Or"></div>
Grailwind uses :has(), CSS masks and CSS nesting, so it needs a current
browser.