Okay... I'm going nuts over here. I've started experimenting with SVG. Working with SVG and applying CSS classes to it works like a charm. I just cant figure out what i'm doing wrong, but i just cant get the class to work on a svg text element. I've stripped it all the way down and this is what i got:
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Playground</title>
</head>
<body>
<style type="text/css">
.mainsvg {
height: 320px;
border: 1px solid red;
width: 400px;
}
.caption {
color: yellow;
}
</style>
<h2>SVG - Sandbox</h2>
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="mainsvg">
<text x="65" y="40" class="caption">Fact</text>
</svg>
</div>
</body>
</html>
According to http://www.w3.org/TR/SVG/styling.html#ClassAttribute this should work...
Any hints/tips on what to change, or an alternative?
Setting the class is correct but the CSS color property has no effect on SVG. SVG uses fill and stroke properties. In your case you probably just need to change color to fill. This displays yellow text for me in Firefox.
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Playground</title>
</head>
<body>
<style type="text/css">
.mainsvg {
height: 320px;
border: 1px solid red;
width: 400px;
}
.caption {
fill: yellow;
}
</style>
<h2>SVG - Sandbox</h2>
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="mainsvg">
<text x="65" y="40" class="caption">Fact</text>
</svg>
</div>
</body>
</html>
This is the top Google result for coloring SVG text and to make it very clear for rookies like me, to color an SVG text element in 2022, use stroke, and fill.
fill="red"
stroke="#0000FF"
Just like you use stroke for the outline color and fill for the inside color of a shape, you can do the same thing for text in SVGs.
And the best news is, if you use fill="currentColor" instead of a hard coded color, you can set the SVG text with CSS.
svg {
color: red;
}
Click run code snippet to see an example right in this answer.
<svg height="202" width="202">
<circle cx="101" cy="101" r="100"
stroke="red"
stroke-width="1"
fill="none"
/>
<!-- fill="currentColor" if you want to use CSS to set the color of SVG text -->
<text x="100" y="100"
text-anchor="middle"
fill="red"
stroke="#0000FF"
stroke-width="1px"
alignment-baseline="middle"
font-variant="all-small-caps"
font-size="25"
font-weight="bold"
>
Font is Colored
</text>
The accepted answer doesn't work for me either, so I did more research, and found a solution.
If you wrap the SVG <text .../> element in an <g .../> (group) element it can work:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="mainsvg">
<g class="caption">
<text x="65" y="40" fill="currentcolor">Fact</text>
</g>
</svg>
This applies the CSS to the <g>, and then the <text> element inherits the currentcolor of the parent into its fill (or stroke).
I'm trying to animate along a path based on this post: move SVG group on path trail based on percentage of whole path trail
It works beautifully in all browsers but Internet Explorer. I've read lots of posts about the lack of support in IE but I still have enough users that use it that I need to consider it. Can I convert this to another method?
Here is my code (simplified icon here, more complex icon in CodePen):
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Jeep Test 5</title>
<style type="text/css">
#carRight{visibility: visible;}
#carLeft{visibility: hidden;}
#carRightIsoBack {visibility: hidden;}
#carRightIsoFront {visibility: hidden;}
#carLeftIsoBack {visibility: hidden;}
#carLeftIsoFront {visibility: hidden;}
</style>
<script src="../SiteAssets/js/jquery-1.8.1.min.js"></script>
</head>
<body>
<input type="range" id="theRange" value="0"/>
<div id="percentage"></div>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 459 257" style="enable-background:new 0 0 459 257;" xml:space="preserve">
<style type="text/css">
#percentage{border:1px solid red; padding: 5px;}
svg{border:1px solid;overflow:visible; width:95vh; display:block; margin:1em auto;}
.st0{fill:none;stroke:#F1EA0D;stroke-width:5;stroke-miterlimit:10;}
.st1{fill:#1A1A1A;}
.st2{fill:#FF0000;}
</style>
<defs>
<g id="carRight" transform="translate(-90, -240)">
<circle class="st3" cx="134.5" cy="215.2" r="12"/>
</g>
</defs>
<path id="path" class="st0" d="M20.5,249.5c0,0,27,0,54,1s47.36-5,61-13c40.32-23.66,50.1-50.05,3-82c-35.12-23.83-65-19-97-44
c-22.4-17.5-21.92-28.85-1-41c31-18,101.15-43.54,158-27c55,16,48,30,45,61s-8,39-13,60s5.09,40.12,17,56c18,24,56.49,26.8,81,17
c10-4,33-17,29-48c-3.36-26.03-15-34-30-53s-4.97-25.67,7-27c18-2,32.57-1.81,59,7c24,8,54,9,65,4s1-22-9-32s-14-17-30-24
s-34-8-53-3s-28,11-44,14s-26-10-18-25s22-28,42-38c4-2,9-4,9-4"/>
<use id="theUse_car_right" transform="translate(0,20)" xlink:href="#carRight" />
</svg>
<script type="text/javascript">
let pathlength = path.getTotalLength();
let pos = path.getPointAtLength(0);
theUse_car_right.setAttributeNS(null,"x", pos.x);
theUse_car_right.setAttributeNS(null,"y", pos.y);
document.getElementById("percentage").textContent = "Completion=0%";
theRange.addEventListener("input", ()=>{
let perc = parseInt(theRange.value);
let leng = pathlength * perc/100;
pos = path.getPointAtLength(leng);
theUse_car_right.setAttributeNS(null,"x", pos.x);
theUse_car_right.setAttributeNS(null,"y", pos.y);
document.getElementById("percentage").textContent = "Completion=" + perc + "%";
})
</script>
</body>
</html>
Demo'd here: https://codepen.io/mrsgorgon/pen/ExNbEPN
The issue of your code is in the JavaScript.
Arrow function => is not supported in IE. You need to use the traditional function expression.
The input event on input range won't be triggerrd in IE. You need to use change event to monitor the change of the input range. But change event won't be triggered in other modern browsers, so we need to combine the two event handlers.
I define the function as moveit and combine the two event handlers like this:
<input type="range" id="theRange" value="0" oninput="moveit()" onchange="moveit()" />
The complete sample code is like this:
let pathlength = path.getTotalLength();
let pos = path.getPointAtLength(0);
theUse_car_right.setAttributeNS(null, "x", pos.x);
theUse_car_right.setAttributeNS(null, "y", pos.y);
document.getElementById("percentage").textContent = "Completion=0%";
function moveit() {
let perc = parseInt(theRange.value);
let leng = pathlength * perc / 100;
pos = path.getPointAtLength(leng);
theUse_car_right.setAttributeNS(null, "x", pos.x);
theUse_car_right.setAttributeNS(null, "y", pos.y);
document.getElementById("percentage").textContent = "Completion=" + perc + "%";
}
#carRight {
visibility: visible;
}
#carLeft {
visibility: hidden;
}
#carRightIsoBack {
visibility: hidden;
}
#carRightIsoFront {
visibility: hidden;
}
#carLeftIsoBack {
visibility: hidden;
}
#carLeftIsoFront {
visibility: hidden;
}
#percentage {
border: 1px solid red;
padding: 5px;
}
svg {
border: 1px solid;
overflow: visible;
width: 95vh;
display: block;
margin: 1em auto;
}
.st0 {
fill: none;
stroke: #F1EA0D;
stroke-width: 5;
stroke-miterlimit: 10;
}
.st1 {
fill: #1A1A1A;
}
.st2 {
fill: #FF0000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<input type="range" id="theRange" value="0" oninput="moveit()" onchange="moveit()" />
<div id="percentage"></div>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 459 257" style="enable-background:new 0 0 459 257;" xml:space="preserve">
<defs>
<g id="carRight" transform="translate(-90, -240)">
<circle class="st3" cx="134.5" cy="215.2" r="12" />
</g>
</defs>
<path id="path" class="st0" d="M20.5,249.5c0,0,27,0,54,1s47.36-5,61-13c40.32-23.66,50.1-50.05,3-82c-35.12-23.83-65-19-97-44
c-22.4-17.5-21.92-28.85-1-41c31-18,101.15-43.54,158-27c55,16,48,30,45,61s-8,39-13,60s5.09,40.12,17,56c18,24,56.49,26.8,81,17
c10-4,33-17,29-48c-3.36-26.03-15-34-30-53s-4.97-25.67,7-27c18-2,32.57-1.81,59,7c24,8,54,9,65,4s1-22-9-32s-14-17-30-24
s-34-8-53-3s-28,11-44,14s-26-10-18-25s22-28,42-38c4-2,9-4,9-4" />
<use id="theUse_car_right" transform="translate(0,20)" xlink:href="#carRight" />
</svg>
I have an array of svg objects that I need to use. Each svg is inserted at two different sections of the HTML when the page is loaded and only one section is displayed at a given time. I use the display property and media queries to hide/unhide the complete section containing the SVGs and other tags.
Each SVG have at least two parts (A/B); part A is a single color but part B use a LinearGradient for Fill.
This method works fine in Chrome, and IE explorer but Firefox does not display part B of the SVG when the media query is called.
I tried changing the id of the linearGradient url to a class, removed the tags, use the and tags, changed the display property types, but nothing worked.
This is simplyfied version of the problem:
https://codepen.io/eddieWin/pen/JOoMLe
Thanks for any help you can give me.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<style type="text/css">
#one{
display: block;
}
#two{
display: none;
}
.svgIcon{
display: inline-block;
border: 2px solid red;
}
#container{
display: flex;
}
#media screen and (min-width: 568px) {
#one{
display: none;
}
#two{
display: block;
}
}
</style>
</head>
<body>
<section id="one">
<h1>One</h1>
<div class="svgContainer"></div>
</section>
<section id="two">
<div id="container">
<div>
<div class="svgContainer"></div>
</div>
<h1>Two</h1>
</div>
</section>
<script type="text/javascript">
var svgIcons = {
'svg1' : '\
<div class="svgIcon">\
<svg version="1.1" class="infoIcon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\
width="72px" height="70px" viewBox="0 0 72 70">\
<defs>\
<linearGradient id="info_1_" gradientUnits="userSpaceOnUse" x1="32.895" y1="49.7476" x2="32.895" y2="28.2964">\
<stop offset="0" style="stop-color:#ff88ff"/>\
<stop offset="1" style="stop-color:#88dddd"/>\
</linearGradient>\
</defs>\
<circle cx="35" cy="35" r="30" fill="#555555"/>\
<circle cx="35" cy="35" r="20" fill="url(#info_1_)"/>\
</svg>\
</div>'
}
var svgContainers = document.getElementsByClassName('svgContainer');
for(var i = 0; i < svgContainers.length; i++){
svgContainers[i].innerHTML = svgIcons['svg1'];
}
</script>
</body>
</html>
after my firefox update to version 35.0.1 my svg animations doesn't work in firefox, but it was working in previous versions and it still works in firefox beta (36), nightly (37.0a2) and other browsers (opera, chrome, safari, modern ie):
html:
<svg version="1.1" id="logo-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="55px" height="53.758px" viewBox="-1061.986 3038.43 55 53.758" enable-background="new -1061.986 3038.43 188.279 53.758" xml:space="preserve">
<g id="logo-mask" >
<rect id="sygnet" fill="#FFFFFF" x="-1100" y="3038" width="100" height="50"/>
</g>
<g id="logo-black">
<rect id="sygnet" fill="#000000" x="-1100" y="3038" width="100" height="50"/>
</g>
</svg>
<div id="button">Click me!</div>
css:
body{
background-color: #777777;
}
#button{
margin-right: 100px;
display: block;
width: 100px;
height: 20px;
float: right;
background-color: #fff;
cursor: pointer;
text-align: center;
line-height: 20px;
}
js (using snap.svg):
$(document).ready(function(){
var s = Snap(),
svg = Snap.select('#logo-svg'),
logo = Snap.select('#logo-mask'),
logoBlack = Snap.select('#logo-black'),
mask = svg.rect(-1100, 2830, 280, 100).attr({
fill: 'white',
id: 'maska-logo'
});
logoBlack.attr({'mask': mask, 'opacity': 1});
});
$(document).on('click', '#button', function(){
var maska = Snap.select('#maska-logo');
maska.animate({
transform: 'T'+[0,200]
}, 500);
});
simple example: http://jsfiddle.net/7yq14L0f/2/
any idea, why? :(
It was caused by a change in the Firefox code which was not completely correct and which was then fixed. Bug 932771 caused it and bug 1127507 which was backported as far as Firefox 36 fixed it.
I'm trying to delete the corners of an img element:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
<body>
<style type="text/css">
#div { background: #ffffff; width: 500px; height: 300px; padding: 10px; }
#div img { background: #000000; }
</style>
<div id="div"><img src="http://maps.google.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=14&size=500x300&sensor=false" alt="" class="t" /></div>
<style>.t { clip-path: url(#c1); }</style>
<svg:svg height="0">
<svg:clipPath id="c1" clipPathUnits="objectBoundingBox">
<svg:polyline x="0" y="0" width="0.5" height="0.5" points="0,60 20,20 40, 100, 60,40, 80,100, 100,40 120,100" fill="red" stroke="black" />
</svg:clipPath>
</svg:svg>
</body>
</html>
But the image disapears?!
I wanted that the red marked areas will be "removed"/disapear and I don't get it work:
First, make sure your document is served as XHTML, not HTML. SVG clipping won't work otherwise. Fix your URL to use & instead of &.
Then, remove the clipPathUnits="objectBoundingBox" or you won't get absolute coordinates. Finally, fix your path by using the following points which should get the shape you need: 0,20 125,0 250,20 375,0 500,20 500,300 0,300.
The final document will look like this:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
<body>
<style type="text/css">
#div { background: #ffffff; width: 500px; height: 300px; padding: 10px; }
#div img { background: #000000; }
</style>
<div id="div"><img src="http://maps.google.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=14&size=500x300&sensor=false" alt="" class="t" /></div>
<style>.t { clip-path: url(#c1); }</style>
<svg:svg height="0">
<svg:clipPath id="c1">
<svg:polyline points="0,20 125,0 250,20 375,0 500,20 500,300 0,300" />
</svg:clipPath>
</svg:svg>
</body>
</html>