Rectify rules for attribute inheritance from <g>#44306
Conversation
Gouvernathor
left a comment
There was a problem hiding this comment.
This PR is an idea of wording, but as per syntax and markup I don't know the standards.
Feel very free to fix my code (contributors should be allowed to edit my branch).
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
|
Preview URLs (1 page) (comment last updated: 2026-06-08 07:30:09) |
| Most of the [presentation attributes](/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes) applied to the element are inherited by its children. | ||
| However, SVG-specific element rules supersede inheritance. | ||
| Geometric attributes specific to certain elements are ignored on a `<g>` container and **not** inherited by its children. | ||
|
|
||
| These non-inherited attributes include: | ||
| * {{SVGAttr("cx")}}, {{SVGAttr("cy")}}, {{SVGAttr("r")}}: {{SVGElement("circle")}}, {{SVGElement("ellipse")}} | ||
| * {{SVGAttr("rx")}}, {{SVGAttr("ry")}}: {{SVGElement("ellipse")}}, {{SVGElement("rect")}} | ||
| * {{SVGAttr("d")}}: {{SVGElement("path")}} | ||
| * {{SVGAttr("x")}}, {{SVGAttr("y")}}, {{SVGAttr("width")}}, {{SVGAttr("height")}}: {{SVGElement("foreignObject")}}, {{SVGElement("image")}}, {{SVGElement("rect")}}, {{SVGElement("svg")}}, {{SVGElement("symbol")}}, {{SVGElement("use")}} | ||
|
|
||
| In addition, non-presentation attributes valid on `<g>` (such as {{SVGAttr("id")}} or {{SVGAttr("class")}}) are not inherited by its children. |
There was a problem hiding this comment.
OK, thought about this a bit more.
- The issue here is attributes that aren't CSS properties aren't inherited "full stop". Saying that is more clear.
useis deprecated, so not mentioning it in the list.- Not mentioning id and class. They aren't inherited by anything, ever.
If you are also happy with this we can merge.
| Most of the [presentation attributes](/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes) applied to the element are inherited by its children. | |
| However, SVG-specific element rules supersede inheritance. | |
| Geometric attributes specific to certain elements are ignored on a `<g>` container and **not** inherited by its children. | |
| These non-inherited attributes include: | |
| * {{SVGAttr("cx")}}, {{SVGAttr("cy")}}, {{SVGAttr("r")}}: {{SVGElement("circle")}}, {{SVGElement("ellipse")}} | |
| * {{SVGAttr("rx")}}, {{SVGAttr("ry")}}: {{SVGElement("ellipse")}}, {{SVGElement("rect")}} | |
| * {{SVGAttr("d")}}: {{SVGElement("path")}} | |
| * {{SVGAttr("x")}}, {{SVGAttr("y")}}, {{SVGAttr("width")}}, {{SVGAttr("height")}}: {{SVGElement("foreignObject")}}, {{SVGElement("image")}}, {{SVGElement("rect")}}, {{SVGElement("svg")}}, {{SVGElement("symbol")}}, {{SVGElement("use")}} | |
| In addition, non-presentation attributes valid on `<g>` (such as {{SVGAttr("id")}} or {{SVGAttr("class")}}) are not inherited by its children. | |
| Most [presentation attributes](/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes) — those that map to inherited CSS properties, such as {{SVGAttr("fill")}}, {{SVGAttr("stroke")}}, and {{SVGAttr("font-size")}} — are passed down to child elements. | |
| Attributes that are not inherited CSS properties are not passed to children. | |
| This is most notable for geometric attributes, which define the shape or position of a specific element type: | |
| - {{SVGAttr("cx")}}, {{SVGAttr("cy")}}: {{SVGElement("circle")}}, {{SVGElement("ellipse")}} | |
| - {{SVGAttr("r")}}: {{SVGElement("circle")}} | |
| - {{SVGAttr("rx")}}, {{SVGAttr("ry")}}: {{SVGElement("ellipse")}}, {{SVGElement("rect")}} | |
| - {{SVGAttr("d")}}: {{SVGElement("path")}} | |
| - {{SVGAttr("x")}}, {{SVGAttr("y")}}, {{SVGAttr("width")}}, {{SVGAttr("height")}}: {{SVGElement("foreignObject")}}, {{SVGElement("image")}}, {{SVGElement("rect")}}, {{SVGElement("svg")}}, {{SVGElement("symbol")}} |
There was a problem hiding this comment.
- The issue is that r, cx, cy and most of the other restricted geometry properties are CSS properties as well. So that criterion is incorrect.
- I don't see use as deprecated on MDN. What's deprecated is its xlink-scoped attribute.
- I think id and class are good examples of attributes that g does take, and yet aren't subject to the inheritance meechanism. I think that's efficient to counter the misconception (currently written on the page) that "all attributes are inherited".
There was a problem hiding this comment.
Perhaps I wasn't precise enough (or perhaps I'm just wrong).
Yes they are CSS properties - the point I'm trying to make is that the are not inherited CSS properties: https://www.w3.org/TR/SVG2/geometry.html#CX
So the rule is more "if you are a CSS property that is inherited normally then you will be, if not, you aren't."
The issue with <g> is that because it is used as a container for grouping and inheritence, people perhaps expect it to allow everything to inherit, even things that wouldn't otherwise.
- I don't see use as deprecated on MDN. What's deprecated is its xlink-scoped attribute.
Apologies. You are right. Don't know where my head was.
- I think id and class are good examples of attributes that g does take, and yet aren't subject to the inheritance meechanism. I think that's efficient to counter the misconception (currently written on the page) that "all attributes are inherited".
I guess I don't see them as necessary because they are never inherited by anything, and because we no longer say that all properties are inherited, this assumption is less likely to be made. On the other hand, it does no harm.
Is this more clear?
| Most of the [presentation attributes](/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes) applied to the element are inherited by its children. | |
| However, SVG-specific element rules supersede inheritance. | |
| Geometric attributes specific to certain elements are ignored on a `<g>` container and **not** inherited by its children. | |
| These non-inherited attributes include: | |
| * {{SVGAttr("cx")}}, {{SVGAttr("cy")}}, {{SVGAttr("r")}}: {{SVGElement("circle")}}, {{SVGElement("ellipse")}} | |
| * {{SVGAttr("rx")}}, {{SVGAttr("ry")}}: {{SVGElement("ellipse")}}, {{SVGElement("rect")}} | |
| * {{SVGAttr("d")}}: {{SVGElement("path")}} | |
| * {{SVGAttr("x")}}, {{SVGAttr("y")}}, {{SVGAttr("width")}}, {{SVGAttr("height")}}: {{SVGElement("foreignObject")}}, {{SVGElement("image")}}, {{SVGElement("rect")}}, {{SVGElement("svg")}}, {{SVGElement("symbol")}}, {{SVGElement("use")}} | |
| In addition, non-presentation attributes valid on `<g>` (such as {{SVGAttr("id")}} or {{SVGAttr("class")}}) are not inherited by its children. | |
| Most [presentation attributes](https://github.com/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes) applied to a `<g>` element are inherited by its children — specifically, those that map to inherited CSS properties, such as {{SVGAttr("fill")}}, {{SVGAttr("stroke")}}, and {{SVGAttr("font-size")}}. | |
| Presentation attributes that map to non-inherited CSS properties are not passed to children. This most notably includes geometric attributes such as: | |
| - {{SVGAttr("cx")}}, {{SVGAttr("cy")}}: {{SVGElement("circle")}}, {{SVGElement("ellipse")}} | |
| - {{SVGAttr("r")}}: {{SVGElement("circle")}} | |
| - {{SVGAttr("rx")}}, {{SVGAttr("ry")}}: {{SVGElement("ellipse")}}, {{SVGElement("rect")}} | |
| - {{SVGAttr("d")}}: {{SVGElement("path")}} | |
| - {{SVGAttr("x")}}, {{SVGAttr("y")}}, {{SVGAttr("width")}}, {{SVGAttr("height")}}: {{SVGElement("foreignObject")}}, {{SVGElement("image")}}, {{SVGElement("rect")}}, {{SVGElement("svg")}}, {{SVGElement("symbol")}}, {{SVGElement("use")}} | |
| Non-presentation attributes such as {{SVGAttr("id")}} and {{SVGAttr("class")}} are also not inherited becaues they are not part of the CSS cascade. |
The main thing I am trying to avoid is "However, SVG-specific element rules supersede inheritance.". It is imprecise.
There was a problem hiding this comment.
You're presenting things so that the inheritance is shown as a superpower not of the g element, but of the CSS properties themselves. (It does not seem to be wrong, but.)
In that version you are removing the information that the listed properties (regardless of CSS) are specific to one or more SVG elements. And so then, it's not clear why elements are listed after each property in the list.
Furthermore, I don't find that version of the rule to be more intuitive, nor easy to check for a particular attribute/property.
Finally, the explanation in the specification I linked is closer to "mine" than "yours" :
Most SVG presentation attributes may be specified on any element in the SVG namespace where there is not a name clash with an existing attribute. However, the geometry properties only have equivalent presentation attributes on designated elements.
It specifically presents the rule as something specific to the element, not to the CSS property and does not even mention the inheritability of the CSS property in general (= when not set through an attribute).
There was a problem hiding this comment.
Thanks. You have convinced me. Still don't like that wording of "However, SVG-specific element rules supersede inheritance.". So if we could just tidy that: https://github.com/mdn/content/pull/44306/changes#r3371284933
There was a problem hiding this comment.
I did that and also rephrased the last line a bit.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
hamishwillee
left a comment
There was a problem hiding this comment.
That works for me. Thank you for your patience, and congratulations on landing your first MDN PR.
Description
Rectifies that all attributes are not inherited : first, non-presentation attributes (such as id or class) are not inherited, second, some presentation attributes that are specific to some SVG elements will be ignored on <g>.
Motivation
I was blocked several times wondering why my g elements refused to work with some attributes and not others.
Additional details
https://svgwg.org/svg2-draft/styling.html#TermPresentationAttribute
See also the linked issue.
Related issues and pull requests
fixes #44288