Search code examples
csssvg

When using SVG to create gradient text with a vertical-rl writing mode, the text displays abnormally


I am trying to create vertically oriented text with a right-to-left gradient using the code below. However, the text is being displayed incorrectly.

text {
  writing-mode: vertical-rl;
  font-size: 50px;
  font-weight: bold;
}
<svg width="500" height="500">
  <defs>
    <linearGradient id="grad-md" x1="100%" y1="0%" x2="0%" y2="0%">
      <stop offset="0%" style="stop-color:#374151; stop-opacity:1"></stop>
      <stop offset="55%" style="stop-color:#374151; stop-opacity:1"></stop>
      <stop offset="100%" style="stop-color:#fff; stop-opacity:0"></stop>
    </linearGradient>
  </defs>
  <text x="50" y="50" fill="url(#grad-md)">测试文本123</text>
</svg>

As you can see, the initial few Chinese characters are not displaying correctly, and the direction of the gradient for Chinese text is incorrect.


Solution

  • By default text-origination is mixed, which applys differently for different languages. That causes the gradient calculation using different coordinating systems. You can force them to use either upright or sideways to uniform the calculation (but that means your Chinese will be sideways as well):

    text {
      writing-mode: vertical-rl;
      font-size: 50px;
      font-weight: bold;
      text-orientation: sideways;
    }
    <svg width="500" height="500">
        <defs>
            <linearGradient id="grad-md" x1="100%" y1="0%" x2="0%" y2="0%">
                <stop offset="0%" style="stop-color:#374151; stop-opacity:1"></stop>
                <stop offset="55%" style="stop-color:#374151; stop-opacity:1"></stop>
                <stop offset="100%" style="stop-color:#fff; stop-opacity:0"></stop>
            </linearGradient>
        </defs>
        <text x="50" y="50" fill="url(#grad-md)">测试文本123</text>
    </svg>

    However if you just want to apply some gradient to a text, a non-SVG solution might be a better choice:

    span {
      background-image: linear-gradient(to right, red, blue);
      background-clip: text;
      -webkit-background-clip: text;
      font-size: 50px;
      writing-mode: vertical-lr;
      color: transparent;
      font-weight: bold;
      white-space: nowrap;
    }
    <span>测试文本123</span>