Why is standalone rendered differently than inline SVG in multiple browsers? - html

This arrow renders just fine when you save it as arrow.html and open it in a modern browser. (Edge, Firefox, Chrome).
<!DOCTYPE html>
<svg
width="490" height="385"
viewBox="0 0 490 385">
<defs>
<marker id="arrow-b" markerWidth="10" markerHeight="10" refx="3" refy="2" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,4 L6,2 z" fill="#000" />
</marker>
<marker id="arrow-a" markerWidth="10" markerHeight="10" refx="3" refy="2" orient="auto" markerUnits="strokeWidth">
<path d="M0,2 L6,0 L6,4 z" fill="#000" />
</marker>
</defs>
<line x1="10" y1="10" x2="480" y2="370" stroke="#000" stroke-width="2" marker-end="url(#arrow-b)" marker-start="url(#arrow-a)" />
</svg>
But having that inline in an HTML file makes it hard to reuse, so I saved the following into arrow.svg and opened that in my browser, and it looks wrong:
<?xml version="1.0" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="490" height="385"
viewBox="0 0 490 385">
<defs>
<marker id="arrow-b" markerWidth="10" markerHeight="10" refx="3" refy="2" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,4 L6,2 z" fill="#000" />
</marker>
<marker id="arrow-a" markerWidth="10" markerHeight="10" refx="3" refy="2" orient="auto" markerUnits="strokeWidth">
<path d="M0,2 L6,0 L6,4 z" fill="#000" />
</marker>
</defs>
<line x1="10" y1="10" x2="480" y2="370" stroke="#000" stroke-width="2" marker-end="url(#arrow-b)" marker-start="url(#arrow-a)" />
</svg>
What's interesting is that it looks wrong in Firefox, Chrome and Edge. So, maybe I'm doing something wrong? Does anybody know what I'm doing wrong?

standalone SVG is XML based which is case sensitive.
HTML is not case sensitive and when you embed SVG in HTML the HTML parser tries to fix up any case sensitivity issues for you.
You have the marker refX and refY attributes entirely in lower case which is invalid and causes them to be ignored in a standalone file.

Related

Arrow not able to draw in exact 90 deg using div tag in html

I am drawing an arrow using div tag in html. It is working fine. But the issue is, when I am trying to draw it in exact 90 deg, it is disappearing. Can someone help me find the issue?
<div class="object-added arrowline" style="top:${shapeValues.top}px; left:${shapeValues.left}px">
<svg height="0" width="0">
<defs>
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
</marker>
</defs>
<defs>
<marker id="markerArrowEnd" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto">
<path d="M10, 2 L10,11 L2,6 L10, 2" style="fill: #000000;" />
</marker>
</defs>
<line x1="0" y1="0" x2="0" y2="0" vector-effect="non-scaling-stroke" style="stroke:rgb(0,0,0);stroke-width:1" />
</svg>
</div>

How can I make the markers overlap perfectly so it doesn't appear twice for the same end?

I am trying to implement a highlight feature that makes the arrow bigger and changes its color. but the problem is when the width change, one of the two end markers (arrowhead) becomes bigger, but also doesn't overlap on the smaller one. how can I make it overlap so they appear as one bigger arrowhead instead of two
without highlight
with highlight
my code
render() {
const [start, target] = this.props.points;
const activeColor = !this.state.isActive ? "#6b6b6b" : "#ffa500";
const arrowWidth = !this.state.isActive ? "1" : "2";
return (
<g>
{
this.props.IsNotDot &&
<line
x1={start.x}
y1={start.y}
x2={target.x}
y2={target.y}
stroke={activeColor}
strokeWidth={arrowWidth}
strokeOpacity="0.7"
markerEnd="url(#arrowhead)"/>
}
</g>
);
}
Why not just create two separate marker definitions and show the correct one? You can swap the ID of the marker with a variable like you're doing for stroke color or by using CSS.
Note: I had to multiply the markerWidth, markerHeight, refX, and refY by the scale to get this to work. I think the reason for this is how SVG handles scaling strokes.
<svg>
<defs>
<marker id="arrowA"
markerWidth="10"
markerHeight="10"
refX="0" refY="3"
orient="auto"
markerUnits="strokeWidth">
<path fill="black" d="M0,0 L0,6 L9,3 z" />
</marker>
<marker id="arrowB"
markerWidth="30"
markerHeight="30"
refX="0" refY="9"
orient="auto"
markerUnits="strokeWidth">
<path
fill="orange" transform='scale(3)'
d="M0,0 L0,6 L9,3 z" />
</marker>
</defs>
</svg>
<svg id="lineA" width="276px" height="100px">
<line x1="64" y1="28" x2="200" y2="70"
stroke="black"
marker-end="url(#arrowA)">
</line>
</svg>
<svg id="lineB" width="276px" height="100px">
<line x1="64" y1="28" x2="200" y2="70"
stroke="black"
marker-end="url(#arrowB)">
</line>
</svg>
CSS to swap
#lineA {
cursor:pointer;
}
#lineA line {
marker-end: url("#arrowA");
}
#lineA:hover line {
stroke:orange;
marker-end: url("#arrowB");
}
<svg>
<defs>
<marker id="arrowA"
markerWidth="10"
markerHeight="10"
refX="0" refY="3"
orient="auto"
markerUnits="strokeWidth">
<path fill="black" d="M0,0 L0,6 L9,3 z" />
</marker>
<marker id="arrowB"
markerWidth="20"
markerHeight="20"
refX="0" refY="6"
orient="auto"
markerUnits="strokeWidth">
<path
fill="orange" transform='scale(2)'
d="M0,0 L0,6 L9,3 z" />
</marker>
</defs>
</svg>
<svg id="lineA" width="276px" height="100px">
<line x1="64" y1="28" x2="200" y2="70"
stroke="black" >
</line>
</svg>
Hover over the arrow

