user3310334
user3310334

Reputation:

Measure text width according to CSS without rendering it

I want to measure the theoretical width of some to-be-rendered text.

I like this method for getting text width, because it doesn't mutate the DOM

function getTextWidth(text, font) {
    // re-use canvas object for better performance
    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
    var context = canvas.getContext("2d");
    context.font = font;
    var metrics = context.measureText(text);
    return metrics.width;
}

I have a CSS description of the font

.dx-widget {
    color: #333;
    font-weight: 400;
    font-size: 14px;
    font-family: "Helvetica Neue","Segoe UI",helvetica,verdana,sans-serif;
    line-height: 1.35715;
}

How can I get in JavaScript the width that different strings would be according to these CSS rules?

I don't think I can apply this CSS class to the canvas to make it work.

Upvotes: 0

Views: 1408

Answers (2)

user3310334
user3310334

Reputation:

By reading https://developer.mozilla.org/en-US/docs/Web/CSS/font I have understood that .font can actually specify all of the information from that CSS.

line-height must immediately follow font-size, preceded by "/", like this: "16px/3"

font-weight must precede font-size

font-family must be the last value specified

So this CSS

font-weight: 400;
font-size: 14px;
font-family: "Helvetica Neue","Segoe UI",helvetica,verdana,sans-serif;
line-height: 1.35715;

can be compressed into

font: 400 14px/1.35715 "Helvetica Neue","Segoe UI",helvetica,verdana,sans-serif;

and that property value can be used in the original canvas getTextWidth function.

Upvotes: 0

Gergo
Gergo

Reputation: 125

Ok. I created a snippet.

By assigning a dummy element style (or of a real element) to a variable it is much easier to correct the code. In the console in the Developer Tools of any browser you can enter the name of the variable and see all properties.

Test and if it works for you- use it ;)

Or as Stephen P suggested in the comments- create a new empty span and you do not have to risc changing some real visible element :)

Vote his comment. It is great improvement.

var stylee=document.getElementById('test_element').style;
stylee.color="#333";
stylee.fontWeight="400";
stylee.fontSize="14px";
stylee.fontFamily='"Helvetica Neue","Segoe UI",helvetica,verdana,sans-serif';
stylee.lineHeight="1.35715";

function getTextWidth(text, font) {
    // re-use canvas object for better performance
    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
    var context = canvas.getContext("2d");
    context.font = font;
    var metrics = context.measureText(text);
    return metrics.width;
}

document.getElementById('result').innerText=getTextWidth('some text or variable', stylee);
<span id="test_element"></span>
<div id="result"></div>

Upvotes: 1

Related Questions