在讨论旋转SVG文本时,有多个不同方面:
这里是完整但难以理解的规范。
'writing-mode'属性应该可以改变第一个方面而不影响其他方面,但正如你发现的在Firefox中根本没有实现,而IE会旋转文本但不遵守水平字形规则。
从理论上讲,通过组合旋转和变换属性,您应该能够获得相同的效果:将整个<text>
元素转换为垂直位置,然后将单个字符反向旋转以使其恢复水平。 但实际操作起来比较麻烦...
首先,双重旋转导致文本最终位于点(x,y)的左侧,因此如果(x,y)为(0,0),它将在SVG外被剪切掉而不需要额外的移位。由于变换的影响,您需要使用负的dy
值将文本移回到锚点的右侧。
其次,旋转应用于每个字符本身,字符间距没有调整以考虑“l”的高度远大于宽度的事实。 因此,除非使用等宽字体,否则文本看起来很混乱。您应该可以使用kerning
和letterspacing
属性更改字母间距,但是浏览器对此的支持也很差:IE11似乎不承认字距值,Firefox两者都不承认。
最后一种选择是自己控制布局:使用d3的强大功能和字符串的.split("")
方法将标题分解为单个字符的<tspan>
元素,这些元素可以一个接一个地放置并且可以在<text>
元素内进行整齐居中。 缺点是这会添加额外的DOM元素,您仍然可以像选择HTML段落中的短语一样选择整个文本块,即使每个字母都被样式化为单独的<span>
。 不确定屏幕阅读器是否会自动假定字母之间有空格......
对比
这个fiddle尝试了三种方法来获得垂直文本标签中的水平字符(writing-mode vs double rotate vs splitting into <tspan>
s):
http://jsfiddle.net/hx5Th/11/
代码:
var svg = d3.select("body").append("svg");
//Green text, uses writing-mode property //
svg.append("text")
.attr("x", 40)
.attr("y", 40)
.attr("id", "title")
.attr("font-size", 50)
.attr("style", "fill: lightgreen; writing-mode: tb; glyph-orientation-vertical: 0")
.text("Top 100 Mentions");
//Black text, uses a double rotate //
svg.append("text")
.attr("x", 40)
.attr("y", 40)
.attr("id", "title")
.attr("font-size", 50)
.attr("rotate", -90)
.attr("dx", "1em")
.attr("dy", "-1em")
.attr("kerning", 0)
.attr("letter-spacing", "0.5em")
.attr("transform", "translate(150,0) rotate(90)")
.text("Top 100 Mentions");
//Blue text, uses d3 to create a series of tspans//
svg.append("text")
.attr("x", 40)
.attr("y", 40)
.attr("font-size", 50)
.attr("id", "title")
.style("fill", "blue")
.attr("transform", "translate(300,0)")
.attr("text-anchor", "middle")
.selectAll("tspan")
.data("Top 100 Mentions".split(""))
.enter().append("tspan")
.attr("x", 0)
.attr("dy", "0.8em")
.text(function(d){return d;});
结果(都在 Windows 7 系统上):
Chrome 33
![输入图像描述](https://istack.dev59.com/AkpYa.webp)
IE 11
![输入图像描述](https://istack.dev59.com/GCDcQ.webp)
Firefox
![输入图像描述](https://istack.dev59.com/dybM4.webp)
我认为这是D3的胜利...
glyph-orientation-vertical: 0
添加到样式中以防止文本旋转。 - Samarth