WebKit(Mac版のSafari含む)では fill-opacity
を設定した要素にSVGグラデーションを適用すると色味がくすんでしまいます。
SVGグラデーションを透明化する場合には、 stop-opacity
を用いるか、塗りと線のパスを分けた上で塗りのパスに opacity
を設定する必要がありそうです。
なお、iOS版Safariでは問題ないもよう(なぜだ)。
現象確認用のデモ
以下の様なSVGで現象が発生します。
<svg viewBox="0 0 300 200">
<defs>
<linearGradient id="g0">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="green"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
</defs>
<circle cx="50%" cy="50%" r="33%" fill="url(#g0)" fill-opacity=".67"></circle>
</svg>
デモURL: https://codepen.io/haribote/pen/BREjKV?editors=1100#0
↑はデモをSafariで開いたキャプチャーです。
お分かりいただけただろうか…?
方法は違えどすべて同じ透明度を指定しているにもかかわらず fill-opacity
を設定しているパターンのみ色味がくすんでしまっています。
ちなみにSVGの <linearGradient />
や <radialGradient />
には color-interpolation
属性で色空間を指定することができますが明示的に sRGB
を指定してもダメでした。
対応方法いろいろ
stop-opacity
を用いる
<svg viewBox="0 0 300 200">
<defs>
<linearGradient id="g1">
<stop offset="0%" stop-color="red" stop-opacity=".67"></stop>
<stop offset="50%" stop-color="green" stop-opacity=".67"></stop>
<stop offset="100%" stop-color="blue" stop-opacity=".67"></stop>
</linearGradient>
</defs>
<circle cx="50%" cy="50%" r="33%" fill="url(#g1)"></circle>
</svg>
グラデーションを適用する要素に透明度を指定するのではなく、グラデーション定義側に透明度を指定します。
定義したグラデーションの使い方が全ての適用要素において同じなのであればこの方法でも良さそうです。
しかし、 stop-opacity
は本来、透明度のグラデーションを設定するための属性・スタイル(不透明から透明にしたい、など)です。
なので要素ごとの塗りの透明度とグラデーション定義自体の透明度はやはり別に設定したいといった場合がおそらく多く、そういった場合にこの方法を用いることはできません。
opacity
を用いる
<svg viewBox="0 0 300 200">
<defs>
<linearGradient id="g2">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="green"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
</defs>
<circle cx="50%" cy="50%" r="33%" fill="url(#g2)" stroke="none" opacity=".67"></circle><!-- 塗りを適用するパス -->
<circle cx="50%" cy="50%" r="33%" fill="none"></circle><!-- 線を適用するパス -->
</svg>
次に考えられるのが、グラデーションを適用する要素に opacity
を設定する方法です。
ただ opacity
は要素丸ごと、すなわち塗りも線も一緒くたに透明化してしまいます。
したがって塗りにだけ透明度を指定したい場合は、上記コードのように塗りを適用するパスと線を適用するパスを分けて書く必要があります。
うん、本当はそんなことしなくて良いように fill-opacity
があるはずなんだけどね…。