Signature

A signature pad lets users sign with a mouse, a pen, or a finger. Use it to confirm an order, accept a contract, or hand over a delivery.

Overview

The signature pad is a canvas element with Tabler styles around it. Drawing is handled by the Signature Pad library.

Use the signature class on the wrapper and signature-canvas on the canvas. The wrapper draws a solid border, and the canvas adds a dashed one, so the signing area is easy to see. The cursor turns into a crosshair over the canvas.

Try it below. Draw with the mouse, or with a finger on a touch screen.

<div class="signature position-relative" style="width: 100%; max-width: 26rem;">
  <canvas id="signature-overview" class="signature-canvas" width="400" height="200" style="height: 10rem"></canvas>
</div>

Installation

The library is not part of the Tabler bundle. Install it with npm:

npm install signature_pad

Or include it from a CDN:

<script src="https://cdn.jsdelivr.net/npm/@tabler/[email protected]/dist/libs/signature_pad/dist/signature_pad.umd.min.js"></script>

Usage

Markup

Wrap the canvas in a signature element. Set width and height on the canvas, so it has a size before the script runs.

Also set the height in CSS. Tabler styles the canvas with width: 100%, so without a CSS height the canvas keeps the ratio of its attributes. The resize code below then reads a new height on every run, and the pad gets shorter each time.

<div class="signature position-relative">
  <canvas id="signature-default" class="signature-canvas" width="400" height="400" style="height: 16rem"></canvas>
</div>

Init the pad

Create the pad after the DOM is ready. Set a transparent background, so the canvas follows the card or the page. Take the pen color from the canvas text color, so the signature also works in dark mode.

document.addEventListener('DOMContentLoaded', function () {
  const canvas = document.getElementById('signature-default')

  const signaturePad = new SignaturePad(canvas, {
    backgroundColor: 'transparent',
    penColor: getComputedStyle(canvas).color,
  })
})

Keep the drawing sharp

A canvas has two sizes: the CSS size and the pixel size. On a retina screen they differ, and the line looks blurry. Scale the canvas to the device pixel ratio, and do it again on resize.

function resizeCanvas() {
  const ratio = Math.max(window.devicePixelRatio || 1, 1)

  canvas.width = canvas.offsetWidth * ratio
  canvas.height = canvas.offsetHeight * ratio
  canvas.getContext('2d').scale(ratio, ratio)

  // resizing clears the canvas, so put the drawing back
  signaturePad.fromData(signaturePad.toData())
}

window.addEventListener('resize', resizeCanvas)
resizeCanvas()

Clear button

Place a button in the corner of the wrapper and call clear() on it. The wrapper needs position-relative for this.

<div class="signature position-relative" style="width: 100%; max-width: 26rem;">
  <div class="position-absolute top-0 end-0 p-2">
    <button type="button" class="btn btn-icon" id="signature-clear-button" title="Clear signature">
      <!-- Download SVG icon from http://tabler.io/icons/icon/trash -->
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" class="icon">
        <path d="M4 7l16 0" />
        <path d="M10 11l0 6" />
        <path d="M14 11l0 6" />
        <path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12" />
        <path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3" />
      </svg>
    </button>
  </div>
  <canvas id="signature-clear" class="signature-canvas" width="400" height="200" style="height: 10rem"></canvas>
</div>
document.getElementById('signature-clear-button').addEventListener('click', function () {
  signaturePad.clear()
})

Pen color

Change penColor at any time. New strokes use the new color, and the old ones keep theirs.

document.getElementById('pen-color').addEventListener('input', function (event) {
  signaturePad.penColor = event.target.value
})

Save the signature

Use toDataURL() to read the drawing. Without arguments you get a PNG. Pass image/svg+xml for a vector file. Check isEmpty() first, so you do not save a blank pad.

if (signaturePad.isEmpty()) {
  // ask the user to sign first
} else {
  const png = signaturePad.toDataURL()
  const svg = signaturePad.toDataURL('image/svg+xml')
}

Use fromDataURL() to show a signature you saved earlier.

Pad inside a modal

A canvas has no size while the modal is hidden, so the pad must start after the modal opens. Listen for the Bootstrap shown.bs.modal event instead of DOMContentLoaded.

document.getElementById('modal-signature').addEventListener('shown.bs.modal', function () {
  // create the pad here
})

Examples

Signature in a form

Put the pad in a form group with a label, the same as any other field. Add the legal text under it when the signature is binding.

Confirm transfer

I agree that this signature is the electronic representation of my signature for all purposes when I use it on documents.
<div class="card">
  <div class="card-body">
    <h3 class="card-title">Confirm transfer</h3>
    <div class="mb-3">
      <label class="form-label required">Signature</label>
      <div class="signature position-relative">
        <div class="position-absolute top-0 end-0 p-2">
          <button type="button" class="btn btn-icon" id="signature-form-clear" title="Clear signature">
            <!-- Download SVG icon from http://tabler.io/icons/icon/trash -->
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" class="icon">
              <path d="M4 7l16 0" />
              <path d="M10 11l0 6" />
              <path d="M14 11l0 6" />
              <path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12" />
              <path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3" />
            </svg>
          </button>
        </div>
        <canvas id="signature-form" class="signature-canvas" width="400" height="180" style="height: 9rem"></canvas>
      </div>
    </div>
    <div class="text-secondary fs-5"> I agree that this signature is the electronic representation of my signature for all purposes when I use it on documents. </div>
    <div class="mt-4 d-flex">
      <button type="button" class="btn">Cancel</button>
      <button type="button" class="btn btn-primary ms-auto">Confirm transfer</button>
    </div>
  </div>
</div>

Accessibility

  • A canvas cannot be used with a keyboard. Offer a second way to sign, for example a text field where the user types their full name.
  • Give the pad a real <label>, so users know what they sign. Link it to the field with for and id.
  • Use a <button type="button"> for the clear action. A div with button classes is not reachable with the keyboard.
  • Tell users what happens with the drawing. A signature is personal data, so say where you store it and for how long.
  • Do not rely on the dashed border alone. Add a short hint, for example Sign inside the box.

On this page

130 sleek illustrations for your startup's visual identity.