Skip to content

Instantly share code, notes, and snippets.

@eweitnauer
Last active January 15, 2019 23:20
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save eweitnauer/7325338 to your computer and use it in GitHub Desktop.
Save eweitnauer/7325338 to your computer and use it in GitHub Desktop.
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
Copy link

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

@eweitnauer
Copy link
Author

Fixed the swapped labels, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment