The Issue
In the following HTML code, I'm using the css calc()
function to make an SVG line a percentage of the width of the parent container, minus a constant 20px:
<button onclick="myOnClick()">Click me</button>
<div id="my-div">
<svg xmlns="http://www.w3.org/2000/svg">
<line
x1="0px"
x2="calc(100% - 20px)"
y1="30px"
y2="50px"
stroke="#0000FF"
strokeWidth="10px"
/>
</svg>
</div>
When the button is clicked, the width of the parent container is changed.
function myOnClick() {
document.getElementById("my-div").style.width = "400px";
}
The expected behavior is that the line should change its ending coordinate to take into account the new width of the container. However, the line does not change width.
If you go into the element inspector and then change the x2
of the line to another value, then back to calc(100% - 20px)
, the line DOES update and takes on the new width of the container. This leads me to believe this is a rendering bug in Chrome.
Other Cases
Curiously, when I change one of the y coordinates to a percentage, rather than a pixel value, it works as expected:
<button onclick="myOnClick()">Click me</button>
<div id="my-div">
<svg xmlns="http://www.w3.org/2000/svg">
<line
x1="0px"
x2="calc(100% - 20px)"
y1="30px"
y2="100%" <-- LINE CHANGED
stroke="#0000FF"
strokeWidth="10px"
/>
</svg>
</div>
function myOnClick() {
document.getElementById("my-div").style.width = "400px";
}
#my-div {
width: 200px;
height: 500px;
background-color: red;
position: relative;
}
svg {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
}
<button onclick="myOnClick()">Click me</button>
<div id="my-div">
<svg xmlns="http://www.w3.org/2000/svg">
<line
x1="0px"
x2="calc(100% - 20px)"
y1="30px"
y2="100%"
stroke="#0000FF"
strokeWidth="10px"
/>
<line
x1="0px"
x2="calc(100% - 20px)"
y1="30px"
y2="50px"
stroke="#0000FF"
strokeWidth="10px"
/>
</svg>
</div>
Question
Is this expected behavior, or is this a bug in Chrome that should be reported?
This question only pertains to Chrome, as Firefox and Safari do not seem to support the calc()
function for SVG components.
CodePudding user response:
calc() is a CSS function and the x2 attribute is not a presentation attribute (can not be used in CSS) and can only take a length, number or percentage.
What is the width of the SVG was 100% - 20px
like in this example:
function myOnClick() {
document.getElementById("my-div").style.width = "400px";
}
#my-div {
width: 200px;
height: 200px;
border: thin solid black;
display: flex;
align-items: flex-end;
flex-direction: column;
}
svg {
width: calc(100% - 20px);
height: 100%;
}
<button onclick="myOnClick()">Click me</button>
<div id="my-div">
<svg xmlns="http://www.w3.org/2000/svg">
<line x1="0" y1="30"
x2="100%" y2="50"
stroke="#0000FF"
stroke-width="10" />
</svg>
</div>
CodePudding user response:
As calc()
doesn't work for sg attributes in Firefox or Safari, you could get a similar layout
by applying padding to the parent <svg>
function myOnClick() {
document.getElementById("my-div").style.width = "400px";
}
#my-div {
width: 200px;
height: 500px;
background-color: red;
position: relative;
}
svg {
width: 100%;
height: 100%;
box-sizing: border-box;
padding-right: 20px;
}
<button onclick="myOnClick()">Click me</button>
<div id="my-div">
<svg xmlns="http://www.w3.org/2000/svg">
<line
x1="0px"
x2="100%"
y1="30px"
y2="100%"
stroke="#0000FF"
strokeWidth="10px"
/>
<line
x1="0px"
x2="100%"
y1="30px"
y2="50px"
stroke="#0000FF"
strokeWidth="10px"
/>
</svg>
</div>