Skip to content

Instantly share code, notes, and snippets.

@paulkaplan
Forked from eweitnauer/README.md
Created January 10, 2018 19:43
Show Gist options
  • Save paulkaplan/6dfef607481f3272ea95487241bd1a0f to your computer and use it in GitHub Desktop.
Save paulkaplan/6dfef607481f3272ea95487241bd1a0f 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment