Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Dominant Baseline Style

Demonstrates the effect of dominant baseline for each of its possible values on text positioning in an SVG.

Each browser/ mobile browser seems to handle these a bit differently. Here are some issues:

  • Retrieving bounding boxes only works correctly after the font is loaded (and there is no easy way to find out when this happens)
  • The bounding box width does not reflect the actual extent of a text, but how far it advances the cursor. That means that in an italic letter 'f' in many fonts, part of the f will actually lie outside of the bounding box
  • The baseline-shift style does not work in FF
  • dominant-baseline values are interpreted different among browsers

All in all its best just use 'alphabetical' (which is consistent across browsers) and do any further vertical positioning by manually by using the x,y or dx,dy or the transform attributes. Also, if one needs to find out about the actual bounds of a text, one cannot rely on the getBBox() or the getBoundingClientRect() DOM methods, but has to use a library like Font.js for accurate results. There is a huge performance cost to consider, though.

<!DOCTYPE html>
<meta charset="utf-8"/>
<title>Dominant Baseline</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
@font-face {
font-family: 'Crimson Text';
src: url(crimson-roman-webfont.ttf);
}
</style>
<svg width=960 height=500>
<line x1=10 x2=920 y1=200.5 y2=200.5 style="stroke: green"></line>
<text x=926 y=200.5 style="dominant-baseline:central;fill: green; font-size: 14px;">y=0</text>
<g class="terms" transform="translate(20,200.5)">
<text x=0 style="dominant-baseline: alphabetic;">(+)</text>
<text x=100 style="baseline-shift: -24%;">(+)</text>
<text x=200 style="dominant-baseline: ideographic;">(+)</text>
<text x=300 style="dominant-baseline: hanging;">(+)</text>
<text x=400 style="dominant-baseline: mathematical;">(+)</text>
<text x=500 style="dominant-baseline: middle;">(+)</text>
<text x=600 style="dominant-baseline: central;">(+)</text>
<text x=700 style="dominant-baseline: text-before-edge;">(+)</text>
<text x=800 style="dominant-baseline: text-after-edge;">(+)</text>
</g>
<g class="labels" transform="translate(50,120)" style="visibility: hidden">
<text>alphabetical</text>
<text>+ bl-shift: -24%</text>
<text>ideographic</text>
<text>hanging</text>
<text>mathemetical</text>
<text>middle</text>
<text>central</text>
<text>text-before-edge</text>
<text>text-after-edge</text>
</g>
</svg>
<script>
var size = 60;
setTimeout(function() {
d3.select('.terms')
.style('font-size', size+"px")
.style('font-family', 'Crimson Text');
var d = [];
d3.selectAll('.terms text')
.each(function() { d.push(this.getBBox()) });
d3.selectAll('.labels text')
.attr('transform', function (d,i) { return 'translate('+[i*100,0]+')rotate(-45)'});
d3.select('.labels')
.style('visibility', 'visible');
d3.select('svg .terms').selectAll('rect')
.data(d).enter()
.append('rect')
.attr('x', function(d) {return d.x})
.attr('y', function(d) {return d.y})
.attr('width', function(d) {return d.width})
.attr('height', function(d) {return d.height})
.style('stroke', 'gray')
.style('stroke-dasharray', '6 6')
.style('fill', 'none')
}, 1000);
</script>
@denilsonsa

This comment has been minimized.

Copy link

@denilsonsa denilsonsa commented Apr 27, 2015

text-before-edge and text-after-edge labels are swapped.

@eweitnauer

This comment has been minimized.

Copy link
Owner Author

@eweitnauer eweitnauer commented Aug 14, 2016

Fixed the swapped labels, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.