In an SVG, can you reuse a common linearGradient but change the colors from CSS?
I have the following HTML:
<svg viewBox="0 0 240 240" xmlns="http://www.w3.org/2000/svg" width="240" height="240">
<defs>
<linearGradient id="sharedGradient" class="grad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="var(--color-top)" />
<stop offset="100%" stop-color="var(--color-bot)" />
</linearGradient>
</defs>
<g transform="translate(0, 0)">
<rect class="node" width="100" height="100" x="0" y="0"></rect>
</g>
<g transform="translate(120, 0)">
<rect class="node green" width="100" height="100" x="0" y="0"></rect>
</g>
</svg>
...and the following CSS:
.node {
fill: url(#sharedGradient) #00FF00;
}
#sharedGradient {
--color-top: #f12c06;
--color-bot: #faed34;
}
.green #sharedGradient {
--color-top: #00ff00;
--color-bot: #00dd00;
}
But I can't find a way to alter the color stops of the gradient without duplicating the whole tag in the SVG.
Like #Kaiido mentioned, the linearGradient just needs to be in the svg part that is being reused via <use href="..." />, then in Firefox that can be styled with css-variables. In chrome only the default values will be shown.
#svg1 {
stroke: url(#gradient);
}
#svg2 {
stroke: url(#gradient);
--color-top: blue;
--color-bot: red;
}
#svg3 {
stroke: url(#cantBeStyled); // but reused
--color-top: violet;
--color-bot: indigo;
}
<html>
<div>
<svg id="svg1">
<defs>
<linearGradient id="cantBeStyled" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="var(--color-top, green)" />
<stop offset="100%" stop-color="var(--color-bot, yellow)" />
</linearGradient>
</defs>
<g id="toReuse">
<linearGradient id="gradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="var(--color-top, green)" />
<stop offset="100%" stop-color="var(--color-bot, yellow)" />
</linearGradient>
<rect width="100" height="100" x="0" y="0" stroke-width="20"></rect>
</g>
</svg>
</div>
<div>CSS-variables work in Firefox, in chrome all gradients are green-yellow as defined as defaults in the svg</div>
<div>
can be styled via css variables
<svg id="svg2">
<use href="#toReuse"></use>
</svg>
</div><br /><br/><br/>
<div>
can't be styled
<svg id="svg3">
<use href="#toReuse"></use>
</svg>
</div>
</html>
There is an example with group of two paths, group filled by gradient.
<svg height="1000" width="1400">
<defs>
<linearGradient id="lingrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="green" />
</linearGradient>
</defs>
<g fill="url(#lingrad)">
<path d="M501.333,490.667H10.667C4.779,490.667,0,495.445,0,501.333C0,507.221,4.779,512,10.667,512h490.667
c5.888,0,10.667-4.779,10.667-10.667C512,495.445,507.221,490.667,501.333,490.667z"/>
<path d="M96,362.667H32c-5.888,0-10.667,4.779-10.667,10.667v128C21.333,507.221,26.112,512,32,512h64
c5.888,0,10.667-4.779,10.667-10.667v-128C106.667,367.445,101.888,362.667,96,362.667z M85.333,490.667H42.667V384h42.667
V490.667z"/>
</g>
</svg>
But each path is filled by its own gradient.
How do I fill all paths by one shared gradient?
By just creating one path.
Just add the d tag of one path to the d tag of the other path:
<path d="M501.333,490.667H10.667C4.779,490.667,0,495.445,0,501.333C0,507.221,4.779,512,10.667,512h490.667
c5.888,0,10.667-4.779,10.667-10.667C512,495.445,507.221,490.667,501.333,490.667z"/>
<path d="M96,362.667H32c-5.888,0-10.667,4.779-10.667,10.667v128C21.333,507.221,26.112,512,32,512h64
c5.888,0,10.667-4.779,10.667-10.667v-128C106.667,367.445,101.888,362.667,96,362.667z M85.333,490.667H42.667V384h42.667
V490.667z"/>
<svg height="1000" width="1400">
<defs>
<linearGradient id="lingrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="green" />
</linearGradient>
</defs>
<g fill="url(#lingrad)">
<path d="M501.333,490.667H10.667C4.779,490.667,0,495.445,0,501.333C0,507.221,4.779,512,10.667,512h490.667
c5.888,0,10.667-4.779,10.667-10.667C512,495.445,507.221,490.667,501.333,490.667zM96,362.667H32c-5.888,0-10.667,4.779-10.667,10.667v128C21.333,507.221,26.112,512,32,512h64
c5.888,0,10.667-4.779,10.667-10.667v-128C106.667,367.445,101.888,362.667,96,362.667z M85.333,490.667H42.667V384h42.667
V490.667z"/>
</g>
</svg>
Define the gradient dimensions not relative to the object bounding box (of the individual shapes, gradientUnits="objectBoundingBox" is the default), but relative to the local coordinate system of the <g> element (gradientUnits="userSpaceOnUse").
<svg height="1000" width="1400">
<defs>
<linearGradient id="lingrad" x1="0" y1="0" x2="512" y2="0" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="green" />
</linearGradient>
</defs>
<g fill="url(#lingrad)">
<path d="M501.333,490.667H10.667C4.779,490.667,0,495.445,0,501.333C0,507.221,4.779,512,10.667,512h490.667
c5.888,0,10.667-4.779,10.667-10.667C512,495.445,507.221,490.667,501.333,490.667z"/>
<path d="M96,362.667H32c-5.888,0-10.667,4.779-10.667,10.667v128C21.333,507.221,26.112,512,32,512h64
c5.888,0,10.667-4.779,10.667-10.667v-128C106.667,367.445,101.888,362.667,96,362.667z M85.333,490.667H42.667V384h42.667
V490.667z"/>
</g>
</svg>
What is the correct way to fill an SVG rectangle with jet colour scheme? Using multiple stops in linearGradient does not seem to work.
Edit, I am trying to fill the a rectangle with one of the following colour gradient.
I edited the MDN code with a rainbow example
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Gradients -->
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="#d30000"/>
<stop offset="30%" stop-color="#ffff05"/>
<stop offset="50%" stop-color="#05ff05"/>
<stop offset="70%" stop-color="#05ffff"/>
<stop offset="100%" stop-color="#041ae0"/>
</linearGradient>
</defs>
<rect x="10" y="10" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/>
</svg>
in a fiddle: https://jsfiddle.net/9bmvr5hd/
The BbwrR gradient is the example used in Mozilla's SVG - Gradients documentation:
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="Gradient1">
<stop class="stop1" offset="25%"/>
<stop class="stop2" offset="50%"/>
<stop class="stop3" offset="75%"/>
</linearGradient>
<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
<stop offset="25%" stop-color="blue"/>
<stop offset="50%" stop-color="black" stop-opacity="0"/>
<stop offset="75%" stop-color="red"/>
</linearGradient>
<style type="text/css"><![CDATA[
#rect1 { fill: url(#Gradient1); }
.stop1 { stop-color: blue; }
.stop2 { stop-color: black; stop-opacity: 0; }
.stop3 { stop-color: red; }
]]></style>
</defs>
<rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100"/>
<rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/>
</svg>
I swapped the location of the red and blue and adjusted the offset percentages to try to make it look more like your image. You should be able to just change the colors and add/remove stops for the others.
I'm trying to apply a CSS Mask to fade a DIV horizontally in both direction.
I created the mask with an online editor and it works smoothly using -webkit-mask and base64 encoding:
#slicenter{-webkit-mask: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+gAAAAUCAYAAAAeGxcbAAACWUlEQVR4Xu3bQU4DMQwFUHoH4P7ng94BGkSlyKQjRv6bqG8kVKVgd/rqjflwefl7vZWnxvly+/r6fXwt59XP31u8T3WjfnWeX672Olu/eDueIkCAAAECBAgQIECAAIEnEvgse+i1nMf352t1vu+/4/GovtZ+lH15dX742mPxrtfZpfhoqT6zzI/76Pwy4InmzVslQIAAAQIECBAgQIAAgQcC0aX59hpHS3dy2f9JxuslQTfnBAgQIECAAAECBAgQILCrgAR9+uTmBF6CvutIu28CBAgQIECAAAECBAjsKSBBnz63OYFP/rn8f/6Hfc/xcdcECBAgQIAAAQIECBAgkBKQoEvQU7OkDwECBAgQIECAAAECBAg0BCToEvTG+CglQIAAAQIECBAgQIAAgZSABF2CnpolfQgQIECAAAECBAgQIECgISBBl6A3xkcpAQIECBAgQIAAAQIECKQEJOgS9NQs6UOAAAECBAgQIECAAAECDQEJugS9MT5KCRAgQIAAAQIECBAgQCAlIEGXoKdmSR8CBAgQIECAAAECBAgQaAhI0CXojfFRSoAAAQIECBAgQIAAAQIpAQm6BD01S/oQIECAAAECBAgQIECAQENAgi5Bb4yPUgIECBAgQIAAAQIECBBICUjQJeipWdKHAAECBAgQIECAAAECBBoCEnQJemN8lBIgQIAAAQIECBAgQIBASkCCLkFPzZI+BAgQIECAAAECBAgQINAQkKBL0Bvjo5QAAQIECBAgQIAAAQIEUgISdAl6apb0IUCAAAECBAgQIECAAIGGwLYJ+jfSylgzQ2my8wAAAABJRU5ErkJggg==);}
The problem is: this works just on Chrome (and maybe Safari).
So I tried to export the same image to HTML/SVG. This is what I got:
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="200px" >
<defs>
<linearGradient id="lgrad" x1="0%" y1="50%" x2="100%" y2="50%" >
<stop offset="0%" style="stop-color:rgb(0,0,0);stop-opacity:0" />
<stop offset="5%" style="stop-color:rgb(0,0,0);stop-opacity:1" />
<stop offset="95%" style="stop-color:rgb(0,0,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(0,0,0);stop-opacity:0" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#lgrad)"/>
</svg>
And then I tried to convert this vector in a mask (but it's probably wrong):
<svg height="0" >
<defs>
<linearGradient id="g" gradientUnits="objectBoundingBox" x1="0%" y1="50%" x2="100%" y2="50%" >
<stop offset="0%" style="stop-color:rgb(0,0,0);stop-opacity:0" />
<stop offset="5%" style="stop-color:rgb(0,0,0);stop-opacity:1" />
<stop offset="95%" style="stop-color:rgb(0,0,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(0,0,0);stop-opacity:0" />
</linearGradient>
<mask id="lgrad" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<rect x="0" y="0" width="100%" height="100%" fill="url(#g)"/>
</mask>
</defs>
</svg>
I applied the mask to the same element with:
#slicenter{mask: url(#lgrad);}
But it doesn't works. Any Ideas?
Cheers