Skip to content

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.

ArgentinaJapanBrazilScotlandSouth Africa
pennant · Pennant
ArgentinaJapanBrazilScotlandSouth Africa
rect · Rectangle 4:3
ArgentinaJapanBrazilScotlandSouth Africa
square · Square
ArgentinaJapanBrazilScotlandSouth Africa
circle · Circle
ShapeCanvasArtworkFrame
pennant66 × 72flag-icons 1x1Golden bar, pointed bottom, 3 px border
rect64 × 48flag-icons 4x32 px border, 2 px corner radius
square48 × 48flag-icons 1x12 px border, 2 px corner radius
circle48 × 48flag-icons 1x1Circular 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 ​

FormatPennant (default)Other shapes
CSS classespennants/css, class pn pn-arpennants/css/rect, class pn-rect pn-ar
CSS from CDNimport 'pennants/css/cdn'import 'pennants/css/rect/cdn'
SVG filespennants/svg/pennant/ar.svgpennants/svg/rect/ar.svg
PNG filespng/pennant/1x/ and png/pennant/2x/png/rect/1x/ (1x only)
SVG spritepennants/sprite (sprite/pennant.svg)not published, see below
URLspennantUrl('ar')pennantUrl('ar', { shape: 'rect' })
Lazy SVGloadFlag('ar')loadFlag('ar', { shape: 'circle' })
Fetch modefetchPennant('ar')fetchPennant('ar', { shape: 'square' })
Static artworkrenderFlag(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.

js
import 'pennants/css';
import 'pennants/css/circle';
html
<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).

js
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' });
jsx
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.

js
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 ​

js
import { SHAPES, isShape, toShape } from 'pennants';

SHAPES; // ['pennant', 'rect', 'square', 'circle']
isShape('circle'); // true
toShape(userInput); // throws RangeError for anything else

Components 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:

sh
npm ci
npm run generate   # writes sprite/rect.svg, sprite/square.svg and sprite/circle.svg

Symbol ids are pn-<code> in every sprite; the file name selects the shape.

MIT licensed. Flag artwork from flag-icons (MIT).