Skip to content

bezoerb/text-metrics

Repository files navigation

text-metrics

NPM version Build Status BrowserStack Status Download Coverage Status

An lightweight & efficient text measurement set for the browser using canvas to prevent layout reflows.

Features

  • Compute width
  • Compute height
  • Compute linebreaks
  • Compute max font-size to fit into element

Installation

If you're using node, you can run npm install text-metrics.

text-metrics is also available via Bower (bower install text-metrics)

Alternatively if you just want to grab the file yourself, you can download either the current stable production version or the development version directly.

Setting it up

text-metrics supports AMD (e.g. RequireJS), CommonJS (e.g. Node.js) and direct usage (e.g. loading globally with a <script> tag) loading methods. You should be able to do nearly anything, and then skip to the next section anyway and have it work. Just in case though, here's some specific examples that definitely do the right thing:

CommonsJS (e.g. Node)

text-metrics needs some browser environment to run.

const textMetrics = require('text-metrics');

const el = document.querySelector('h1');
const metrics = textMetrics.init(el);

metrics.width('unicorns');
// -> 210

metrics.height('Some long text with automatic word wraparound');
// -> 180
metrics.lines('Some long text with automatic word wraparound');
// -> ['Some long text', 'with automatic', 'word', 'wraparound']
metrics.maxFontSize('Fitting Headline');
// -> 33px

Webpack / Browserify

const textMetrics = require('text-metrics');
textMetrics.init(document.querySelector('.textblock')).lines();

AMD (e.g. RequireJS)

define(['text-metrics'], function (textMetrics) {
  textMetrics.init(document.querySelector('h1')).width('unicorns');
});

Directly in your web page:

<script src="text-metrics.min.js"></script>
<script>
  textMetrics.init(document.querySelector('h1')).width('unicorns');
</script>

API

Construct textmetrics object:

textMetrics.init([el, overwrites])

You can call textMetrics with either an HTMLElement or with an object with style overwrites or with both. e.g.

// takes styles from h1
textMetrics.init(document.querySelector('h1'));

// takes styles from h1 and overwrites font-size
textMetrics.init(document.querySelector('h1'), {fontSize: '20px'});

// only use given styles
textMetrics.init({
  fontSize: '14px',
  lineHeight: '20px',
  fontFamily: 'Helvetica, Arial, sans-serif',
  fontWeight: 400,
  width: 100,
});

Methods

width([text, [options, [overwrites]]])
height([text, [options, [overwrites]]])
lines([text, [options, [overwrites]]])
maxFontSize([text, [options, [overwrites]]])

text

Type: string Defaults to el.innerText if an element is available

options

Type: object

key default description
multiline false The width of widest line instead of the width of the complete text

overwrites

Type: object

Use to overwrite styles

Performance

I've compared this module with a very naive jQuery implementation as well as the . See https://jsperf.com/bezoerb-text-metrics Even if Range.getBoundingClientRect should be considered as a performance bottleneck according to what-forces-layout by Paul Irish, i couldn't detect any sort of recalculate style and it massively outperforms textMetrics.height().

Compatibility

The normal build (3,2kb gzipped) should work well on modern browsers.
These builds are tested using
Browserstack

License

Copyright (c) 2016 Ben Zörb Licensed under the MIT license.

License

MIT © Ben Zörb