CSSを使用したSVGグラデーション


102

SVG rect要素にグラデーションを適用しようとしています。

現在、私はfill属性を使用しています。私のCSSファイル:

rect {
    cursor: pointer;
    shape-rendering: crispEdges;
    fill: #a71a2e;
}

また、rect要素はブラウザで表示したときに正しい塗りつぶし色になります。

ただし、この要素に線形グラデーションを適用できるかどうか知りたいですか?

回答:


95

fill属性で使用するものはすべてCSSで使用してください。もちろん、これには、SVGのどこかに線形グラデーションを定義しておく必要があります。

以下は完全な例です。

rect {
    cursor: pointer;
    shape-rendering: crispEdges;
    fill: url(#MyGradient);
}
<svg width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <style type="text/css">
        rect{fill:url(#MyGradient)}
      </style>
      <defs>
        <linearGradient id="MyGradient">
          <stop offset="5%" stop-color="#F60" />
          <stop offset="95%" stop-color="#FF6" />
        </linearGradient>
      </defs>
      
      <rect width="100" height="50"/>
    </svg>


2
そのため、別のファイルでそのグラデーションを作成し、fill次のように使用しましたfill: url(../js/gradient.svg#MyGradient);。これは正しい方法ですか?
Hrishikesh Choudhari 2012

@HrishikeshChoudhari:はい、これは正しいですが、Chromeと私はSafariも他のファイルからの要素の参照をサポートしていないと思います。IE9については不明です(現在テストできません。試してみてください)。
トーマスW

53
これを読んで「どうfill: linear-gradient (...)ですか?」CSS2 クラスを中心に構築されたがfill必要です。言い換えれば、このコメントを書いている時点で、この回答が現在CSSを介して行う唯一の方法です。要素を追加する必要があります。最後に、SVG2用のw3ワーキングドラフトを検討すると、fill cssルールのサポートが仕様に組み込まれていない可能性があります。<paint><color>linearGradientlinear-gradient
Arthur Weborg 2015年

この場合、方向を変えるには?
AGamePlayer 2016年

1
@AwQiruiGuo MDN(特にgradientTransform属性)をご覧ください
Thomas W

34

2019回答

新しいCSSプロパティを使用すると、別名変数を使用してさらに柔軟にすることができます custom properties

.shape {
  width:500px;
  height:200px;
}

.shape .gradient-bg {
  fill: url(#header-shape-gradient) #fff;
}

#header-shape-gradient {
  --color-stop: #f12c06;
  --color-bot: #faed34;
}
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" class="shape">
  <defs>
    <linearGradient id="header-shape-gradient" x2="0.35" y2="1">
        <stop offset="0%" stop-color="var(--color-stop)" />
        <stop offset="30%" stop-color="var(--color-stop)" />
        <stop offset="100%" stop-color="var(--color-bot)" />
      </linearGradient>
  </defs>
  <g>
    <polygon class="gradient-bg" points="0,0 100,0 0,66" />
  </g>
</svg>

stopグラデーションでそれぞれに名前付き変数を設定し、CSSで好きなようにカスタマイズするだけです。次のように、JavaScriptを使用して動的に値を変更することもできます。

document.querySelector('#header-shape-gradient').style.setProperty('--color-stop', "#f5f7f9");

3
IEではサポートされていません。
aoakeson

3
CSSカスタムプロパティは非常に長い間ここにあります。何らかの理由で誰かがまだそれらを使用する準備ができていなければ、変更の準備ができません。
Maciej Kwas

1
@MaciejKwas、あなたは間違っています。古いブラウザは永遠にとどまるわけではないので、今準備ができていない会社はそのとき準備ができています。そして、誰かがオーディエンスの一部を破棄する準備ができていなくても、変更の準備ができていないという意味ではなく、後で変更を活用してより多くのオーディエンスを維持することを好むということです。
Finesse

19
@aoakeson IEは死にました。寿命の終わり。エッジも死にかけている、これは2019年の答えなので、IEは数えるべきではありません。IEは無地の色を使用することにより、優雅に低下させることができます。
シプリアン

5
私は驚くほど2019での応答のようなものに遭遇して驚い@aoakesonあなたはでしょう、このレベルにIEでSVGのサポートを前提とする開発者としてナイーブだろうこれまで、SOあなたの肥大化を与えるのはおろか新進開発者サポートされます、IEをサポートする場合に不必要に必要なものに対するポリフィルされた回答。
James Martin-Davies

18

Finesseが書いたものを基にして、svgをターゲットにしてグラデーションを変更する簡単な方法を次に示します。

これはあなたがする必要があることです:

  1. グラデーション要素で定義された各カラーストップにクラスを割り当てます。
  2. cssをターゲットにして、プレーンクラスを使用して各ストップのストップカラーを変更します。
  3. 勝つ!

代わりにクラスを使用するいくつかの利点は:nth-child、ストップを並べ替えても影響を受けないことです。また、これにより各クラスの意図が明確になります。最初の子に青色が必要か、2番目の子に青色が必要か疑問に思われることでしょう。

私はすべてのChrome、Firefox、IE11でテストしました:

.main-stop {
  stop-color: red;
}
.alt-stop {
  stop-color: green;
}
<svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <linearGradient id="gradient">
    <stop class="main-stop" offset="0%" />
    <stop class="alt-stop" offset="100%" />
  </linearGradient>
  <rect width="100" height="50" fill="url(#gradient)" />
</svg>

ここで編集可能な例を参照してください:https : //jsbin.com/gabuvisuhe/edit? html,css,output


欠けているのは、ストップクラスの名前が何であるか、またどのような順序であるかが確実にわからないことです。実際、解決策は同じで、唯一の違いはCSSセレクターです。
Finesse

3
これがOPの質問に対する最新の最良の答えだと思います。
Elemental

9

CSSのみを使用してグラデーションを追加し、その色を変更できるソリューションは次のとおりです。

// JS is not required for the solution. It's used only for the interactive demo.
const svg = document.querySelector('svg');
document.querySelector('#greenButton').addEventListener('click', () => svg.setAttribute('class', 'green'));
document.querySelector('#redButton').addEventListener('click', () => svg.setAttribute('class', 'red'));
svg.green stop:nth-child(1) {
  stop-color: #60c50b;
}
svg.green stop:nth-child(2) {
  stop-color: #139a26;
}

svg.red stop:nth-child(1) {
  stop-color: #c84f31;
}
svg.red stop:nth-child(2) {
  stop-color: #dA3448;
}
<svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <linearGradient id="gradient">
    <stop offset="0%" />
    <stop offset="100%" />
  </linearGradient>
  <rect width="100" height="50" fill="url(#gradient)" />
</svg>

<br/>
<button id="greenButton">Green</button>
<button id="redButton">Red</button>


2

正確な返信をありがとうございました。

影のドームでsvgを使用して、svg内のに必要な3つの線形グラデーションを追加します。cssフィルルールをWebコンポーネントに配置すると、継承odフィルが機能します。

<svg viewbox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
  <path
    d="m258 0c-45 0-83 38-83 83 0 45 37 83 83 83 45 0 83-39 83-84 0-45-38-82-83-82zm-85 204c-13 0-24 10-24 23v48c0 13 11 23 24 23h23v119h-23c-13 0-24 11-24 24l-0 47c0 13 11 24 24 24h168c13 0 24-11 24-24l0-47c0-13-11-24-24-24h-21v-190c0-13-11-23-24-23h-123z"></path>
</svg>

<svg height="0" width="0">
  <defs>
    <linearGradient id="lgrad-p" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#4169e1"></stop><stop offset="99%" stop-color="#c44764"></stop></linearGradient>
    <linearGradient id="lgrad-s" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#ef3c3a"></stop><stop offset="99%" stop-color="#6d5eb7"></stop></linearGradient>
    <linearGradient id="lgrad-g" gradientTransform="rotate(75)"><stop offset="45%" stop-color="#585f74"></stop><stop offset="99%" stop-color="#b6bbc8"></stop></linearGradient>
  </defs>
</svg>

<div></div>

<style>
  :first-child {
    height:150px;
    width:150px;
    fill:url(#lgrad-p) blue;
  }
  div{
    position:relative;
    width:150px;
    height:150px;
    fill:url(#lgrad-s) red;
  }
</style>
<script>
  const shadow = document.querySelector('div').attachShadow({mode: 'open'});
  shadow.innerHTML="<svg viewbox=\"0 0 512 512\">\
    <path d=\"m258 0c-45 0-83 38-83 83 0 45 37 83 83 83 45 0 83-39 83-84 0-45-38-82-83-82zm-85 204c-13 0-24 10-24 23v48c0 13 11 23 24 23h23v119h-23c-13 0-24 11-24 24l-0 47c0 13 11 24 24 24h168c13 0 24-11 24-24l0-47c0-13-11-24-24-24h-21v-190c0-13-11-23-24-23h-123z\"></path>\
  </svg>\
  <svg height=\"0\">\
  <defs>\
    <linearGradient id=\"lgrad-s\" gradientTransform=\"rotate(75)\"><stop offset=\"45%\" stop-color=\"#ef3c3a\"></stop><stop offset=\"99%\" stop-color=\"#6d5eb7\"></stop></linearGradient>\
    <linearGradient id=\"lgrad-g\" gradientTransform=\"rotate(75)\"><stop offset=\"45%\" stop-color=\"#585f74\"></stop><stop offset=\"99%\" stop-color=\"#b6bbc8\"></stop></linearGradient>\
  </defs>\
</svg>\
";
</script>

コードペンでテストを見る

1つ目は通常のSVGで、2つ目はシャドウDOM内にあります。


-4

ターゲット要素にlinearGradientを設定する方法は次のとおりです。

<style type="text/css">
    path{fill:url('#MyGradient')}
</style>
<defs>
    <linearGradient id="MyGradient">
        <stop offset="0%" stop-color="#e4e4e3" ></stop>
        <stop offset="80%" stop-color="#fff" ></stop>
    </linearGradient>
</defs>

質問の何もphpの使用を意味しません。
ACJ 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.