Home > Back-end >  Persian text in SVG is falling apart
Persian text in SVG is falling apart

Time:03-05

I have an SVG with persian text in it. for example: سلام دنیا which means Hello World

But when I open my SVG in browser, it will falling appart!

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="68" height="24" role="img" aria-label="سلام دنیا">
    <link xmlns="" type="text/css" rel="stylesheet" id="dark-mode-custom-link"/>
    <link xmlns="" type="text/css" rel="stylesheet" id="dark-mode-general-link"/>
    <style xmlns="" lang="en" type="text/css" id="dark-mode-custom-style"/>
    <style xmlns="" lang="en" type="text/css" id="dark-mode-native-style"/>
    <title>سلام دنیا</title>
    <a target="_blank" xlink:href="#">
        <linearGradient id="s" x2="0" y2="100%">
            <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
            <stop offset="1" stop-opacity=".1"/>
        </linearGradient>
        <clipPath id="r">
            <rect width="68" height="24" rx="3" fill="#fff"/>
        </clipPath>
        <g clip-path="url(#r)">
            <rect width="0" height="24" fill="#555"/>
            <rect x="0" width="68" height="24" fill="rgb(245, 119, 31)"/>
            <rect width="68" height="24" fill="url(#s)"/>
        </g>
        <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
            <text aria-hidden="true" x="340" y="170" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="580">سلام دنیا</text>
            <text x="340" y="160" transform="scale(.1)" fill="rgb(0, 0, 0)" textLength="580">سلام دنیا</text>
        </g>
    </a>
</svg>

Expected:

expected

What I see in my browser:(Sorry for bad quality)

actual

I tried:

xml:lang="fa" direction="rtl" in <svg> and <text> tag : not worked

CodePudding user response:

As @myf has pointed out: textLength="580" will tear your text appart that might prevent correct text rendering (direction, applying ligatures etc.) in some browsers.

Your code also contains empty <link>and <style> elements that might also cause issues.

unicode-bidi: bidi-override
You might also force a rtl direction via

text{
  direction: rtl; 
  unicode-bidi: bidi-override;
}

Css-tricks: unicode-bidi

Here's is a stripped down example that's rendered fine in chromium, Firefox and ios safari.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-width="68" data-height="24" role="img" aria-label="سلام دنیا" viewBox="0 0 68 24">
  <title>سلام دنیا</title>
  <defs>
    <linearGradient id="s" gradientTransform="rotate(90)">
      <stop offset="0%" stop-color="rgb(245, 119, 31)" stop-opacity="0.75" />
      <stop offset="50%" stop-color="rgb(245, 119, 31)" stop-opacity="1" />
    </linearGradient>
    <filter id="textShadow">
      <feDropShadow dx="0" dy="1" stdDeviation="0" flood-color="#010101" flood-opacity="0.25" />
    </filter>
  </defs>
  <a target="_blank" xlink:href="#">
    <rect x="0" width="100%" height="100%" fill="url(#s)" rx="3" />
    <text x="50%" y="50%" dy="12%" text-rendering="geometricPrecision" text-anchor="middle" style="font-family:Verdana, Geneva, DejaVu Sans, sans-serif; font-size:11px; direction: rtl; unicode-bidi: bidi-override;" filter="url(#textShadow)" fill="rgb(0, 0, 0)">سلام دنیا</text>
  </a>
</svg>

Debugging example: multiple bidi-override modes

<p>Auto text direction</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-width="68" data-height="24" role="img" aria-label="سلام دنیا" viewBox="0 0 68 24">
  <title>سلام دنیا</title>
  <defs>
    <linearGradient id="s" gradientTransform="rotate(90)">
      <stop offset="0%" stop-color="rgb(245, 119, 31)" stop-opacity="0.75" />
      <stop offset="50%" stop-color="rgb(245, 119, 31)" stop-opacity="1" />
    </linearGradient>
    <filter id="textShadow">
      <feDropShadow dx="0" dy="1" stdDeviation="0" flood-color="#010101" flood-opacity="0.25" />
    </filter>
  </defs>
  <a target="_blank" xlink:href="#">
    <rect x="0" width="100%" height="100%" fill="url(#s)" rx="3" />
    <text x="50%" y="50%" dy="12%" text-rendering="geometricPrecision" text-anchor="middle" style="font-family:Verdana, Geneva, DejaVu Sans, sans-serif; font-size:11px; direction: rtl;" filter="url(#textShadow)" fill="rgb(0, 0, 0)">سلام دنیا</text>
  </a>
