SVG - Filling Rectangle with Jet Colour Scheme - html

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.

Related

In an SVG, can you reuse a common linearGradient but change the colors from CSS?

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>

SVG Linear gradient, UserSpaceOnUse

I am trying to get a linear gradient to work with gradientUnits='userSpaceOnUse' but for some reason the gradient is not applied.Take a look at the following code.
<svg width="500" height="500" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="user-grad" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse">
<stop stop-color="orange" offset="0"></stop>
<stop stop-color="blue" offset="1"></stop>
</linearGradient>
<linearGradient id="object-grad" x1="0" y1="0" x2="1" y2="0">
<stop stop-color="orange" offset="0"></stop>
<stop stop-color="blue" offset="1"></stop>
</linearGradient>
</defs>
<rect x="0" y="0" width="200" height="100" fill="url(#user-grad)"/>
<rect x="250" y="0" width="200" height="100" fill="url(#object-grad)"/>
</svg>
The first rect has the gradientUnits attribute applied and the second one does not. The gradient works well the second one but not the first one. How do I get the first one to look like the second one

SVG does not line up correctly with aspect ratio

I've been trying to solve this for a while now and can't get the SVGs to align correctly for some width and height. My viewBox has 16:9 aspect ratio and I would like to scale the SVG by the same aspect ratio. For some width and height, it does line correctly but for others it doesn't although both have the same aspect ratio.
Any hints on what is causing this?
I have a JSFiddle for you to try, https://jsfiddle.net/n90ty8ys/1/
<svg id="svg-main-panel" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 768 432" preserveAspectRatio="xMinYMin meet" width="1120" height="630">
<rect xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="200" height="200" fill="blue"></rect>
<svg width="20" height="40" x="20" y="20">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="657.247" y1="172.823" x2="657.247" y2="152.907" gradientTransform="rotate(90 405.13 -232.117)">
<stop offset="0" stop-color="#BDCCD4"></stop>
<stop offset=".5" stop-color="#EBF0F2"></stop>
<stop offset="1" stop-color="#BDCCD4"></stop>
</linearGradient>
<path fill="url(#a)" d="M20 0H.034L0 40h19.966"></path>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" x="20" y="60">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="19.775" y1="30" x2="-.14" y2="30">
<stop offset="0" stop-color="#BDCCD4" />
<stop offset=".5" stop-color="#EBF0F2" />
<stop offset="1" stop-color="#BDCCD4" />
</linearGradient>
<path fill="url(#a)" d="M-.034 20h20v20h-20z" />
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="-1207.701" y1="556.747" x2="-1207.701" y2="576.663" gradientTransform="matrix(0 -1 -1 0 576.556 -1188.2)">
<stop offset="0" stop-color="#BDCCD4" />
<stop offset=".5" stop-color="#EBF0F2" />
<stop offset="1" stop-color="#BDCCD4" />
</linearGradient>
<path fill="url(#b)" d="M0 40l19.966-20L20-1H0" />
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="-847.237" y1="1808.924" x2="-847.237" y2="1828.84" gradientTransform="matrix(-1 0 0 1 -826.737 -1788.733)">
<stop offset="0" stop-color="#BDCCD4" />
<stop offset=".5" stop-color="#EBF0F2" />
<stop offset="1" stop-color="#BDCCD4" />
</linearGradient>
<path fill="url(#c)" d="M41 40V20H19.934L0 40h19.968" />
</svg>
</svg>
Updates
Originally I thought viewBox and svg had different ratio, which actually had the same. I updated #2 below accordingly.
I see two potential issues:
Your <path> elements have decimal numbers in d attribute. As browsers rendering unit is pixel (integer), it might misalign your SVG elements. In the below snippet, I changed all the decimal numbers in d attributes to integers. For example, I changed <path fill="url(#c)" d="M41 40V20H19.934L0 40h19.968" /> to <path fill="url(#c)" d="M41 40V20H20L0 40h20" />.
Your base <svg>’s viewBox size, especially ratio, is different from width and height attribute value. Your viewBox width and height is 768 and 432 respectively, while your <svg> has width="1120" height="630" for its size value. That difference makes the SVG skewed unexpectedly and might produce decimal-based rendering that causes pixel misalignment in the browser. As viewBox vs <svg> size ratio is 1:1.46 (1120/768), it could render misaligned elements. There is a great article by Sara Soueidan about how to configure your viewBox numbers.
I applied those two changes in the snippet below, and it seems to work fine. Good luck!
<svg id="svg-main-panel" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1120 630" preserveAspectRatio="xMinYMin meet" width="1120" height="630">
<rect xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="200" height="200" fill="blue"></rect>
<svg width="20" height="40" x="20" y="20">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="657.247" y1="172.823" x2="657.247" y2="152.907" gradientTransform="rotate(90 405.13 -232.117)">
<stop offset="0" stop-color="#BDCCD4"></stop>
<stop offset=".5" stop-color="#EBF0F2"></stop>
<stop offset="1" stop-color="#BDCCD4"></stop>
</linearGradient>
<path fill="url(#a)" d="M20 0H0L0 40h20"></path>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" x="20" y="60">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="19.775" y1="30" x2="-.14" y2="30">
<stop offset="0" stop-color="#BDCCD4" />
<stop offset=".5" stop-color="#EBF0F2" />
<stop offset="1" stop-color="#BDCCD4" />
</linearGradient>
<path fill="url(#a)" d="M0 20h20v20h-20z" />
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="-1207.701" y1="556.747" x2="-1207.701" y2="576.663" gradientTransform="matrix(0 -1 -1 0 576.556 -1188.2)">
<stop offset="0" stop-color="#BDCCD4" />
<stop offset=".5" stop-color="#EBF0F2" />
<stop offset="1" stop-color="#BDCCD4" />
</linearGradient>
<path fill="url(#b)" d="M0 40l20-20L20-1H0" />
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="-847.237" y1="1808.924" x2="-847.237" y2="1828.84" gradientTransform="matrix(-1 0 0 1 -826.737 -1788.733)">
<stop offset="0" stop-color="#BDCCD4" />
<stop offset=".5" stop-color="#EBF0F2" />
<stop offset="1" stop-color="#BDCCD4" />
</linearGradient>
<path fill="url(#c)" d="M41 40V20H20L0 40h20" />
</svg>
</svg>

