Skip to content

Signature

<quiet-signature> stable since 2.3 form control This component is a form-associated custom element. It will submit its value when given a name and placed inside a <form>.

Allows users to capture signatures by drawing on a canvas or typing their name.

The signature component includes a text field that is always visible for accessibility. This ensures keyboard users can provide their signature by typing their name, while touch/mouse users can draw directly on the canvas.

Drawing and typing are mutually exclusive — starting one clears the other. Typed names are rendered on the canvas using a customizable cursive font, ensuring consistent output regardless of input method.

<quiet-signature name="signature" label="Your signature"></quiet-signature>

Examples Jump to heading

Labels and descriptions Jump to heading

You can use the label and description attributes to provide plain text labels and descriptions for the signature field. If you want to provide HTML, use the label and description slots instead.

By signing, you agree to the terms and conditions.
<quiet-signature name="signature" label="Signature">
  <span slot="description">
    By signing, you agree to the <a href="https://example.com/" target="_blank">terms and conditions</a>.
  </span>
</quiet-signature>

Submitting signatures Jump to heading

When a signature field is inside a form, its value is submitted with the form data using the name attribute as the key. Both drawn and typed signatures are submitted as Base64-encoded PNG data URIs (e.g., data:image/png;base64,...). On the server, you can decode the Base64 data to save the signature as an image file.


Submit
<div id="signature__form">
  <form>
    <quiet-signature name="signature" label="Signature"></quiet-signature>
    <br>
    <quiet-button type="submit" variant="primary">Submit</quiet-button>
  </form>

  <pre style="max-width: 100%; overflow: auto; margin-block: 1.5rem 0;" hidden></pre>
</div>

<script type="module">
  import { allDefined } from '/dist/quiet.js';

  await allDefined();

  const container = document.getElementById('signature__form');
  const form = container.querySelector('form');
  const output = container.querySelector('pre');

  form.addEventListener('submit', event => {
    const formData = new FormData(form);
    const signature = formData.get('signature');

    output.hidden = false;
    event.preventDefault();

    if (signature) {
      output.textContent = signature.substring(0, 100) + '...';
    } else {
      output.textContent = 'No signature provided';
    }
  });
</script>

Controlling the exported image Jump to heading

Use the export-width and export-height attributes to control the dimensions of the exported signature image. This affects both getImage() and the value submitted with forms.

The default width is 800 pixels, which ensures signatures remain crisp on high-density displays. Height is automatically calculated unless a special export-height is set.

Use export-ink-color to export signatures with a different ink color than what's displayed on screen. The image's background is always transparent.


Submit Reset
<div id="signature__export">
  <form>
    <quiet-signature
      name="signature"
      label="Sign below"
      export-width="800"
      export-height="800"
      export-ink-color="deeppink"
      required
    ></quiet-signature>
    <br>
    <quiet-button type="submit" variant="primary">Submit</quiet-button>
    <quiet-button type="reset">Reset</quiet-button>
  </form>

  <div style="margin-top: 1rem;" hidden>
    Exported image (square, deeppink)
    <br>
    <img style="width: 200px; height: 200px; margin-top: 0.5rem; border: 1px solid var(--quiet-neutral-stroke-soft);">
  </div>
</div>

<script type="module">
  import { allDefined } from '/dist/quiet.js';

  await allDefined();

  const container = document.getElementById('signature__export');
  const form = container.querySelector('form');
  const signature = container.querySelector('quiet-signature');
  const result = container.querySelector('div');
  const img = container.querySelector('img');

  form.addEventListener('submit', event => {
    event.preventDefault();
    const image = signature.getImage();
    if (image) {
      img.src = image;
      result.hidden = false;
    }
  });

  form.addEventListener('reset', () => {
    result.hidden = true;
    img.src = '';
  });
</script>

Custom ink color and width Jump to heading

Use the --ink-color custom property to change the color of the drawn signature. Use --ink-width to change the stroke width (default: 2).



<quiet-signature
  name="signature"
  label="Colored signature"
  style="--ink-color: var(--quiet-primary-fill-mid);"
></quiet-signature>

<br>

<quiet-signature
  name="signature"
  label="Thicker signature"
  style="--ink-width: 6;"
></quiet-signature>

<br>

<quiet-signature
  name="signature"
  label="Thinner signature"
  style="--ink-width: 1.5;"
></quiet-signature>

Custom fonts Jump to heading

Typed names are rendered on the canvas using a cursive font. Use the --signature-font-family custom property to change the font. The default is cursive, which uses the system's cursive font.

<quiet-signature
  name="signature"
  label="Signature with custom font"
  style="--signature-font-family: 'Brush Script MT', 'Segoe Script', cursive;"
></quiet-signature>

You can also use web fonts like Google Fonts. Make sure to load the font before using it.

<link href="https://fonts.googleapis.com/css2?family=Dancing+Script&display=swap" rel="stylesheet">

<quiet-signature
  name="signature"
  label="Signature with Google Font"
  style="--signature-font-family: 'Dancing Script', cursive;"