</svg>

<p>Forced rtl text direction – unicode-bidi: bidi-override</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-width="68" data-height="24" role="img" aria-label="سلام دنیا" viewBox="0 0 68 24">
  <title>سلام دنیا</title>
  <defs>
    <linearGradient id="s" gradientTransform="rotate(90)">
      <stop offset="0%" stop-color="rgb(245, 119, 31)" stop-opacity="0.75" />
      <stop offset="50%" stop-color="rgb(245, 119, 31)" stop-opacity="1" />
    </linearGradient>
    <filter id="textShadow">
      <feDropShadow dx="0" dy="1" stdDeviation="0" flood-color="#010101" flood-opacity="0.25" />
    </filter>
  </defs>
  <a target="_blank" xlink:href="#">
    <rect x="0" width="100%" height="100%" fill="url(#s)" rx="3" />
    <text x="50%" y="50%" dy="12%" text-rendering="geometricPrecision" text-anchor="middle" style="font-family:Verdana, Geneva, DejaVu Sans, sans-serif; font-size:11px; direction: rtl; unicode-bidi: bidi-override;" filter="url(#textShadow)" fill="rgb(0, 0, 0)">سلام دنیا</text>
  </a>
</svg>

<p>Forced ltr text direction – unicode-bidi: bidi-override</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-width="68" data-height="24" role="img" aria-label="سلام دنیا" viewBox="0 0 68 24">
  <title>سلام دنیا</title>
  <defs>
    <linearGradient id="s" gradientTransform="rotate(90)">
      <stop offset="0%" stop-color="rgb(245, 119, 31)" stop-opacity="0.75" />
      <stop offset="50%" stop-color="rgb(245, 119, 31)" stop-opacity="1" />
    </linearGradient>
    <filter id="textShadow">
      <feDropShadow dx="0" dy="1" stdDeviation="0" flood-color="#010101" flood-opacity="0.25" />
    </filter>
  </defs>
  <a target="_blank" xlink:href="#">
    <rect x="0" width="100%" height="100%" fill="url(#s)" rx="3" />
    <text x="50%" y="50%" dy="12%" text-rendering="geometricPrecision" text-anchor="middle" style="font-family:Verdana, Geneva, DejaVu Sans, sans-serif; font-size:11px; direction: ltr; unicode-bidi: bidi-override;" filter="url(#textShadow)" fill="rgb(0, 0, 0)">سلام دنیا</text>
  </a>
</svg>

CodePudding user response:

Use this snippet. You should use display: block with direction.

svg {
    display: block;
    direction: rtl;
    margin-left: auto;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="68" height="24" role="img" aria-label="سلام دنیا">
    <link xmlns="" type="text/css" rel="stylesheet" id="dark-mode-custom-link"/>
    <link xmlns="" type="text/css" rel="stylesheet" id="dark-mode-general-link"/>
    <style xmlns="" lang="en" type="text/css" id="dark-mode-custom-style"/>
    <style xmlns="" lang="en" type="text/css" id="dark-mode-native-style"/>
    <title>سلام دنیا</title>
    <a target="_blank" xlink:href="#">
        <linearGradient id="s" x2="0" y2="100%">
            <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
            <stop offset="1" stop-opacity=".1"/>
        </linearGradient>
        <clipPath id="r">
            <rect width="68" height="24" rx="3" fill="#fff"/>
        </clipPath>
        <g clip-path="url(#r)">
            <rect width="0" height="24" fill="#555"/>
            <rect x="0" width="68" height="24" fill="rgb(245, 119, 31)"/>
            <rect width="68" height="24" fill="url(#s)"/>
        </g>
        <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
            <text aria-hidden="true" x="340" y="170" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="580">سلام دنیا</text>
            <text x="340" y="160" transform="scale(.1)" fill="rgb(0, 0, 0)" textLength="580">سلام دنیا</text>
        </g>
    </a>
</svg>

  • Related