Signatur
Beschreibung
Die schreibgeschützte Eigenschaft fontBoundingBoxAscent eines TextMetrics-Objekts gibt an, wie weit die Oberkante der Font-Bounding-Box über der aktuellen Grundlinie liegt. Welche Linie als Grundlinie gilt, bestimmt CanvasRenderingContext2D.textBaseline. Das TextMetrics-Objekt selbst bekommen Sie über ctx.measureText(text).
Die Font-Bounding-Box beschreibt die Maße der Schrift, also den Oberlängenwert aus den Metadaten der Schriftdatei. Die tatsächlich gezeichneten Zeichen spielen keine Rolle. Deshalb ist der Wert für "a" und "Ä" bei gleicher Schrift und Größe gleich. Genau das braucht man für eine gleichmäßige Zeilenhöhe, für Textboxen mit festem Innenabstand oder für das vertikale Ausrichten mehrerer Textzeilen. Die Ergebnisse springen dann nicht, wenn sich der Inhalt ändert.
Die Oberkante der tatsächlich gezeichneten Zeichen liefert dagegen actualBoundingBoxAscent. Die Gesamthöhe der Zeile ergibt sich aus fontBoundingBoxAscent + fontBoundingBoxDescent.
Rückgabewert
textBaseline = "top" ist der Wert meist 0 oder sehr klein, und er kann auch negativ werden.Beispiele
Oberlänge der Schrift auslesen
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '32px Arial';
ctx.textBaseline = 'alphabetic';
const metrics = ctx.measureText('Hallo Welt');
console.log(metrics.fontBoundingBoxAscent);
Zeilenhöhe für mehrzeiligen Text berechnen
const ctx = document.querySelector('canvas').getContext('2d');
ctx.font = '20px system-ui';
ctx.textBaseline = 'alphabetic';
const lines = ['Erste Zeile', 'zweite zeile', 'ÄÖÜ gjpqy'];
const m = ctx.measureText('M');
const lineHeight = m.fontBoundingBoxAscent + m.fontBoundingBoxDescent;
lines.forEach((line, i) => {
// Grundlinie jeder Zeile: Oberlänge + i * Zeilenhöhe
const y = 10 + m.fontBoundingBoxAscent + i * lineHeight;
ctx.fillText(line, 10, y);
});
console.log('Zeilenhöhe:', lineHeight.toFixed(1));
Hintergrundbox mit stabiler Höhe hinter einem Label
const ctx = document.querySelector('canvas').getContext('2d');
ctx.font = 'bold 16px sans-serif';
ctx.textBaseline = 'alphabetic';
const drawLabel = (text, x, y) => {
const m = ctx.measureText(text);
const padding = 6;
const top = y - m.fontBoundingBoxAscent - padding;
const height = m.fontBoundingBoxAscent + m.fontBoundingBoxDescent + padding * 2;
ctx.fillStyle = '#1e3a8a';
ctx.fillRect(x - padding, top, m.width + padding * 2, height);
ctx.fillStyle = '#fff';
ctx.fillText(text, x, y);
};
// Beide Boxen sind gleich hoch, obwohl der Inhalt verschieden ist
drawLabel('aaa', 20, 40);
drawLabel('Ägypten', 100, 40);
Vergleich mit actualBoundingBoxAscent
const ctx = document.createElement('canvas').getContext('2d');
ctx.font = '40px serif';
for (const text of ['x', 'H', 'Ä']) {
const m = ctx.measureText(text);
console.log(text, m.fontBoundingBoxAscent.toFixed(1), m.actualBoundingBoxAscent.toFixed(1));
}
// Wichtig · Fallstricke
- Hängt von der Grundlinie ab: Der Wert wird relativ zu
ctx.textBaselinegemessen. Setzen SietextBaselinealso vor dem Aufruf vonmeasureText(), und messen Sie neu, wenn Sie die Grundlinie ändern. - Schrift muss geladen sein: Bei Webfonts misst der Browser mit der Ersatzschrift, solange die eigentliche Schrift noch nicht geladen ist. Warten Sie deshalb vorher auf
await document.fonts.load('20px MeineSchrift')oderdocument.fonts.ready. - Font-Box oder tatsächliche Box: Die Font-Box ist oft deutlich höher als die gezeichneten Zeichen. Für eine pixelgenaue Umrandung des Inhalts nehmen Sie
actualBoundingBoxAscent. - Kompatibilität: Firefox unterstützt die Eigenschaft erst seit Version 116, vorher war sie dort nur über ein Flag verfügbar. In älteren Browsern ist sie
undefined, deshalb lohnt sich ein Ersatzwert, z. B.m.fontBoundingBoxAscent ?? m.actualBoundingBoxAscent. In Web Workers steht sie auch überOffscreenCanvaszur Verfügung. - Unterschiedliche Betriebssysteme und Schriftversionen können leicht abweichende Werte liefern. Schreiben Sie deshalb keine festen Werte in Tests.