Shapes
Every flag comes in four shapes. The pennant is the default and the signature style; the other three use the same artwork and the same 30% darkening border, so they read as one family.
pennant · Pennantrect · Rectangle 4:3square · Squarecircle · Circle| Shape | Canvas | Artwork | Frame |
|---|---|---|---|
pennant | 66 × 72 | flag-icons 1x1 | Golden bar, pointed bottom, 3 px border |
rect | 64 × 48 | flag-icons 4x3 | 2 px border, 2 px corner radius |
square | 48 × 48 | flag-icons 1x1 | 2 px border, 2 px corner radius |
circle | 48 × 48 | flag-icons 1x1 | Circular clip, 2 px ring |
Codes, names and the API are the same for every shape. Only the pennant has the bar, so only the pennant can be themed.
Choosing a shape, per format
| Format | Pennant (default) | Other shapes |
|---|---|---|
| CSS classes | pennants/css, class pn pn-ar | pennants/css/rect, class pn-rect pn-ar |
| CSS from CDN | import 'pennants/css/cdn' | import 'pennants/css/rect/cdn' |
| SVG files | pennants/svg/pennant/ar.svg | pennants/svg/rect/ar.svg |
| PNG files | png/pennant/1x/ and png/pennant/2x/ | png/rect/1x/ (1x only) |
| SVG sprite | pennants/sprite (sprite/pennant.svg) | not published, see below |
| URLs | pennantUrl('ar') | pennantUrl('ar', { shape: 'rect' }) |
| Lazy SVG | loadFlag('ar') | loadFlag('ar', { shape: 'circle' }) |
| Fetch mode | fetchPennant('ar') | fetchPennant('ar', { shape: 'square' }) |
| Static artwork | renderFlag(ar) | renderFlag(ar, { shape: 'circle' }) |
| React | <Pennant code="ar" /> | <Pennant code="ar" shape="circle" /> |
| Web Component | <pennant-flag code="ar"> | <pennant-flag code="ar" shape="rect"> |
CSS classes
Each shape's stylesheet has its own base class: pn (pennant), pn-rect, pn-square and pn-circle. The flag class pn-<code> is the same everywhere, and flag rules are scoped to their base, so you can load several stylesheets and mix shapes on one page.
import 'pennants/css';
import 'pennants/css/circle';<span class="pn pn-ar" role="img" aria-label="Argentina"></span>
<span class="pn-circle pn-ar" role="img" aria-label="Argentina"></span>
<span class="pn-circle pn-jp pn-2x" role="img" aria-label="Japan"></span>Use exactly one base class per element: pn pn-circle pn-ar is undefined. Size helpers (.pn-lg, .pn-2x to .pn-4x) work with every base, and every stylesheet has a /cdn variant (pennants/css/circle/cdn). Each stylesheet you load adds its own cost; see Performance.
Artwork modules
JavaScript modules export artwork ({ code, viewBox, content }), not a framed SVG, so a flag is bundled once however many shapes you render it in. Pick the artwork set the shape is drawn from: 4x3 for rect, 1x1 for the others (SHAPE_ART holds the mapping).
import { renderFlag } from 'pennants';
import ar from 'pennants/art/1x1/ar';
import arWide from 'pennants/art/4x3/ar';
renderFlag(ar); // pennant
renderFlag(ar, { shape: 'circle' });
renderFlag(arWide, { shape: 'rect' });import { PennantSvg } from 'pennants/react';
<PennantSvg art={ar} shape="square" size={24} />;renderFlag is synchronous, which makes it the SSR-friendly option. loadArt(code, { set }) returns the artwork lazily if you want to frame it yourself.
Sizing
Sizes are heights; widths follow the shape's ratio.
import { SHAPE_SIZE } from 'pennants';
import { pennantBox } from 'pennants/react';
SHAPE_SIZE.rect; // { width: 64, height: 48 }
pennantBox(32, 'rect'); // { width: '42.667px', height: '32px' }Each base class sets height: 1em and the width from its shape's ratio.
Validating shape names
import { SHAPES, isShape, toShape } from 'pennants';
SHAPES; // ['pennant', 'rect', 'square', 'circle']
isShape('circle'); // true
toShape(userInput); // throws RangeError for anything elseComponents throw a RangeError for unknown shapes during render; <pennant-flag> fires pennant-error instead. pennantUrl also throws for PNG scale: 2 on any shape other than the pennant, since only pennant PNGs ship at 2x.
Sprites for other shapes
Only sprite/pennant.svg is published to npm, to keep the install small. The other sprites (rect.svg, square.svg, circle.svg) are generated by the build. To get them, clone the repository and run:
npm ci
npm run generate # writes sprite/rect.svg, sprite/square.svg and sprite/circle.svgSymbol ids are pn-<code> in every sprite; the file name selects the shape.