Start · Sprachen · JavaScript · Referenz · TextMetrics.width

TextMetrics.width

Eigenschaft

Schreibgeschützte Eigenschaft, die die Vorschubbreite (Advance Width) eines mit <code>measureText()</code> gemessenen Textes in CSS-Pixeln liefert.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

TextMetrics.width

Beschreibung

Die Eigenschaft width eines TextMetrics-Objekts gibt an, wie weit der Text den Zeichenstift horizontal vorschiebt – also die Vorschubbreite des Inline-Blocks in CSS-Pixeln. Man erhält ein TextMetrics-Objekt über CanvasRenderingContext2D.measureText() oder OffscreenCanvasRenderingContext2D.measureText().

Typische Einsatzfälle sind das manuelle Zentrieren oder Ausrichten von Text, automatische Zeilenumbrüche im Canvas, das Kürzen von Beschriftungen mit Auslassungspunkten, das Dimensionieren von Hintergrund-Boxen hinter Labels sowie die Berechnung von Achsenbeschriftungen in Diagrammen.

Der Wert hängt vom aktuellen Zustand des Kontexts ab, vor allem von ctx.font, aber auch von letterSpacing, wordSpacing, fontKerning und fontStretch. Die Schriftart muss vor dem Messen gesetzt werden. Die Vorschubbreite ist nicht dasselbe wie die tatsächlich eingefärbte Fläche: Kursive oder überhängende Glyphen können darüber hinausragen. Für die exakte Pixel-Ausdehnung nimmt man actualBoundingBoxLeft + actualBoundingBoxRight.

Rückgabewert

Typ
number
Beschreibung
Vorschubbreite des gemessenen Textes in CSS-Pixeln (Gleitkommazahl, kann Nachkommastellen haben; 0 bei leerem String).

Beispiele

Textbreite messen

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

ctx.font = '16px sans-serif';
const metrics = ctx.measureText('Hallo Welt');
console.log(metrics.width.toFixed(2));
z. B. 77.45 (abhängig von Schrift und Browser)

Label mit passender Hintergrund-Box zeichnen

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const drawLabel = (text, x, y, padding = 6) => {
  ctx.font = 'bold 14px system-ui';
  const { width } = ctx.measureText(text);
  const height = 14;

  ctx.fillStyle = '#1e293b';
  ctx.fillRect(x, y - height - padding, width + padding * 2, height + padding * 2);

  ctx.fillStyle = '#fff';
  ctx.textBaseline = 'alphabetic';
  ctx.fillText(text, x + padding, y);
};

drawLabel('Umsatz: 12.400 €', 20, 40);

Automatischer Zeilenumbruch im Canvas

const wrapText = (ctx, text, maxWidth) => {
  const words = text.split(' ');
  const lines = [];
  let line = '';

  for (const word of words) {
    const test = line ? `${line} ${word}` : word;
    if (ctx.measureText(test).width > maxWidth && line) {
      lines.push(line);
      line = word;
    } else {
      line = test;
    }
  }
  if (line) lines.push(line);
  return lines;
};

const ctx = document.createElement('canvas').getContext('2d');
ctx.font = '16px serif';
const lines = wrapText(ctx, 'Canvas kennt keinen automatischen Zeilenumbruch, also bauen wir ihn selbst.', 180);
lines.forEach((l, i) => ctx.fillText(l, 10, 20 + i * 20));
console.log(lines.length);
z. B. 3

Text mit Auslassungspunkten kürzen

const truncate = (ctx, text, maxWidth) => {
  if (ctx.measureText(text).width <= maxWidth) return text;
  let result = text;
  while (result.length && ctx.measureText(result + '…').width > maxWidth) {
    result = result.slice(0, -1);
  }
  return result + '…';
};

const ctx = document.createElement('canvas').getContext('2d');
ctx.font = '14px sans-serif';
console.log(truncate(ctx, 'Sehr langer Dateiname_final_v2.pdf', 120));
z. B. "Sehr langer Datei…"

// Wichtig · Fallstricke

  • Reihenfolge beachten: ctx.font (und ggf. letterSpacing) muss vor measureText() gesetzt werden. Das Objekt ist eine Momentaufnahme und aktualisiert sich bei späteren Änderungen nicht.
  • Webfonts: Ist eine per @font-face eingebundene Schrift noch nicht geladen, wird mit der Ersatzschrift gemessen. Vorher mit await document.fonts.load('16px MeineSchrift') bzw. document.fonts.ready warten.
  • Vorschubbreite ≠ sichtbare Breite: Bei kursiven Schriften oder Glyphen mit Überhang ist actualBoundingBoxLeft + actualBoundingBoxRight genauer.
  • Keine Transformation: scale(), setTransform() und devicePixelRatio fließen nicht ein; der Wert ist immer in CSS-Pixeln des Kontext-Koordinatensystems.
  • Performance: measureText() in engen Schleifen (z. B. zeichenweises Kürzen) kann teuer sein – Ergebnisse cachen oder binär suchen.
  • Kompatibilität: width wird von allen Browsern seit Langem unterstützt, auch in OffscreenCanvas und Web Workern. Die übrigen TextMetrics-Felder (Bounding Boxes) sind neuer.
  • Die Eigenschaft ist schreibgeschützt; eine Zuweisung wird ignoriert (im Strict Mode TypeError).