></quiet-signature>

You can also control the font weight with --signature-font-weight, and the minimum and maximum font sizes that will be displayed with --signature-font-size-min and --signature-font-size-max.

<quiet-signature
  name="signature"
  label="Signature with bold font"
  style="--signature-font-weight: bold;"
></quiet-signature>

Custom placeholders Jump to heading

Use the placeholder attribute to change the text field's placeholder. Use the signature-placeholder attribute to change the placeholder shown in the signature box.

The signature box also supports HTML placeholders through the signature-placeholder slot, as shown below.


scribble here
<quiet-signature
  name="signature"
  label="Signature"
  signature-placeholder="Draw your signature here"
  placeholder="Or you can type in your name here"
>
  <div slot="signature-placeholder">
    <quiet-icon name="signature" style="font-size: 3em;"></quiet-icon>
    <br>
    scribble here
  </div>
</quiet-signature>

Changing the size Jump to heading

Use the size attribute to change the signature field's size.

<quiet-select label="Select a size" value="xs" style="max-width: 18rem; margin-block-end: 2rem;">
  <option value="xs">Extra small</option>
  <option value="sm">Small</option>
  <option value="md" selected>Medium</option>
  <option value="lg">Large</option>
  <option value="xl">Extra large</option>
</quiet-select>

<quiet-signature
  id="signature__size"
  name="signature"
  label="Signature"
  size="xs"
></quiet-signature>

<script>
  const signature = document.getElementById('signature__size');
  const select = signature.previousElementSibling;

  select.addEventListener('quiet-change', () => {
    signature.size = select.value;
  });
</script>

Disabling Jump to heading

Use the disabled attribute to disable the signature field.

<quiet-signature label="Disabled signature" disabled></quiet-signature>

Read-only Jump to heading

Use the readonly attribute to make the signature field read-only. The user can see any existing signature but cannot modify it.

<quiet-signature label="Read-only signature" readonly></quiet-signature>

Validation Jump to heading

The required attribute can be used to make the signature field required. The form will not submit until the user provides a signature (drawn or typed).


Submit Reset
<form action="about:blank" method="get" target="_blank">
  <quiet-signature
    name="signature"
    label="Signature"
    required
  ></quiet-signature>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

Using custom validation Jump to heading

Use the setCustomValidity() method to make the signature field invalid and show a custom error message on submit. This will override all other validation parameters. To clear the error, call it with an empty string.


Submit
<form action="about:blank" method="get" target="_blank" id="signature__custom-validation">
  <quiet-signature
    name="signature"
    label="Signature"
    description="This field will be invalid until custom validation is removed"
  ></quiet-signature>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
</form>

<script type="module">
  import { allDefined } from '/dist/quiet.js';

  await allDefined();

  const form = document.getElementById('signature__custom-validation');
  const signature = form.querySelector('quiet-signature');

  signature.setCustomValidity('This field will be invalid until custom validation is removed');
</script>

Styling validation Jump to heading

You can style valid and invalid signature fields using the :valid and :invalid pseudo classes.


Submit Reset
<form action="about:blank" method="get" target="_blank" class="signature__validation-pseudo">
  <quiet-signature
    name="signature"
    label="Signature"
    description="This field is required"
    required
  ></quiet-signature>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

<style>
  .signature__validation-pseudo {
    quiet-signature:valid {
      outline: solid 2px var(--quiet-constructive-stroke-mid);
      outline-offset: .5rem;
    }

    quiet-signature:invalid {
      outline: solid 2px var(--quiet-destructive-stroke-mid);
      outline-offset: .5rem;
    }
  }
</style>

However, these selectors will match even before the user has had a chance to interact with the form. More often than not, you'll want to use the user-valid and user-invalid custom states instead. This way, validation styles are only shown after the user interacts with the form control or when the form is submitted.


Submit Reset
<form action="about:blank" method="get" target="_blank" class="signature__validation-custom">
  <quiet-signature
    name="signature"
    label="Signature"
    description="This field is required"
    required
  ></quiet-signature>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

<style>
  .signature__validation-custom {
    quiet-signature:state(user-valid) {
      outline: solid 2px var(--quiet-constructive-stroke-mid);
      outline-offset: .5rem;
    }

    quiet-signature:state(user-invalid) {
      outline: solid 2px var(--quiet-destructive-stroke-mid);
      outline-offset: .5rem;
    }
  }
</style>

API Jump to heading

Importing Jump to heading

The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.

CDN Self-hosted

To manually import <quiet-signature> from the CDN, use the following code.

import 'https://cdn.quietui.org/v2.4.0/components/signature/signature.js';

To manually import <quiet-signature> from a self-hosted distribution, use the following code. Remember to replace /path/to/quiet with the appropriate local path.

import '/path/to/quiet/components/signature/signature.js';

Slots Jump to heading

Signature supports the following slots. Learn more about using slots