How to fix: text displaying in svg across-browsers?

My svg is displayed correct in IE, Edge and Chrome. Firefox doesn't work. The problem is, that the text doesn't appear correct.
Chrome
chrome
FF
Firefox Version
Here the code of my svg. I really don't know what the problem is.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="780px" height="540px" viewBox="0 0 780 540" enable-background="new 0 0 780 540" xml:space="preserve">
<a href="https://www.google.ch" target="_blank">
<g>
<image
overflow="visible"
opacity="0.35"
width="56"
height="52"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA1CAYAAAD72kP+AAAACXBIWXMAAAsSAAALEgHS3X78AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAu9JREFUeNrsmmtv0zAUhp1LU5goDDGuAgk+8oH//0s2beIqBmUbW9e10DVN13AOeU0PrtMLrUuqOtKreU2jniev7ZP4OFRbcMQzzgcbxJIvAhkY2iRIqVJIhorweYx2uAGwI2goNLJBasA66Q6pQdoh1SrsqnbshpSSfpA6pGtSpkFNyBiAT0nPSXsAjSvu4oB0RTohHZPOAf6769ogGwB8Q3pF2hVuVtFJhuyRTkmHpD4c7QP0j0OBgGTnHpJekl6jnVR4XPL4+0m6S+qSPiNePZfkZjcM4dpt0n0APsI4rTJkF+41EGsk4y1LITFgE1xUxw2oYneNMCZriHsiG8RTHgBkrqxqGpGxhWVZIFRbcHhID+khPaSH9JAe0kN6SA/pIT2kh/SQHtJDbiFkbvzdlKM07jInR0J5hYF1bGa8UyH5C7y0zsWSFMrUuK5QNUBdyRqIeIcmbGzcEV0d4hXpFulCFQUgvhm31HhlOqgIIMNxieASsbZVURfJZA+MxIV6gbYGoET9vSodWtwP/hMcQ3BBh8t0Z6RPpCPSW1XUQlowa2RCyqB1l81s9lsAgzV2TV2HZOe+kt6R9kkHaJ/g/NDmpDkm+7C+h3a/ZHy6hLXBsUvfSB/h3j7EgE24m0pjopLZaij6u67edtC+XgNsGVzTAneEz84wl6RmbNEcs1YPF7ehK/zvAnYeuAPAccH1A861xIQzMbSiGT8ou6521AXsonDvMR7P8d1UjMGJVBfN+eM3cHXVsMvAdRFP2cQ4N+QqYU1I53DLTBA6n0bIpVx653r9A9ITVWyqeAE9U0VJfhcPFQmuy41cd4Gpn0GOoSYmk7boktm/PGouMwsuCruH84ka79i4dAm3yrw2L6wG3UFXlvtuvriAc5G8p8E+VsUGKA05BOQpEvt3F3AuH8dssLz15B6g63CyB9COK7h1PHNK2BrgzIlnADmBW+dbRCDeYkJLWnL+Yr7OVyW5Pyi3LFv4w6/WzTh+CTAA7UuPJ4vLMvAAAAAASUVORK5CYII="
transform="matrix(1 0 0 1 490.2483 147.248)"
></image>
<g>
<g>
<polygon
fill="red"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
<polygon
fill="none"
stroke="#D9D9D9"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
</g>
</g>
</g>
</a>
<text transform="matrix(1 0 0 1 509.5081 163.1104)">
<tspan x="0" y="0" fill="#949495" font-family="'Calibri'" font-size="11">
KVP
</tspan>
<tspan
x="-0.516"
y="12"
fill="#949495"
font-family="'Calibri'"
font-size="11"
>
[VP]
</tspan>
</text>
<path
fill="none"
stroke="#A3D2C4"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
d="M664.349,162.086"
/>
</svg>
This is not an answer, it's just a comment: As you can see the next example works the same way in Chrome and FF. There must be something else in your code that is causing the problem.
svg{border:1px solid;}
<svg viewBox="240 120 90 50">
<rect x="260" y="135" width="50" height="20" fill="none" stroke="black" />
<text id="txt"
transform="matrix(1 0 0 1 262.6731 147.9746)"
fill="#1D1D1B"
font-family='Calibri'
font-size="11"
>
Betrieb
</text>
</svg>
UPDATE
The OP added more code.
I've replaced the <tspan> with <text> elements. Instead of having the <a> inside the text, now the <a> is wrapping the text.
Also I've replaced your image with a shadow generated with an svg filter.
svg{border:1px solid}
text{fill:#949495;font-family:Calibri;font-size:11;text-anchor:middle}
<svg viewBox="480 140 78 60">
<defs>
<filter id="f">
<feGaussianBlur in="SourceAlpha" stdDeviation="1.3" result="desenfoque"></feGaussianBlur>
<feOffset in="desenfoque" dx="0" dy="0" result="sombra"></feOffset>
<feMerge>
<feMergeNode in="sombra"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
</defs>
<a href="https://www.google.ch" target="_blank">
<g>
<g>
<g filter="url(#f)">
<polygon
fill="red"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
<polygon
fill="none"
stroke="#D9D9D9"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
points="540.724,151.425 540.724,180.043 518.262,191.72 495.801,180.043 495.801,151.425"
/>
</g>
</g>
</g>
</a>
<a href="https://google.ch">
<text x="518.5" y="167" >KVP</text>
</a>
<a href="https://google.ch">
<text x="518.5" y="180" >[VP]</text>
</a>
<!--This path has a width and a height == 0
you can delete it -->
<path
fill="none"
stroke="#A3D2C4"
stroke-width="0.75"
stroke-linejoin="round"
stroke-miterlimit="10"
d="M664.349,162.086"
/>
</svg>

SVG filter not work with marker-end in Firefox

I have following svg code works great in Chrome, but the marker did not show in Firefox. Is there someone know why? Thanks!
<svg id="exhibition_svg" width="1235" height="487" class="exhibitionSvg"
viewBox="-139.2135523613963,-60,806.4271047227926,318"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="bgPoint" width="800%" height="800%" x="-200%" y="-200%">
<feGaussianBlur stdDeviation="1" width="800%" height="800%" x="-300%"
y="-300%">
</feGaussianBlur>
</filter>
<marker id="app5end-arrow-active" viewBox="0 0 14 14" refX="7" refY="7"
markerWidth="3" markerHeight="3" orient="auto" filter="url(#bgPoint)">
<g>
<circle cx="7" cy="7" r="5" fill="#122C34" stroke="#3AD5C9" stroke-width="1">
</circle>
<circle cx="7" cy="7" r="2" fill="#122C34" stroke="#3AD5C9" stroke-width="2">
</circle>
</g>
</marker>
</defs>
<g>
<path class="connect_line" d="M245,153L250,153L283,153L283,153"
stroke="#0F364B" fill="none" stroke-width="7" rotate="auto"
marker-end="url(#app5end-arrow-active)"
marker-start="url(#app5end-arrow-active)">
</path>
</g>
</svg>
I also put it on codepen: https://codepen.io/rrandom/pen/yXrRZQ , please have a look

how to create rounded corners in svg

I'd like to create rounder corners for my svg path but I can't make it work.
Is there a good way to accomplish this? here is my code:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<clipPath id="svgClip">
<path id="svgPath" d="M3,474 L957,471 942,24 40,1 z" />
</clipPath>
<path id="svgMask" d="M3,474 L957,471 942,24 40,1 z" />
</svg>
Thanks!
You can use stroke-linejoin="round" and pick a suitable stroke-width.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="300" viewBox="-100 -100 1200 1000">
<path id="svgMask" d="M3,474 L957,471 942,24 40,1 z" stroke-linejoin="round" stroke="black" stroke-width="80"/>
</svg>
This may depend on compatibility but stroke-linecap works in Chromium browsers.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<clipPath id="svgClip">
<path id="svgPath" d="M3,474 L957,471 942,24 40,1 z" stroke-linecap="round"/>
</clipPath>
<path id="svgMask" d="M3,474 L957,471 942,24 40,1 z" stroke-linecap="round"/>
</svg>
There is no automatic or easy way to do this for paths. You can supply an r (radius) attribute to<rect> elements, but there is no equivalent for <path>.
You would need to calculate and add cubic bezier path commands (C or c) at the appropriate places in your path.