I am trying to have an <img src="*.svg"> tag to display (any) svg file, however with what I have so far there is some overflow of the svg's viewbox when it fills the width:
If I did not need absolute positioning, it works without any overlfow if you remove display: inline-block and use max-width and max-height, but since I need the image to fill its container, I have to use inline-block.
Thanks in advance for any help .
#inner-map {
display: inline-block;
position: relative;
}
#map-svg {
border-style: solid;
}
#map-svg img {
width: 100%;
height: 80vh;
display: block;
}
#pog-outer {
position: absolute;
}
#pog-inner {
position: absolute;
left:-9px;
top:-9px;
}
<div id="inner-map">
<div id="pog-outer" style="top:58.794%;left:28.915%">
<div id="pog-inner">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="18" height="18">
<defs>
<radialGradient id="Shiny" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="#FFFFFF" />
<stop offset="50%" stop-color="#DD3333" />
<stop offset="75%" stop-color="#990000" />
<stop offset="100%" stop-color="#000000" />
</radialGradient>
</defs>
<circle r="6" cx="9" cy="9" fill="url(#Shiny)" />
</svg>
</div>
</div>
<div id="map-svg">
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/North_America_laea_location_map.svg">
</div>
</div>
Per the question's comments you want the image to fill the whole container and then if the aspect ratio of the image and its container differ, some edges of the image would overflow and are no longer be visible.
So to get that we'd want the image to have have preserveAspectRatio="xMidYMid slice" on its root element but unfortunately it doesn't. It doesn't have that attribute at all and the default if you have a viewBox is preserveAspectRatio="xMidYMid meet"
We'll need to override that value by using an SVG fragment identifier.
To make the example below more obvious I've also changed the width to width: 70vh; so it always overflows. You probably don't want to do that.
#inner-map {
display: inline-block;
position: relative;
}
#map-svg {
border-style: solid;
}
#map-svg img {
width: 70vh;
height: 80vh;
display: block;
}
#pog-outer {
position: absolute;
}
#pog-inner {
position: absolute;
left:-9px;
top:-9px;
}
<div id="inner-map">
<div id="pog-outer" style="top:58.794%;left:28.915%">
<div id="pog-inner">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="18" height="18">
<defs>
<radialGradient id="Shiny" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="#FFFFFF" />
<stop offset="50%" stop-color="#DD3333" />
<stop offset="75%" stop-color="#990000" />
<stop offset="100%" stop-color="#000000" />
</radialGradient>
</defs>
<circle r="6" cx="9" cy="9" fill="url(#Shiny)" />
</svg>
</div>
</div>
<div id="map-svg">
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/North_America_laea_location_map.svg#svgView(preserveAspectRatio(xMidYMid slice))">
</div>
</div>
You can replace the height: 80vh; with height: 80% in the element and this way it's going to always hide the non-blue svg part and without making any overflow.
#inner-map {
display: inline-block;
position: relative;
}
#map-svg {
border-style: solid;
}
#map-svg img {
width: 100%;
height: 80%;
display: block;
}
#pog-outer {
position: absolute;
}
#pog-inner {
position: absolute;
left:-9px;
top:-9px;
}
<div id="inner-map">
<div id="pog-outer" style="top:58.794%;left:28.915%">
<div id="pog-inner">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="18" height="18">
<defs>
<radialGradient id="Shiny" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="#FFFFFF" />
<stop offset="50%" stop-color="#DD3333" />
<stop offset="75%" stop-color="#990000" />
<stop offset="100%" stop-color="#000000" />
</radialGradient>
</defs>
<circle r="6" cx="9" cy="9" fill="url(#Shiny)" />
</svg>
</div>
</div>
<div id="map-svg">
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/North_America_laea_location_map.svg">
</div>
</div>
I have an svg like
<svg>
<linearGradient id="SVGID_124_" gradientUnits="userSpaceOnUse" x1="205.2935" y1="707.9475" x2="206.9863" y2="707.9475" gradientTransform="matrix(41.432 0 0 -41.432 -8114.9512 30139.9746)">
<stop offset="0" style="stop-color:#0071BC"/>
<stop offset="3.780070e-02" style="stop-color:#0071BC"/>
<stop offset="0.6151" style="stop-color:#00538B"/>
<stop offset="0.784" style="stop-color:#004C86"/>
<stop offset="0.9966" style="stop-color:#003B7C"/>
<stop offset="1" style="stop-color:#003B7C"/>
</linearGradient>
</svg>
I'm not sure how can I give this linear gradient as a background for a button. I tried the following, but I don't know how to give gradient transform in css.
.btn {
background: linear-gradient(to right, #0071BC 0%, #0071BC 37.80070%, #00538B 061.51%, #004C86 078.4%, #003B7C 099.66%, #003B7C 100%);
color: white;
border-radius: 8px;
/* border: 1px solid #00538B; */
width: 95%;
height: 25px;
padding: 0px;
}
<button class="btn">button</button>
Can somebody help?
It is expected to look like this
But i'm getting something like:
This is a close gradient in css.
.btn {
background: linear-gradient(to right, #0071bd 0%,#0171bb 39%,#016db5 41%,#005691 58%,#005691 59%,#01538b 61%,#014c86 78%,#003c7b 100%);
border-radius: 5px;
color: #fff;
border: none;
}
<button class="btn">Closed</button>
In generally, I'm using the gradient editor by colorzila to generate gradients from image / css / manually. May there are another tools.
You can use the SVG itself, BUT:
You have to make sure that the gradient's coordinates are right and feet to the element (aka .btn) which in this case, not.
You need to convert it to base64.
In the below snippet, for quick fixing, I created a script that read the svg in the html and convert it to base64 so you can tuning your gradient with it.
Also, I changed a little the SVG syntax, Take a look:
const svg = document.querySelector('svg').outerHTML;
const base64 = window.btoa(svg);
document.querySelector('.btn').style.backgroundImage = `url(data:image/svg+xml;base64,${base64})`;
.btn {
background: top repeat-x;
background-size: cover;
border-radius: 5px;
color: #fff;
border: none;
}
<button class="btn">Closed</button>
<svg width="1000px" height="30000px" xmlns="http://www.w3.org/2000/svg" style="display: none">
<linearGradient id="SVGID_124_" gradientUnits="userSpaceOnUse" x1="205.2935" y1="707.9475" x2="206.9863" y2="707.9475" gradientTransform="matrix(41.432 0 0 -41.432 -8114.9512 30139.9746)">
<stop offset="0" style="stop-color:#0071BC"/>
<stop offset="3.780070e-02" style="stop-color:#0071BC"/>
<stop offset="0.6151" style="stop-color:#00538B"/>
<stop offset="0.784" style="stop-color:#004C86"/>
<stop offset="0.9966" style="stop-color:#003B7C"/>
<stop offset="1" style="stop-color:#003B7C"/>
</linearGradient>
<g>
<rect fill="url(#SVGID_124_)" stroke-width="0" x="0" y="0" width="100%" height="100%" />
</g>
</svg>
I have an SVG image which I would like to change from a block colour to a gradient. I have got this working, however I would like to have a transition or animation. Is this possible - if so how would it be achieved?
http://jsfiddle.net/otaxjpa2/
HTML:
<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<defs>
<linearGradient id="gradient" gradientUnits="userSpaceOnUse" fy="90%" >
<stop offset="0" style="stop-color:#1EBEE0"/>
<stop offset="1" style="stop-color:#952491"/>
<animate attributeName="fy"from="0" to="1" dur="5s" repeatCount="indefinite" />
</linearGradient>
</defs>
<path id="time-3-icon" d="M256,50C142.229,50,50,142.229,50,256c0,113.77,92.229,206,206,206c113.77,0,206-92.23,206-206
C462,142.229,369.77,50,256,50z M256,417c-88.977,0-161-72.008-161-161c0-88.979,72.008-161,161-161c88.977,0,161,72.007,161,161
C417,344.977,344.992,417,256,417z M382.816,265.785c1.711,0.297,2.961,1.781,2.961,3.518v0.093c0,1.72-1.223,3.188-2.914,3.505
c-37.093,6.938-124.97,21.35-134.613,21.35c-13.808,0-25-11.192-25-25c0-9.832,14.79-104.675,21.618-143.081
c0.274-1.542,1.615-2.669,3.181-2.669h0.008c1.709,0,3.164,1.243,3.431,2.932l18.933,119.904L382.816,265.785z"/>
</svg>
CSS:
svg {
fill: blue;
transition: all 0.3s ease;
display: inline-block;
-webkit-transition: fill .4s ease;
-moz-transition: fill .4s ease;
-o-transition: fill .4s ease;
transition: fill .4s ease;
}
svg:hover {
fill: url(#gradient);
}
Any pointers would be much appreciated!
You can avoid using two rects by transitioning the stop-colors instead:
svg {
display: inline-block;
}
stop {
transition: .4s ease;
}
/* Use the colors to transition to */
svg:hover stop:first-child {
stop-color: #1EBEE0;
}
svg:hover stop:last-child {
stop-color: #952491;
}
<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<defs>
<linearGradient id="gradient" gradientUnits="userSpaceOnUse" fy="90%">
<stop offset="0" stop-color="blue" /> <!-- Colors to transition from -->
<stop offset="1" stop-color="blue" />
</linearGradient>
<mask id="clock-icon-mask" maskUnits="userSpaceOnUse" x="0" y="0" width="512" height="512">
<path d="M256,50C142.229,50,50,142.229,50,256c0,113.77,92.229,206,206,206c113.77,0,206-92.23,206-206C462,142.229,369.77,50,256,50z M256,417c-88.977,0-161-72.008-161-161c0-88.979,72.008-161,161-161c88.977,0,161,72.007,161,161C417,344.977,344.992,417,256,417z M382.816,265.785c1.711,0.297,2.961,1.781,2.961,3.518v0.093c0,1.72-1.223,3.188-2.914,3.505c-37.093,6.938-124.97,21.35-134.613,21.35c-13.808,0-25-11.192-25-25c0-9.832,14.79-104.675,21.618-143.081c0.274-1.542,1.615-2.669,3.181-2.669h0.008c1.709,0,3.164,1.243,3.431,2.932l18.933,119.904L382.816,265.785z"
fill="white" />
</mask>
</defs>
<g mask="url(#clock-icon-mask)">
<rect x="0" y="0" width="512" height="512" fill="url(#gradient)" />
</g>
</svg>
Here's a demo of the technique using a simplified shape (no mask required).
Put the two fill styles on overlapping <rect> objects, and use the clock icon as a mask object applied to both <rect> objects. You can then animate the apparent fill style by animating the opacity of the uppermost <rect>. Remember to apply a white fill to the mask object (white=opaque, black=transparent).
If the following snippet doesn't work, try this jsfiddle link.
#clock-gradient {
opacity: 0.0;
display: inline-block;
-webkit-transition: opacity .4s ease;
-moz-transition: opacity .4s ease;
-o-transition: opacity .4s ease;
transition: opacity .4s ease;
}
#clock-gradient:hover {
opacity: 1.0;
}
<svg width="96px" height="96px" viewBox="0 0 512 512" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="gradient" gradientUnits="userSpaceOnUse" fy="90%">
<stop offset="0" style="stop-color:#1EBEE0" />
<stop offset="1" style="stop-color:#952491" />
</linearGradient>
<mask id="clock-icon-mask" maskUnits="userSpaceOnUse" x="0" y="0" width="512" height="512">
<path d="M256,50C142.229,50,50,142.229,50,256c0,113.77,92.229,206,206,206c113.77,0,206-92.23,206-206C462,142.229,369.77,50,256,50z M256,417c-88.977,0-161-72.008-161-161c0-88.979,72.008-161,161-161c88.977,0,161,72.007,161,161C417,344.977,344.992,417,256,417z M382.816,265.785c1.711,0.297,2.961,1.781,2.961,3.518v0.093c0,1.72-1.223,3.188-2.914,3.505c-37.093,6.938-124.97,21.35-134.613,21.35c-13.808,0-25-11.192-25-25c0-9.832,14.79-104.675,21.618-143.081c0.274-1.542,1.615-2.669,3.181-2.669h0.008c1.709,0,3.164,1.243,3.431,2.932l18.933,119.904L382.816,265.785z" fill="white" />
</mask>
</defs>
<g mask="url(#clock-icon-mask)">
<rect x="0" y="0" width="512" height="512" fill="blue" />
<rect id="clock-gradient" x="0" y="0" width="512" height="512" fill="url(#gradient)" />
</g>
</svg>