Closed Bug 721082 Opened 13 years ago Closed 13 years ago

Percentages in -moz-perspective-origin aren't relative to element's border box

Categories

(Core :: Layout, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla13

People

(Reporter: ayg, Assigned: mattwoodrow)

References

Details

Attachments

(2 files, 1 obsolete file)

These two look identical in Firefox 12.0a1 (2012-01-24), where the only difference is the value of -moz-perspective-origin: data:text/html,<!DOCTYPE html> <div style="-moz-perspective:100px; -moz-perspective-origin:25% 25%; height:100px;width:100px"> <div style="height:70px;width:70px;background:green; margin:5px;padding:5px;border:5px solid black; -moz-transform:rotateX(45deg)"></div> </div> data:text/html,<!DOCTYPE html> <div style="-moz-perspective:100px; -moz-perspective-origin:22.5px 22.5px; height:100px;width:100px"> <div style="height:70px;width:70px;background:green; margin:5px;padding:5px;border:5px solid black; -moz-transform:rotateX(45deg)"></div> </div> This means 25% somehow evaluates to 22.5px here. The only way I can see that happening is if it's evaluated relative to the *child's* border box, since that's the only thing that's 90px tall/wide. This is unexpected -- I'd expect it to evaluate relative to the border box of the element itself, like transform-origin. I was not able to test what IE10 or WebKit does. The spec currently says: "Percentages: refer to the size of the elemen's box" http://dev.w3.org/csswg/css3-3d-transforms/#perspective-origin-property It doesn't say whether it's the element's content, padding, border, or margin box. Probably the intent is border box (https://www.w3.org/Bugs/Public/show_bug.cgi?id=15708). But it should be relative to *some* box of the element it's specified on, not a box of its child. Is there a reason for this behavior, or is it just a bug?
I was finally able to test in Chrome 17 dev, and it looks identical in that test-case if I give 25px, not 22.5px. If I modify the test-case to add some margin/border/padding to the outer box too data:text/html,<!DOCTYPE html> <div style="-webkit-perspective:100px; -webkit-perspective-origin:25% 25%; height:100px;width:100px; margin:5px;padding:5px; border:5px solid gray"> <div style="height:70px;width:70px;background:green; margin:5px;padding:5px;border:5px solid black; -webkit-transform:rotateX(45deg)"></div> </div> it looks the same in WebKit if I replace "25%" with "30px", so it is indeed relative to the border box of the element that perspective-origin is specified on.
Well, that was an adventure :)
Attachment #595580 - Flags: review?(roc)
Comment on attachment 595580 [details] [diff] [review] Make perspective origin use the parents border box Review of attachment 595580 [details] [diff] [review]: ----------------------------------------------------------------- A separate patch for constifying GetParentStyleContextFrame would be good. ::: layout/generic/nsFrame.cpp @@ +976,5 @@ > } > > +bool > +nsIFrame::HasPerspective() const > +{ Can we check IsTransformed here? @@ +6763,5 @@ > } > if (Preserves3DChildren()) { > ComputePreserve3DChildrenOverflow(aOverflowAreas, newBounds); > + } else if (HasPerspective()) { > + RecomputePerspectiveChildrenOverflow(this, &newBounds); Could we fold RecomputePerspectiveChildrenOverflow into ComputePreserve3DChildrenOverflow?
I get a segfault at this line - nsDisplayTransform::GetFrameBoundsForTransform(aFrame)); + nsDisplayTransform::GetFrameBoundsForTransform(aFrame->GetParentStyleContextFrame())); when loading this: data:text/html,<html style=-moz-transform:scale(-1)>
Attachment #595580 - Attachment is obsolete: true
Attachment #595580 - Flags: review?(roc)
Attachment #595868 - Flags: review?(roc)
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #3) > Can we check IsTransformed here? Definitely. > > @@ +6763,5 @@ > > } > > if (Preserves3DChildren()) { > > ComputePreserve3DChildrenOverflow(aOverflowAreas, newBounds); > > + } else if (HasPerspective()) { > > + RecomputePerspectiveChildrenOverflow(this, &newBounds); > > Could we fold RecomputePerspectiveChildrenOverflow into > ComputePreserve3DChildrenOverflow? I can't see an easy way to do this. All 3 (includes RecomputePreserve3DChildrenOverflow) loop over the child frames, but they take different actions and have different termination conditions. It would be a fairly complex set of flags passed in to handle all the cases within a single loop.
Attachment #595869 - Flags: review?(roc)
(In reply to Aryeh Gregor from comment #4) > I get a segfault at this line > > - > nsDisplayTransform::GetFrameBoundsForTransform(aFrame)); > + > nsDisplayTransform::GetFrameBoundsForTransform(aFrame- > >GetParentStyleContextFrame())); > > when loading this: data:text/html,<html style=-moz-transform:scale(-1)> Er yeah, that needs a null check.
Fixed that already, moved calculation of the perspective origin offset so that it only runs when we have perspective.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla13
Blocks: 731777
Depends on: 729955
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: