Barcode (1D)
FreeCode 128, EAN-13 and EAN-8 rendered as SVG from a real encoder: mod-103 and mod-10 check characters computed rather than trusted, EAN-13's leading digit carried in the left-half parity, subset-C packing so a long serial fits the label, spec quiet zones, and a module width snapped to whole device pixels. Refuses to draw what cannot scan, and says why.
Complexity tier: Primitive Presents a value: held to semantic markup and contrast, with its right-to-left and print gaps recorded and the right-to-left debt allowed only to shrink.
import { SvBarcode1dComponent } from '@styloviz/barcode-1d';Demo & usage
Basic usage
Usage example — open the gallery for the full interactive demo.
An interactive demo for this component lives in the gallery.
Open live demoMore examples
Code 128 with a long serial
Subset C packs two digits into one symbol character, so the printed symbol is about half as wide as a subset-B-only encoder would produce.
<sv-barcode-1d value="SN00219874553301" symbology="code128" />
Inspect — what was actually encoded
<sv-barcode-1d variant="inspect" value="4006381333931" symbology="ean13" />
Bare — no human-readable line
<sv-barcode-1d variant="bare" value="SHIP-4471" symbology="code128" [requestedModuleWidth]="3" />
Handle a refusal
A value that cannot be encoded renders the reason instead of a picture. Listen for it if the value comes from user input.
<sv-barcode-1d [value]="sku()" symbology="ean13" (encodeError)="onEncodeError($event)" />
Printing: pin the X-dimension, not the pixels
A barcode is correct in modules and scannable in millimetres. The X-dimension — the width of one module on paper — is what ISO/IEC 15416 and GS1 specify, and CSS pixels do not survive a print dialog: "shrink to fit" rescales the symbol and the X-dimension goes with it. printModuleWidthMm pins the printed width so it measures the same whatever the dialog decides. The component also carries its own @media print block for the two other ways print destroys a correct symbol — stripped backgrounds (the white is half the contrast a scanner measures, and the quiet zone is nothing but background) and a page break through the middle.
<!-- EAN-13 at 100% magnification: the nominal 0.33 mm module. --> <sv-barcode-1d value="4006381333931" symbology="ean13" [printModuleWidthMm]="0.33" />
When the symbol is correct and too small to read
Every other check here is arithmetic on modules; this is the one failure that survives all of it. A container that squeezes the module, or a print setting below the floor, produces bars in perfect proportion that will not scan — and the component says so in place and emits the measurements, so a label pipeline can refuse the job rather than print a roll of stickers. Worth knowing why it is reachable at all: the pixel-snap floors at one DEVICE pixel, which at dpr 1 is 0.2646 mm — a hair above EAN's 0.264 mm floor — but at dpr 2 it is half that. A finer screen lets the symbol get physically smaller, so the better display is the one that produces the unscannable label.
<sv-barcode-1d [value]="sku()" symbology="ean13" [requestedModuleWidth]="width()" [devicePixelRatio]="dpr" (scanSizeWarning)="refuseTheJob($event)" />
When to use
- Printing a label, packing slip, shelf tag or ticket that a handheld scanner has to read.
- You have a GTIN, SKU or serial and need the symbol drawn correctly, including the check digit.
- For a 2D code holding a URL or a payload, use the QR Code instead.
Async states
- loading
- error
- retry
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| loading | boolean | false | True while the value to encode is being fetched; shows a skeleton in place of the barcode. |
| error | SvDataError | string | null | null | Load failure, shown as an error panel in place of the content. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`. |
| variant | BarcodeVariant | 'labelled' | Bars with text, bars alone, or bars with the encoder's report. |
| value | string | '' | What to encode. For EAN, with or without the check digit. |
| symbology | BarcodeSymbology | 'code128' | Barcode standard `value` is encoded in: `'code128'`, `'ean13'` or `'ean8'` (check digit computed). |
| requestedModuleWidth | number | 2 | Requested width of one module, in CSS px. Requested, not final — see `moduleWidth`. A module narrower than a whole device pixel antialiases, and a scanner reads the antialiasing as different run widths. |
| devicePixelRatio | number | 1 | Device pixel ratio to snap against. |
| barHeight | number | 64 | Bar height in px, excluding the human-readable text. |
| showQuietZone | boolean | false | Draw the quiet zones as a visible margin outline. For the `inspect` view. The quiet zone is invisible by nature, which is exactly why people lay a barcode flush against a border and cannot see what broke it. |
| printModuleWidthMm | number | 0 | Physical width of one module when printed, in millimetres. `0` leaves the printed size to the browser, which is what an untouched print job does. This is the X-dimension, the quantity ISO/IEC 15416 and GS1 actually specify — and the reason it exists as its own input is that CSS pixels do not survive a print dialog. Pin it and the symbol measures the same on paper whatever "fit to page" decides. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| retry | void | Emitted when the user presses the error panel's "Try again" button (retryable errors only); the host should re-run the failed load. |
| encodeError | string | Emitted whenever the value cannot be encoded, with the reason. |
| scanSizeWarning | SvBarcodeScanSize | Emitted when the symbol's physical size falls below the floor its symbology may be printed at. Carries the measurements, so a label pipeline can refuse the job rather than print a roll of stickers that will not read. |
Customization & theming
- Three symbologies: `code128`, `ean13`, `ean8`.
- Three variants: `labelled` (bars + human-readable line), `bare`, and `inspect` (module count, quiet zones, check character, snapped width and the subset-C saving).
- `requestedModuleWidth` + `devicePixelRatio` (snapped to whole device pixels; `widthAdjusted` says when it moved), `barHeight`, and `showQuietZone` to make the invisible margin visible.
- `encodeError` reports why a value could not be encoded; `loading` / `error` / `retry` for the async shells.
- `printModuleWidthMm` pins the printed X-dimension in millimetres, and the component's own `@media print` block forces `print-color-adjust: exact`, avoids a page break through the symbol, and hides the `inspect` report (a development aid, not part of the label).
- `scanSizeWarning` emits `{ xMm, widthMm, heightMm, magnification, minXMm, belowMinimum }` whenever the symbol falls under its symbology's floor. `svScanSize()` and `SV_BARCODE_MIN_X_MM` are exported for a pipeline that wants to check before rendering.
Best practices
- Do: Leave the quiet zones alone. They are part of the symbol — the scanner uses them to find the edges — not padding you can trim to fit.
- Do: Pass the 12-digit payload and let the component compute the check digit, or pass 13 and let it verify yours.
- Do: Handle `encodeError`: a refusal is a value that needs fixing before it is printed, not a rendering failure.
- Tip: Keep `requestedModuleWidth` at 2 or more for print. The component snaps it to whole device pixels; below one pixel per module no amount of snapping helps.
- Don't: Don't shrink the symbol until it fits. A barcode with the wrong check digit does not fail to scan — it scans as a different number.
- Do: Set `printModuleWidthMm` for anything that gets printed. It is the X-dimension, the only size a scanner has an opinion about, and it is the half of the geometry a CSS pixel cannot express.
- Do: Handle `scanSizeWarning` in a label pipeline. A symbol under the floor is a job to refuse, not a warning to log — the roll of stickers is already printed by the time anyone tries to scan one.
- Don't: Don't assume the print gate is a guarantee. Print quality, ink spread and scanner distance are outside a browser's reach; the component can only make sure the geometry it hands the printer is right.
Accessibility
- The symbol carries an accessible name naming the symbology, the encoded value and the check character — a scanner reads the bars, a person reads the label, and a screen reader gets both.
- A refusal is rendered as text stating what is wrong (e.g. "EAN-13 needs 12 digits; this has 11"), not as an empty box.
- EAN guard bars extend below the digit row, which is how a human recognises the symbol's start, end and midpoint.
- A symbol too small to scan renders a `role="status"` warning stating the measurement and the floor, so the problem is legible rather than left to a failed scan in a warehouse.
Feedback on Barcode (1D)
Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.