Name Description
label The signature field's label. For plain-text labels, you can use the label attribute instead.
description The signature field's description. For plain-text descriptions, you can use the description attribute instead.
signature-placeholder The placeholder to render in the signature box.

Properties Jump to heading

Signature has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties

Property / Attribute Description Reflects Type Default
label The signature field's label. If you need to provide HTML in the label, use the label slot instead. string
description The signature field's description. If you need to provide HTML in the description, use the description slot instead. string
name The name of the signature field. This will be submitted with the form as a name/value pair. string
value The signature field's value. When a signature is drawn, this will be a Base64 data URI. When typed, this will be the typed text. string ''
signaturePlaceholder
signature-placeholder
The placeholder text shown when the canvas is empty. Defaults to a localized "Sign here" message. string ''
placeholder The placeholder text for the text field. Defaults to a localized "Type your full name" message. string ''
disabled Disables the signature field. boolean false
readonly Makes the signature field read-only. boolean false
required Makes the signature field required. Form submission will not be allowed when this is set and no signature or typed name exists. boolean false
size The signature field's size. 'xs'
'sm'
'md'
'lg'
'xl'
'md'
exportWidth
export-width
The width of the exported image in pixels. Height is auto-calculated to preserve the canvas aspect ratio unless export-height is also set. number 800
exportHeight
export-height
The height of the exported image in pixels. If only export-height is set, width is calculated to preserve the canvas aspect ratio. If both export-width and export-height are set, the signature is scaled to fit within the bounds while preserving aspect ratio. number
undefined
exportInkColor
export-ink-color
The ink color used when exporting via getImage(). When set, allows the UI to display one color (e.g. for dark mode) while exporting with a different color (e.g. black for transparent backgrounds). If not set, defaults to the current --ink-color. string
form The form to associate this control with. If omitted, the closest containing <form> will be used. The value of this attribute must be an ID of a form in the same document or shadow root. string

Methods Jump to heading

Signature supports the following methods. You can obtain a reference to the element and call them like functions in JavaScript. Learn more about methods

Name Description Arguments
focus() Sets focus to the text field.
blur() Removes focus from the signature field.
clear() Clears the signature and typed name.
getImage() Returns the signature as a data URI, or returns null if no signature exists. format: 'png' <br> 'jpeg'
checkValidity() Checks if the form control has any restraints and whether it satisfies them. If invalid, false will be returned and the invalid event will be dispatched. If valid, true will be returned.
reportValidity() Checks if the form control has any restraints and whether it satisfies them. If invalid, false will be returned and the invalid event will be dispatched. In addition, the problem will be reported to the user. If valid, true will be returned.
setCustomValidity() Sets a custom validation message for the form control. If this message is not an empty string, then the form control is considered invalid and the specified message will be displayed to the user when reporting validity. Setting an empty string clears the custom validity state. message: string

Events Jump to heading

Signature dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events

Name Description
quiet-blur Emitted when the signature field loses focus. This event does not bubble.
quiet-change Emitted when the user commits changes to the signature field's value.
quiet-focus Emitted when the signature field receives focus. This event does not bubble.
quiet-input Emitted when the signature field receives input.

CSS custom properties Jump to heading

Signature supports the following CSS custom properties. You can style them like any other CSS property. Learn more about CSS custom properties

Name Description Default
--ink-color The color of the drawn or typed signature. var(--quiet-text-body)
--ink-width The stroke width in pixels. 2
--signature-font-family The font family used for typed signatures. cursive
--signature-font-weight The font weight used for typed signatures. normal
--signature-font-size-min The minimum font size in pixels for typed signatures. 16
--signature-font-size-max The maximum font size in pixels for typed signatures. 64

CSS parts Jump to heading

Signature exposes internal elements that can be styled with CSS using the selectors shown below. Learn more about CSS parts

Name Description CSS selector
label The element that contains the signature field's label. ::part(label)
description The element that contains the signature field's description. ::part(description)
signature-box The container that wraps the canvas. ::part(signature-box)
canvas The drawing canvas element. ::part(canvas)
signature-placeholder The placeholder text shown when the signature box empty. ::part(signature-placeholder)
clear-button The clear button that appears when a signature exists. ::part(clear-button)
type-field The text field for typing a name, an <input> element. ::part(type-field)

Custom States Jump to heading

Signature has the following custom states. You can target them with CSS using the selectors shown below. Learn more about custom states

Name Description CSS selector
disabled Applied when the signature field is disabled. :state(disabled)
blank Applied when the signature field has no signature or typed name. :state(blank)
focused Applied when the signature field has focus. :state(focused)
user-valid Applied when the signature field is valid and the user has sufficiently interacted with it. :state(user-valid)
user-invalid Applied when the signature field is invalid and the user has sufficiently interacted with it. :state(user-invalid)

Dependencies Jump to heading

Signature automatically imports the following elements. Sub-dependencies are also included in this list.

Search this website Toggle dark mode View the code on GitHub Follow @quietui.org on Bluesky Follow @quiet_ui on X

    No results found