ChatGPT解决这个技术问题 Extra ChatGPT

SVG gradient using CSS

I'm trying to get a gradient applied to an SVG rect element.

Currently, I'm using the fill attribute. In my CSS file:

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

And the rect element has the correct fill color when viewed in the browser.

However, I'd like to know if I can apply a linear gradient to this element?


m
morkro

Just use in the CSS whatever you would use in a fill attribute. Of course, this requires that you have defined the linear gradient somewhere in your SVG.

Here is a complete example:

rect { cursor: pointer; shape-rendering: crispEdges; fill: url(#MyGradient); }


So I created that gradient in a separate file, and used fill this way: fill: url(../js/gradient.svg#MyGradient);. Is this the right way?
@HrishikeshChoudhari: Yes, this is correct, but Chrome and I think Safari as well don't support referencing elements from other files. Not sure about IE9 (can't test right now, just give it a try).
To anyone who reads this and asks "what about fill: linear-gradient (...)?" fill requires a <paint> which is built around the CSS2 <color> class. In other words, this answer is currently the only way to do it via CSS at the time I am writing this comment. You need to add a linearGradient element. Lastly, going through the w3 Working Draft for SVG2, it appears support for linear-gradient on the fill css rule has not and might not make it into the spec.
How to change the direction in this case?
@AwQiruiGuo Have a look at MDN (specifically the gradientTransform attribute)
C
Community

2019 Answer

With brand new css properties you can have even more flexibility with 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; }

Just set a named variable for each stop in gradient and then customize as you like in css. You can even change their values dynamically with javascript, like:

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

Not supported In IE.
@MaciejKwas, you are wrong. Old browsers don't stay forever so companies who are not ready now will be ready then. And if somebody isn't ready to discard a portion of his audience, it doesn't mean that he isn't ready for changes, it means he prefers to leverage the changes later to keep a bigger audience.
@aoakeson IE is dead. End of lifed. Edge is also dying, this is a 2019 answer, so IE shouldn't count. IE can degrade gracefully by using a solid colour.
@aoakeson I'm amazingly surprised to come across that kind of response in 2019. You'd be naive as a developer to assume SVG support in IE on this level would ever be supported, let alone a budding developer on SO giving you a bloated, polyfilled answer for something unnecessarily needed if you intend to support IE.
k
kumarharsh

Building on top of what Finesse wrote, here is a simpler way to target the svg and change it's gradient.

This is what you need to do:

Assign classes to each color stop defined in the gradient element. Target the css and change the stop-color for each of those stops using plain classes. Win!

Some benefits of using classes instead of :nth-child is that it'll not be affected if you reorder your stops. Also, it makes the intent of each class clear - you'll be left wondering whether you needed a blue color on the first child or the second one.

I've tested it on all Chrome, Firefox and IE11:

.main-stop { stop-color: red; } .alt-stop { stop-color: green; }

See an editable example here: https://jsbin.com/gabuvisuhe/edit?html,css,output


The lack is that you don't know for sure what the stop class names are and what order they have. Actually, the solutions are the same good, the only difference is the CSS selectors.
F
Finesse

Here is a solution where you can add a gradient and change its colours using only 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; }


G
GirkovArpa

Thank you everyone, for all your precise replys.

Using the svg in a shadow dom, I add the 3 linear gradients I need within the svg, inside a . I place the css fill rule on the web component and the inheritance od fill does the job.

The first one is normal SVG, the second one is inside a shadow dom.


a
axelparatre

Here is how to set a linearGradient on a target element:

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

Nothing in the question implies use of php.