Apply an opacity mask with CSS3

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

CSS background image not positioning bottom

I'm having an odd issue happen when trying to position an SVG at the bottom of a div:
http://jsfiddle.net/GsPhA/2/
The svg source is listed below:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad" x1="0" y1="0" x2="100%" y2="0">
<stop offset="0" stop-color="#FFF" />
<stop offset="0.1" stop-color="#FFF" />
<stop offset="0.5" stop-color="#B1B1B1" />
<stop offset="0.9" stop-color="#FFF" />
<stop offset="1" stop-color="#FFF" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100%" height="1px" style="fill:url(#grad)" />
</svg>
How can I get the svg to appear below the text (like a border-bottom)?
I'm not entirely fussed about earlier browsers, if it requires CSS 3 properties I'm happy!
EDIT: If there is no better way than absolute positioning, I will just add another div below to provide the effect.
EDIT 2: I'm not sure what I need to do differently with SVG, but positioning bottom with PNG works just fine: http://jsfiddle.net/YXRQX/1/
Is there anything I need to specify in the SVG code so it works properly?
EDIT 3: Final working jsFiddle here: http://jsfiddle.net/GsPhA/4/ Thank you To Ryan for the pointer!
Done it! Thanks to Ryan's pointer, I've added the background-size css property to fix the size to 1px high:
.ucp-controls {
text-align: center;
margin-top: 10px;
padding-bottom: 2px;
margin-bottom: 5px;
color: #242424;
cursor: default;
background: url('http://priddle.serveblog.net/sums2/images/header/line.png') bottom no-repeat;
background-size: 100% 1px; // The key line; preserves the width but locks the height.
font-family: Arial;
}​
In the end, the SVG was resizing itself based on the size of the container it was being the background for.
As long as both are in the same container, the text should go above the SVG object like below:
<center>
<p>Sample Text Here</p>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad" x1="0" y1="0" x2="100%" y2="0">
<stop offset="0" stop-color="#FFF" />
<stop offset="0.1" stop-color="#FFF" />
<stop offset="0.5" stop-color="#B1B1B1" />
<stop offset="0.9" stop-color="#FFF" />
<stop offset="1" stop-color="#FFF" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100%" height="1px" style="fill:url(#grad)" />
</svg>
</center>