- From: Karl Dubost via GitHub <noreply@w3.org>
- Date: Mon, 19 Jan 2026 09:06:14 +0000
- To: public-svg-issues@w3.org
Being naïve on purpose.
Reading step by step, the issue:
Differences of implementations:
<img width="1044" height="697" alt="Image" src="https://github.com/user-attachments/assets/370f3fb9-57cf-4f68-833f-cede07cfa899" />
Gecko, Blink return the same results.
Safari already does the right thing according to STP 235 for **missing values**, but maybe I'm missing some cases.
https://codepen.io/webcompat/pen/GgZQMgZ
This renders the same everywhere.
<img width="3162" height="753" alt="Image" src="https://github.com/user-attachments/assets/946e9593-e61a-44dd-a5a5-cde7fe094f5c" />
The WPT tests are failing with `expected "50%" but got "0"`
* SVGAnimatedLength, initial values, SVGRadialGradientElement.prototype.fx (remove)
* SVGAnimatedLength, initial values, SVGRadialGradientElement.prototype.fx (invalid value)
* SVGAnimatedLength, initial values, SVGRadialGradientElement.prototype.fy (remove)
* SVGAnimatedLength, initial values, SVGRadialGradientElement.prototype.fy (invalid value)
This is **only for SVGRadialGradientElement**.
https://github.com/web-platform-tests/wpt/blob/17ed18c17ad38f84d48f327dd4103b9b4271b732/svg/types/scripted/support/initial-value-helper.js
The code does:
```
e.removeAttribute(content_attribute);
assert_equals(getValue(e[attribute].baseVal), initial, 'initial after');
```
and
```
e.setAttribute(content_attribute, 'foobar');
assert_equals(getValue(e[attribute].baseVal), initial, 'initial after');
```
why would it work for other properties, but radialGradient?
Oh it fails even before.
```
let e = document.createElementNS('http://www.w3.org/2000/svg', objects[info.interface]);
let initial = info[attribute] && info[attribute].initial || config.initial;
let valid = info[attribute] && info[attribute].valid || config.valid;
assert_equals(getValue(e[attribute].baseVal), initial, 'initial before');
```
At the moment the element is created `fx` and `fy` do not have a default value of `50%` as expected.
even before removing or trying to set an invalid value.
## The spec:
1. If attribute ‘[fx](https://svgwg.org/svg2-draft/pservers.html#RadialGradientElementFXAttribute)’ is not specified, ‘[fx](https://svgwg.org/svg2-draft/pservers.html#RadialGradientElementFXAttribute)’ will coincide with the presentational value of ‘[cx](https://svgwg.org/svg2-draft/pservers.html#RadialGradientElementCXAttribute)’ for the element whether the value for 'cx' was inherited or not. ✅
2. If the element references an element that specifies a value for 'fx', then the value of 'fx' is inherited from the referenced element. ✅
Basically, it says go see `cx` definition.
Let's modify the WPT to make it more obvious
```
let e = document.createElementNS(
"http://www.w3.org/2000/svg",
objects[info.interface],
);
let initial = (info[attribute] && info[attribute].initial) || config.initial;
let valid = (info[attribute] && info[attribute].valid) || config.valid;
if (
e.nodeName === "radialGradient" &&
(content_attribute === "fx" || content_attribute === "fy")
) {
console.log("TEST: -------- BEFORE --------------------");
console.log("e: " + e.nodeName);
console.log("content_attribute: " + content_attribute);
console.log("e[attribute]: " + e[attribute]);
console.log("e[attribute].baseVal: " + e[attribute].baseVal);
console.log(
"getValue(e[attribute].baseVal): " + getValue(e[attribute].baseVal),
);
console.log("initial: " + initial);
console.log("VALUE OF CX: " + getValue(e["cx"].baseVal));
console.log("VALUE OF CY: " + getValue(e["cy"].baseVal));
console.log("TEST: ---------END BEFORE -------------------");
assert_equals(getValue(e[attribute].baseVal), initial, "initial before");
e.setAttribute(content_attribute, valid);
assert_not_equals(getValue(e[attribute].baseVal), initial, "new value");
e.removeAttribute(content_attribute);
assert_equals(getValue(e[attribute].baseVal), initial, "initial after");
}
```
And run the test again:
```
[Log] TEST: -------- BEFORE -------------------- (initial-value-helper.js, line 53)
[Log] e: radialGradient (initial-value-helper.js, line 54)
[Log] content_attribute: fx (initial-value-helper.js, line 55)
[Log] e[attribute]: [object SVGAnimatedLength] (initial-value-helper.js, line 56)
[Log] e[attribute].baseVal: [object SVGLength] (initial-value-helper.js, line 57)
[Log] getValue(e[attribute].baseVal): 0 (initial-value-helper.js, line 58)
[Log] initial: 50% (initial-value-helper.js, line 59)
[Log] VALUE OF CX: 50% (initial-value-helper.js, line 60)
[Log] VALUE OF CY: 50% (initial-value-helper.js, line 61)
[Log] TEST: ---------END BEFORE ------------------- (initial-value-helper.js, line 62)
[Log] TEST: -------- BEFORE -------------------- (initial-value-helper.js, line 53)
[Log] e: radialGradient (initial-value-helper.js, line 54)
[Log] content_attribute: fy (initial-value-helper.js, line 55)
[Log] e[attribute]: [object SVGAnimatedLength] (initial-value-helper.js, line 56)
[Log] e[attribute].baseVal: [object SVGLength] (initial-value-helper.js, line 57)
[Log] getValue(e[attribute].baseVal): 0 (initial-value-helper.js, line 58)
[Log] initial: 50% (initial-value-helper.js, line 59)
[Log] VALUE OF CX: 50% (initial-value-helper.js, line 60)
[Log] VALUE OF CY: 50% (initial-value-helper.js, line 61)
[Log] TEST: ---------END BEFORE ------------------- (initial-value-helper.js, line 62)
```
The value of cx and cy are '50%', each so the initial value of `fx` and `fy` should be 50%.
So the spec says the correct thing.
Note that **when `cx` value is NOT defined explicitly** or the attribute is missing, its default value **per spec** is `50%`.
--
GitHub Notification of comment by karlcow
Please view or discuss this issue at https://github.com/w3c/svgwg/issues/1054#issuecomment-3767221527 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Monday, 19 January 2026 09:06:15 UTC