Layer content inside HTML in SVG foreignObject renders in the wrong place
https://bugs.webkit.org/show_bug.cgi?id=23113
Summary Layer content inside HTML in SVG foreignObject renders in the wrong place
Simon Fraser (smfr)
Reported 2009-01-04 20:17:43 PST
When HTML content inside an SVGForeignObject gets a RenderLayer for whatever reason, then it renders in the wrong place. I guess this happens because the RenderLayer hierarchy does not extend through the SVG renderers, so the HTML RenderLayers have no knowledge of the SVG transforms etc.
Attachments
Testcase (740 bytes, image/svg+xml)
2009-01-04 20:18 PST, Simon Fraser (smfr)
no flags
Work-in-progress patch (12.46 KB, patch)
2009-02-27 09:37 PST, Simon Fraser (smfr)
no flags
Another work-in-progress patch (14.13 KB, patch)
2012-02-03 13:55 PST, Florin Malita
no flags
foreignObject and positioning bug (2.54 KB, text/html)
2020-02-21 08:46 PST, fabswt
no flags
Showing defect using scrolling section (484.21 KB, image/png)
2020-07-17 00:11 PDT, Edaqa Mortoray
no flags
Simon Fraser (smfr)
Comment 1 2009-01-04 20:18:13 PST
Created attachment 26421 [details] Testcase
vikram hegde
Comment 2 2009-02-25 23:07:38 PST
Hi, i have found out that in the html code if i remove the sytle attribute for div element the text inside the div element is renderred in the correct place and the bug is not seen> also if i change the opacity value of div to 1.0 the bug is not seen. It looked strange. could anyone put more light on this.
Simon Fraser (smfr)
Comment 3 2009-02-25 23:24:13 PST
Yes, the problem is that the RenderSVGForeignObject does not have a RenderLayer, so that layers inside the HTML are not positioned correctly.
vikram hegde
Comment 4 2009-02-26 00:41:57 PST
Actually i dont think its the case in every html object, the bug is seen only when we apply opacity, if we remove opacity everrything works perfectly fine.And also other html elements are getting rendered properly. could you please brief more on this.
Simon Fraser (smfr)
Comment 5 2009-02-26 08:42:35 PST
Opacity makes a RenderLayer in the HTML. That RenderLayer is parented currently in the SVGRoot's layer, not the foreignObject's layer, so ends up in completely the wrong places. Are you planning to work on this bug?
vikram hegde
Comment 6 2009-02-26 10:26:59 PST
(In reply to comment #5) > Opacity makes a RenderLayer in the HTML. That RenderLayer is parented currently > in the SVGRoot's layer, not the foreignObject's layer, so ends up in completely > the wrong places. > Are you planning to work on this bug? yes i am planing to work on this bug.which would be the better place or approach to resolve the issue?
Simon Fraser (smfr)
Comment 7 2009-02-26 10:30:07 PST
I have a hacked-up patch that I can attach when I get home. It has a number of issues, though.
Simon Fraser (smfr)
Comment 8 2009-02-27 09:37:02 PST
Created attachment 28077 [details] Work-in-progress patch Here's a work-in-progress patch. There are a number of things wrong with it: * The RenderBox.cpp change needs cleaning up (see bug 23111 for some comments about that) * The way that the layer paints with the ancestor transform seems weird * Some SVG layout tests are broken
Simon Fraser (smfr)
Comment 9 2009-02-27 09:37:37 PST
Note that if you fix this bug, you'll probably fix bug 23111 too.
Nikolas Zimmermann
Comment 10 2010-07-08 02:19:28 PDT
Changed component to SVG, so it shows up in my all-svg-bugs search.
Silvia Pfeiffer
Comment 11 2010-08-12 01:59:12 PDT
I have a similar problem, where I have a foreignObject in a <defs> and cannot apply a mask to it, because the foreignObject keeps getting rendered. I hope it can be fixed with the same fixes - if not, I can open a new bug. <?xml version="1.0"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="270px" width="480px"> <mask id="c1" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse"> <circle id="circle" cx="240" cy="135" r="135" fill="white"/> </mask> <defs> <g id="videoGroup"> <foreignObject width="100%" height="100%"> <body xmlns="http://www.w3.org/1999/xhtml"> <video id="vid" class="target" height="270px" width="480px" controls="controls" autoplay="autoplay"> <source src="http://annodex.net/~silvia/itext/chocolate_rain/chocolate_rain.mp4" type="video/mp4"/> <source src="http://annodex.net/~silvia/itext/chocolate_rain/chocolate_rain.ogv" type="video/ogg"/> </video> </body> </foreignObject> </g> </defs> <use xlink:href="#videoGroup" mask="url(#c1)"/> </svg>
Eric Seidel (no email)
Comment 12 2010-08-12 05:51:49 PDT
The foreignObject inside a defs sounds like a separate bug, please file. :) CCing Ken, because his latest work needs to be aware of the possible interaction issues between layers and SVG.
Silvia Pfeiffer
Comment 13 2010-08-12 06:07:07 PDT
Tim Horton
Comment 14 2011-07-28 15:44:07 PDT
Florin Malita
Comment 15 2012-02-03 13:55:39 PST
Created attachment 125408 [details] Another work-in-progress patch I've updated Simon's patch and it works pretty well for the issue at hand (still a couple of rough edges to fix). There's a major limitation with this approach though: the SVG paint context is lost with a separate layer - hence masks, filters, etc. on the FO's ancestor elements are not applied to embedded content. I can't think of a way around this that doesn't involve some major RenderLayer surgery, so any ideas/comments are much appreciated.
Simon Fraser (smfr)
Comment 16 2012-02-04 09:51:14 PST
(In reply to comment #15) > I can't think of a way around this that doesn't involve some major RenderLayer surgery, so any ideas/comments are much appreciated. I don't think there is an easy way. We'll probably have to glue RenderLayers together across foreignObject boundaries. We'd need one layer that knows all about the SVG transforms.
Florin Malita
Comment 17 2012-02-15 11:07:55 PST
There is also a stacking problem: SVG specifies that elements are rendered in implicit order (elements should be "covering" their same-fragment predecessors). To preserve these semantics, we'll probably have to group FO sibling elements into additional synthetic layers to be composited in implicit order - pre-FO layer, FO layer, post-FO layer. Otherwise regular elements following a FO will be covered by it.
Nikolas Zimmermann
Comment 18 2012-02-15 14:47:48 PST
(In reply to comment #17) > There is also a stacking problem: SVG specifies that elements are rendered in implicit order (elements should be "covering" their same-fragment predecessors). To preserve these semantics, we'll probably have to group FO sibling elements into additional synthetic layers to be composited in implicit order - pre-FO layer, FO layer, post-FO layer. Otherwise regular elements following a FO will be covered by it. Exactly! I had fO + layers working until this point :-) This is the really problematic thing. Any SVG renderer would need to check if it follows a <fO/> - if yes, it has to return true for requiresLayer - probably requires some plumbing in RenderSVGBlock, RenderSVGInline, RenderSVGModelObject (+ another base class I probably forgot). Once that works, we need testcases which moves <svg><g id="g1"/><fO/><g id="g2"/>.... eg. g1 behind g2, etc, to make sure we handle updates of the "pre-Fo layer, FO-layer, post-fO-layer" states properly. I could think of more tricky test cases as well... Are you planning to work on that?
Florin Malita
Comment 19 2012-02-16 07:52:31 PST
(In reply to comment #18) > Exactly! I had fO + layers working until this point :-) This is the really problematic thing. Any SVG renderer would need to check if it follows a <fO/> - if yes, it has to return true for requiresLayer - probably requires some plumbing in RenderSVGBlock, RenderSVGInline, RenderSVGModelObject (+ another base class I probably forgot). My initial thought was to group the elements following a FO into a hidden container and only create one additional layer. But that can be probably implemented later as an optimization (if needed at all) - your idea seems much more straightforward. > Are you planning to work on that? Sure, I've been chipping at this issue long enough now that I might as well keep doing it :) Do you have a saved patch that you can share?
Elliott Sprehn
Comment 20 2012-11-05 11:22:47 PST
*** Bug 101237 has been marked as a duplicate of this bug. ***
Philip Rogers
Comment 21 2014-04-15 20:24:08 PDT
*** Bug 131492 has been marked as a duplicate of this bug. ***
Said Abou-Hallawa
Comment 22 2019-08-02 15:29:37 PDT
*** Bug 165516 has been marked as a duplicate of this bug. ***
Said Abou-Hallawa
Comment 23 2019-08-02 15:31:14 PDT
*** Bug 200383 has been marked as a duplicate of this bug. ***
Said Abou-Hallawa
Comment 24 2019-08-02 15:33:58 PDT
*** Bug 32218 has been marked as a duplicate of this bug. ***
Said Abou-Hallawa
Comment 25 2019-08-02 15:35:39 PDT
*** Bug 198660 has been marked as a duplicate of this bug. ***
Jay Wang
Comment 26 2019-12-19 17:24:37 PST
Having the same issue with <foreignObject>. Any work on this issue?
fabswt
Comment 27 2020-02-21 08:46:44 PST
Created attachment 391404 [details] foreignObject and positioning bug Attaching a test case. It demonstrates the issue with `transform` breaking the positioning of foreignObject's children. It also shows a workaround: `position: fixed` can be used to prevent the issue. Problem is it can't be used just anywhere. In any case… This is a basic SVG functionality that's broken. Any chance to get a fix? It's been open for 11 years now.
Timur
Comment 28 2020-03-24 06:23:00 PDT
I encountered this problem. When will it be resolved? There has been no progress for 11 years. Please speed up the solution of this problem.
chototoro
Comment 29 2020-03-30 11:43:51 PDT
I was about to file a bug regarding foreignObject content not being correctly scaled when using the zoom command +/- in Safari, but i think it is related to this bug. As previous comments said, it occurs on elements with positioning, opacity, or transform. Here is a test-case where the layout is fine, until you zoom in or out the page: https://codepen.io/chototoro/pen/gOpqjEX
Edaqa Mortoray
Comment 30 2020-07-17 00:11:23 PDT
Created attachment 404542 [details] Showing defect using scrolling section This shows the defect using a div which contains a scrollable section. The inner-document has these CSS settings: ``` .inner-document { font-size: 28px; overflow-y: auto; width: 100%; height: 100%; } ``` The moment the size exceeds the space to the foreignObject the render error happens.
Nikos
Comment 31 2020-09-01 12:40:46 PDT
any updates? no wonder people call safari the new ie)
eldar
Comment 32 2020-10-05 09:33:10 PDT
Same issue in Safari v14.0 is there any chance to get this fixed?
terrence
Comment 33 2020-12-06 01:47:29 PST
This issue was also on chromium but has now been fixed in chrome 87 - which was stable as November 17th, 2020 The chromium bug is here: https://bugs.chromium.org/p/chromium/issues/detail?id=976224 which is a duplicate of this related bug: https://bugs.chromium.org/p/chromium/issues/detail?id=738022&q=foreign-object The test case used for this bug was: https://codesandbox.io/s/chrome-foreignobject-defect-wf91j This test currently passes on the chrome 87 but fails on safari 14. Would be great if this could fixed to have standardized SVGForeignObject behavior.
terrence
Comment 34 2020-12-06 02:00:40 PST
terrence
Comment 35 2020-12-06 02:00:58 PST
William Spitzer
Comment 36 2020-12-10 14:46:54 PST
I encountered this bug as part of my workflow and found that the issue that was causing it was due to position: relative/absolute elements in the foreignObject. I made a demo to show the differences in behavior (try in chrome vs safari) https://jsfiddle.net/hkctay9z/2/ This is a pretty big blocker which prevents usage of foreignObject in Safari for our project. Hopefully the demo provided will help the bugfix.
Rob Johnston
Comment 37 2021-04-07 13:50:12 PDT
We've hit this one too. We use SVG content that includes embedded iframes to deliver advanced "touchscreen" layouts to our users. Now that this technique works on Chrome, we're shipping a product that works most everywhere except for Safari.
Artemy
Comment 38 2021-07-12 10:57:35 PDT
Hi, Our customers faced the same issue when are using one of our HTML/JS components. I reproduced the issue using a simple HTML markup, Check the following sample: https://codesandbox.io/s/templates-devextreme-diagram-forked-56vuc?file=/CustomShapeTemplate.vue Would you please inform me if this issue is fixed? Thanks, Artemy DevExpress
Mark
Comment 39 2021-08-06 21:38:53 PDT
Also experiencing this issue with a major customer, reading StackOverflow and elsewhere, I get the express feeling that many people are being affected by this. Depends on 90738 which seems to be progressing at least. It's not great that customers have to use another browser, and of course you're out of luck on iOS and iPadOS. Can anyone give any indication of what is happening with this bug?
Patrick Spiegel
Comment 40 2022-01-04 03:07:18 PST
This is a major issue. This is an issue that makes it impossible to user Safari properly. This should get a higher priority as there is no possible work around beside using a different browser.
kshetline
Comment 41 2022-03-17 19:59:40 PDT
I'm running into a problem with this issue here: https://shetline.com/orloj/ Changing positioning of a div inside my foreignObject from absolute to fixed helped some, but the sizing of a canvas inside the div inside the foreignObject is still wrong, and layering is completely ignored -- the canvas contents appear on top of all of the other SVG components, rather than being an intermediate layer, the way the canvas works in Chrome and Firefox. Other suggestions like using a body tag, xmlns="http://www.w3.org/1999/xhtml", or requiredExtensions="http://www.w3.org/1999/xhtml" didn't help either.
kshetline
Comment 42 2022-03-18 18:42:55 PDT
(In reply to kshetline from comment #41) > I'm running into a problem with this issue here: https://shetline.com/orloj/ > > Changing positioning of a div inside my foreignObject from absolute to fixed > helped some, but the sizing of a canvas inside the div inside the > foreignObject is still wrong, and layering is completely ignored -- the > canvas contents appear on top of all of the other SVG components, rather > than being an intermediate layer, the way the canvas works in Chrome and > Firefox. The sample website above will no longer displaying the bug. My not-very-satisfactory workaround for now is to draw to an off-screen canvas, turn the contents of that canvas into a data URL, then assign that URL to an SVG <image>. The performance of this workaround is very slow compared to using a canvas directly. Fortunately fast animation is not vital for this particular website, but where fast animation is needed my workaround would be totally unsatisfactory.
Jakub T. Jankiewicz
Comment 43 2022-03-28 10:40:12 PDT
I have a demo that can confirm this. Safari/Webkit doesn't render HTML inside SVG foreign Object properly: This is my app, SVG laptop with Terminal inside. https://terminal.jcubic.pl/laptop/ The position and scale of the terminal are way off. I use CSS custom properties and calculate pixel density to fix the scaling of the terminal inside the SVG Laptop. More or less it works correctly in Firefox and Chrome (Chrome has some issues, but they were reported).
Simon Fraser (smfr)
Comment 44 2022-03-28 11:00:16 PDT
*** Bug 238461 has been marked as a duplicate of this bug. ***
Simon Fraser (smfr)
Comment 45 2022-03-31 12:15:48 PDT
*** Bug 238499 has been marked as a duplicate of this bug. ***
Simon Fraser (smfr)
Comment 46 2022-06-01 19:37:25 PDT
*** Bug 83189 has been marked as a duplicate of this bug. ***
Simon Fraser (smfr)
Comment 47 2022-06-03 21:14:28 PDT
Simon Fraser (smfr)
Comment 48 2022-06-17 20:35:29 PDT
*** Bug 93358 has been marked as a duplicate of this bug. ***
Simon Fraser (smfr)
Comment 49 2022-07-18 16:02:44 PDT
*** Bug 103117 has been marked as a duplicate of this bug. ***
Anthony Johnston
Comment 50 2023-08-12 10:15:21 PDT
I am using this to create a dataUrl to share an image of an element in my project. Its an important part of the app, and does not work correctly on Safari iOS https://8bit.antix.co.uk/ completing a bitmap will show the share button
Simon Fraser (smfr)
Comment 51 2023-09-06 13:45:15 PDT
*** Bug 241983 has been marked as a duplicate of this bug. ***
Silvan Mühlemann
Comment 52 2024-01-05 08:41:10 PST
On https://codepen.io/silvanm75/pen/KKbBqzB you can see how to reproduce the issue and how I worked around it. The workaround lead to odd side effects on my project. That's why I would appreciate it if this bug could be fixed.
Simon Fraser (smfr)
Comment 53 2024-04-24 11:33:10 PDT
*** Bug 273173 has been marked as a duplicate of this bug. ***
Note You need to log in before you can comment on or make changes to this bug.