Is it possible to more accurately measure SVG text height?
No. All the SVG DOM methods (getBBox()
, getExtentOfChar()
) are defined to return the full glyph cell height. That extra space above the cap height is allowance for taller glyphs - such as accented capitals. I think this is true for HTML DOM methods as well.
There are, however, JS libraries around which may be of use. For example:
https://github.com/Pomax/fontmetrics.js
I have not used this library myself, so I can't tell you how reliable or accurate it is.
Proper way to calculate the height and width of a SVG text
Maybe there is no good way to achieve exactly what I was after. However, giving up the "without actually adding it to the DOM of my page" part, the following function seems to achieve my goal.
function bboxText( svgDocument, string ) {
var data = svgDocument.createTextNode( string );
var svgElement = svgDocument.createElementNS( svgns, "text" );
svgElement.appendChild(data);
svgDocument.documentElement.appendChild( svgElement );
var bbox = svgElement.getBBox();
svgElement.parentNode.removeChild(svgElement);
return bbox;
}
Edit:
A note on the calculation of the height: the height of the bbox returned, i.e. bbox.height
, is always the full height of the glyph, i.e. a
will have the same height as A
. And I could not find a way to calculate them more exactly.
However, one can calculate the height of uppercase accented characters, e.g. Ä
. This will be just the negative of the y coordinate of the bbox, i.e. -bbox.y
.
Using this one can calculate, for example, some coordinates for vertical alignment. For example to emulate the dominantBaseline
attribute set to text-before-edge
, text-after-edge
, and central
.
text-before-edge
: dy = -bbox.y
text-after-edge
: dy = -bbox.height -bbox.y
central
: dy = -bbox.y -bbox.height/2
Where dy
is the vertical translation. This can be used to get around limitations of some applications that do not support these alignments set by attributes.
Set height of SVG to line-height?
I would consider the svg as a background-image to be sure it will match the height without setting any height:
h1 { line-height: 1; padding-left: 1.8em; background-size: auto 100%; background-repeat: no-repeat;}
<h1 style="background-image:url(https://upload.wikimedia.org/wikipedia/commons/f/f7/Bananas.svg)"> Headline</h1>
<h1 style="font-size:50px;background-image:url(https://upload.wikimedia.org/wikipedia/commons/f/f7/Bananas.svg)"> Headline</h1><h1 style="font-size:10px;background-image:url(https://upload.wikimedia.org/wikipedia/commons/f/f7/Bananas.svg)"> Headline</h1>
SVG get text element width
var bbox = textElement.getBBox();
var width = bbox.width;
var height = bbox.height;
and then set the rect's attributes accordingly.
Link: getBBox()
in the SVG v1.1 standard.
How can I determine accurate height of Raphael text()?
You can't. Actually this is not a "padding". getBBox returns dimentions given from a font metric, not individual glyphs. BBox height for text element includes font ascent and descent.
In most fonts, ascent reserves a gap above cap-height for glyphs such as "Ä". Discenders are reserved for lowercase characters with "tails" such as "g", "j", "q" and etc. For example, draw a rect around text "Äg".
For more detais see:
http://commons.oreilly.com/wiki/index.php/SVG_Essentials/Text
http://www.w3.org/TR/SVG11/text.html#BaselineAlignmentProperties
http://en.wikipedia.org/wiki/Baseline_(typography)
Related Topics
How to Achieve Fixed Position Background Scroll/Reveal Effect? Jquery Plugin Available
Adding Style Stored in a Variable Inside React Class
Jqm Ui-Content 100% Height Issue
How to Override the Style of the Material-Ui Switch Component When Checked
Jquery Example (In Jsfiddle) Working in Firefox But Not in IE8, 7
Detect If Text-Overflow:Ellipsis Is Active on Input Field
How to Disable Smooth Scrolling in Ie11
Workaround for Display Block and CSS Transitions Not Triggering
Android - Parse Js Generated Urls with Jsoup
How to Save an Image with CSS Filter Applied
How to Show a Label Beyond a Certain Zoom Level in Leaflet
Horizontal Slideshow with Divs
Get Pixelcolor of CSS Background Image
Infinite Rotation Animation Using CSS and JavaScript
Laravel 8 + Nginx - App.CSS and App.Js Resources from Public/ Not Loading - 404 Not Found