Closed Bug 603043 Opened 14 years ago Closed 2 years ago

SVG can't access padding CSS property if element in defs, works in Firefox 3.6

Categories

(Core :: SVG, defect)

defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: zzhumphreyt, Unassigned)

References

(Depends on 1 open bug, Blocks 1 open bug)

Details

Attachments

(2 files, 1 obsolete file)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 ( .NET CLR 3.5.30729; .NET4.0E) Build Identifier: 4.0b8pre I'm using padding and margin CSS properties to convey spacing information even though I know it's not rendered, I use getComputedStyle to get the values. In Firefox 3.6 if I have an element in a defs element then I can get padding and margin information via getComputedStyle, in Firefox 4.0b8 I just get 0 instead of the actual value. If I move the element out of the defs then I get the right values. Since I have multiple use elements that reference the element in defs it's not an option to move it out. Reproducible: Always Steps to Reproduce: 1. Create an SVG document that has a rect element inside a defs element. 2. Apply an inline style containing padding to the rect. 3. getComputedStyle for the rect will not return the correct padding CSS value. Actual Results: I get 0 as the padding value when 20 is specified. Expected Results: Expected to get 20. Regression, behavior does not occur in Firefox 3.6.
Attached image Test case for bug (deleted) —
The thing is, getComputedStyle for padding actually returns used styles, not computed ones. And the used style for SVG stuff is in fact 0....
Component: SVG → Style System (CSS)
QA Contact: general → style-system
Couldn't the argument be made that elements in a defs element are in fact used, by a use element? Between SVG, HTML, and XUL I can't think of any other element that works quite like the use element does in aping another element. I get your point that padding isn't a legal CSS property for SVG documents. I've been counting on the fact that even though these CSS properties aren't strictly legal for SVG documents they'll at least be returned to me intact. There's no way to convey relative positioning information for elements in SVG, everything's absolutely positioned, so padding and margin have been useful to use for this purpose. (If I'm wrong on this please let me know!)
Component: Style System (CSS) → SVG
Attachment #482005 - Attachment mime type: application/vnd.mozilla.xul+xml → image/svg+xml
> Couldn't the argument be made that elements in a defs element are in fact used, That's not what "used value" means. "used value" is a technical term in the CSS spec: it's the value actually used for rendering. The SVG spec defines that padding doesn't apply to SVG elements, so the used value of padding for SVG elements is always 0. > they'll at least be returned to me intact. They're intact through computed style, but not in used style. > relative positioning information for elements in SVG You can be relatively positioned wrt your ancestor, no? Also, you can use transforms in SVG to do relative offsets.
> The SVG spec defines > that padding doesn't apply to SVG elements, so the used value of padding for > SVG elements is always 0. So is it a bug in Firefox that a rect that's outside of a defs element will return a value for padding? > They're intact through computed style, but not in used style. Now I'm becoming confused. :P The getComputedStyle method actually returns the used style of an element now, not its computed style? If that's the case how do I get the computed style? > You can be relatively positioned wrt your ancestor, no? I guess by relative positioning I mean more like flow, as in the rect elements in this g element are x pixels away from each other, e.g. margin. Although it would be nice if SVG supported the concept of margins or paddings, I can still use code to calculate the absolute positions of elements. And being able to indicate in my stylesheet the spacing of elements is very convenient. > Also, you can use transforms in SVG to do relative offsets. Can I use a transform to define what I mentioned above?
> The getComputedStyle method actually returns the used style of an element now, > not its computed style? It returns more or less what CSS 2 called "computed style", which is what CSS 2.1 calls "used style". Mostly. In practice, it returns whatever is needed for web compat. > If that's the case how do I get the computed style? At the moment, you don't. There are some proposals for adding new APIs for it. > I guess by relative positioning I mean more like flow Yeah, that's a meaningless concept in SVG.... Anyway, the inside-defs vs not-inside-defs difference is one reason this bug is still open...
QA Contact: style-system → general
Timothy, since this worked differently in Firefox 3.6 you could help us by finding out when things changed if you're up for it. There are some instructions here: https://wiki.mozilla.org/QA/Triage#How_to_Help_with_Regressions_--_Finding_Regression_Windows and you want to be looking in the mozilla-central directories
Okay, I'll try and look back to see when this changed.
Found the regression window: March 1, 2010 trunk: works, March 2, 2010 trunk: broken I took a quick look at the changesets between those dates using Bonsai and nothing really stuck out, no "SVG" files. If I can be of any more help let me know.
Thanks Timothy, If you could type about:buildconfig into the URL bar and post the links that follow "Source built from" on that page for both of those builds that will provide a more accurate list changeset list for us.
Attached image working testcase (click to test) (deleted) —
The existing testcase didn't seem to work for me (tried on bugzilla & a locally saved copy). Here's a simplified version that's just SVG instead of SVG-in-XUL.
(and I confirmed that this new testcase produces 20px/20px in Firefox 3.6, vs 0px/20px in trunk, as described in comment 0)
From about:buildconfig source built from March 1: http://hg.mozilla.org/mozilla-central/rev/e7970f6c7cdd March 2: http://hg.mozilla.org/mozilla-central/rev/ba77049941c3 The March 2nd changeset definitely shows SVG changes. Guess I was using Bonsai wrong that it never showed this.
So the behavior there might have changed due to bug 542361, which changes how and when used padding is stored. Daniel, any idea why the <defs> matters?
It has a state bit NS_STATE_SVG_NONDISPLAY_CHILD which stops it and it's children being drawn, otherwise there's not much to a defs frame. I can confirm that <g> and inner <svg> frames do report non-zero padding so it's clearly specific to defs. FWIW I'm building changeset 365acfca64dc now.
Comment 15 is right on.
Blocks: 542361
Attached patch PoC patch (obsolete) (deleted) — Splinter Review
Because <defs> frames are never drawn they don't get an InitialUpdate so they don't get any state bits cleared. Specifically they will always have NS_FRAME_FIRST_REFLOW set. Padding now works like this... /* virtual */ nsMargin nsIFrame::GetUsedPadding() const { nsMargin border(0, 0, 0, 0); if ((mState & NS_FRAME_FIRST_REFLOW) && !(mState & NS_FRAME_IN_REFLOW)) return border; So this always returns 0 for a <defs> frame. The attached patch would fix it but I'm more inclined to WONTFIX this bug as the patch will make pages marginally slower to load as we clear out the bits and padding/margin/border are not SVG styles anyway.
Attachment #482282 - Flags: feedback?(bzbarsky)
Would that actually help? If after initial reflow I dynamically add some kids inside the <defs>, will that trigger a reflow of the outer SVG? Perhaps it would make more sense to not set FIRST_REFLOW on SVG frames that never actually get reflowed to start with?
(In reply to comment #19) > Would that actually help? If after initial reflow I dynamically add some kids > inside the <defs>, will that trigger a reflow of the outer SVG? Correct, this is not a complete patch. That would need fixing too. > > Perhaps it would make more sense to not set FIRST_REFLOW on SVG frames that > never actually get reflowed to start with? Yes, if we could do that efficiently. The frames will have NS_STATE_SVG_NONDISPLAY_CHILD but we'd have to determine whether we were looking at an SVG frame before we checked that.
Right now NS_FRAME_FIRST_REFLOW is set in exactly one place: the nsFrame constructor. You could just unset it in the constructors of the relevant frame classes, assuming "doesn't get reflowed" is a class invariant. That should be efficient and all.
Attachment #482282 - Flags: feedback?(bzbarsky)
Depends on: 732930
Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20130731 Firefox/25.0 Mozilla/5.0 (Macintosh: Intel Mac OS X 10.9; rv:25.0) Gecko/20130731 Firefox/25.0 Reproduced the issue on latest Nightly 25.0a1 (buildID: 20130731030203). In Chrome, Opera and IE it displays: "rect in defs, padding-left: 20px rect outside defs, padding-left: 20px"
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: qawanted
OS: Windows 7 → All
Hardware: x86 → All
Version: unspecified → Trunk
Attachment #482282 - Attachment is obsolete: true

Fixed sometime in the last 9 years.

Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: