133 votes

Dégradé SVG avec CSS

J'essaie d'appliquer un dégradé à un SVG. rect élément.

Actuellement, j'utilise le fill attribut. Dans mon fichier CSS :

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

Et le rect a la couleur de remplissage correcte lorsqu'il est affiché dans le navigateur.

Cependant, j'aimerais savoir si je peux appliquer un gradient linéaire à cet élément ?

128voto

Thomas W Points 4326

Il suffit d'utiliser dans le CSS ce que vous utiliseriez dans un fichier fill attribut. Bien entendu, cela suppose que vous ayez défini le gradient linéaire quelque part dans votre SVG.

Voici un exemple complet :

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>

58voto

Maciej Kwas Points 1102

Réponse de 2019

Grâce aux nouvelles propriétés css, vous pouvez bénéficier d'une flexibilité accrue avec les variables aka. 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>

Il suffit de définir une variable nommée pour chaque stop en dégradé, puis personnalisez comme vous le souhaitez en css. Vous pouvez même changer leurs valeurs dynamiquement avec javascript, comme :

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

30voto

Kumar Harsh Points 3960

En s'appuyant sur ce que Finesse a écrit, voici une manière plus simple de cibler le svg et de modifier son gradient.

C'est ce que vous devez faire :

  1. Attribuez des classes à chaque arrêt de couleur défini dans l'élément de gradient.
  2. Ciblez le css et changez la couleur d'arrêt pour chacun de ces arrêts en utilisant des classes simples.
  3. Gagnez !

Certains avantages de l'utilisation de classes au lieu de :nth-child est qu'il ne sera pas affecté si vous réorganisez vos arrêts. De plus, l'intention de chaque classe est claire - vous ne vous demanderez pas si vous aviez besoin d'une couleur bleue sur le premier ou le deuxième enfant.

Je l'ai testé sur tous les Chrome, Firefox et 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>

Voir un exemple modifiable ici : https://jsbin.com/gabuvisuhe/edit?html,css,output

11voto

Finesse Points 2058

Voici une solution qui vous permet d'ajouter un dégradé et de modifier ses couleurs en utilisant uniquement les 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>

5voto

Roland Gautier Points 305

Merci à tous, pour toutes vos réponses précises.

En utilisant le svg dans un shadow dom, j'ajoute les 3 dégradés linéaires dont j'ai besoin à l'intérieur du svg, dans un . Je place la règle de remplissage css sur le composant web et l'héritage od fill fait le travail.

    <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>

Le premier est un SVG normal, le second est à l'intérieur d'un shadow dom.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X