Search code examples
textsvgsafarishadow

Text shadow on SVG text element is always white on mobile Safari ...


I'm converting the main banner of a website from image to a SVG based. The code is basically this one:

<svg fill="url(#gradient-5)" width="100%" height="100%" style="transform: scale(1);">
    <defs>
        <linearGradient id="gradient-5" x2="0%" y2="100%" gradientUnits="userSpaceOnUse">
              <stop offset="40%" stop-color="#fff"></stop>
              <stop offset="60%" stop-color="#888"></stop>
              <stop offset="69%" stop-color="#fff"></stop>
              <stop offset="100%" stop-color="#fff"></stop>
        </linearGradient>
    </defs>
    <text text-anchor="middle" x="50%" y="75%">Sample text</text>
</svg>

And so, I see the text with the original gradient. The problem is that the original text had text-shadow, so I added text shadow with CSS:

.svg-main-banner text {
    text-shadow: #FF0000 0 3px;
}

But the text shadow is always white on mobile Safari. It's OK on all the other devices/browsers. Any idea why is this happening ?


Solution

  • As suggested by Michael Mullany, you could replace the CSS text-shadow with an equivalent SVG filter. You can create a drop shadow using a SVG filter of the form...

    <filter id="drop-shadow">
        <feGaussianBlur in="SourceAlpha" stdDeviation="[radius]"/>
        <feOffset dx="[offset-x]" dy="[offset-y]" result="offsetblur"/>
        <feFlood flood-color="[color]"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feMerge>
            <feMergeNode/>
            <feMergeNode in="SourceGraphic"/>
        </feMerge>
    </filter>
    

    Just fill in the radius, offset-x, offset-y, and color values. In your example, the SVG code would become...

    <svg fill="url(#gradient-5)" width="100%" height="100%" style="transform: scale(1);">
        <defs>
            <filter id="drop-shadow">
                <feGaussianBlur in="SourceAlpha" stdDeviation="0"/>
                <feOffset dx="0" dy="3" result="offsetblur"/>
                <feFlood flood-color="#FF0000"/>
                <feComposite in2="offsetblur" operator="in"/>
                <feMerge>
                    <feMergeNode/>
                    <feMergeNode in="SourceGraphic"/>
                </feMerge>
            </filter>
            <linearGradient id="gradient-5" x2="0%" y2="100%" gradientUnits="userSpaceOnUse">
                  <stop offset="40%" stop-color="#fff"></stop>
                  <stop offset="60%" stop-color="#888"></stop>
                  <stop offset="69%" stop-color="#fff"></stop>
                  <stop offset="100%" stop-color="#fff"></stop>
            </linearGradient>
        </defs>
        <text text-anchor="middle" x="50%" y="75%" filter="url(#drop-shadow)">Sample text</text>
    </svg>