Forums
View unanswered posts | View active topics It is currently Sat Oct 25, 2014 10:42 am



Reply to topic  [ 6 posts ] 
 Fixed-position elements and mispaced PIE rendering 
Author Message

Joined: Tue Aug 31, 2010 2:33 am
Posts: 3
Post Fixed-position elements and mispaced PIE rendering
Hi all.

I'm not sure this is the right forum for this, considering that I've got a problem and potential solution at the same time. Does already shot trouble go in trouble-shooting or not?

Anyway, having tried out PIE to give me border-image support in IE, I discovered that my borders and background were being drawn in the wrong position when the styled element had position: fixed. Specifically, the element in question was an immediate child of the body; I suspect the problem would not have occurred, or would have manifested differently, had that element been contained in another absolutely-positioned element.

So I dived into the PIE code to figure out what was going wrong. I discovered that PIE did not correctly calculate the position of position: fixed elements, only for elements positioned with respect to some positioned parent element.

So I changed the updatePos function of PIE.RootRenderer, and my tests so far show it to be working for me. Here's my version of the function...
Code:
   updatePos: function() {
      if (this.isActive()) {
         var el = this.element,
                par = el,
                docEl,
                elRect, parRect,
                s = this.getBox().style, cs,
                x = 0, y = 0;

         // Get the element's offsets from its nearest positioned ancestor. Uses
         // getBoundingClientRect for accuracy and speed.
         do {
            par = par.offsetParent;
         } while (par && par.currentStyle.position === 'static');
         elRect = el.getBoundingClientRect();
         if (par) {
            parRect = par.getBoundingClientRect();
            cs = par.currentStyle;
            x = elRect.left - parRect.left - (parseFloat(cs.borderLeftWidth) || 0);
            y = elRect.top - parRect.top - (parseFloat(cs.borderTopWidth) || 0);
         } else {
            docEl = el.document.documentElement;
            x = elRect.left - docEl.clientLeft;
            y = elRect.top - docEl.clientTop;
            if (el.currentStyle.position !== 'fixed') {
               x += docEl.scrollLeft;
               y += docEl.scrollTop;
            }
         }

         s.position = el.currentStyle.position === 'fixed' ? 'fixed' : 'absolute';
         s.left = x;
         s.top = y;
         s.zIndex = el.currentStyle.position === 'static' ? -1 : el.currentStyle.zIndex;
      }
   },


Notice that I've set the position of PIE's element to be fixed if it is to sit behind a fixed element, and in such a case the document scrollLeft and scrollTop are not used to calculate position.

I have not, however, done anything about getting the positions right for IE6 (or earlier). IE6 treats position: fixed as position: absolute, which means that this would now produce an incorrect result in IE6 whereas before it would have worked (for a given value of "worked") in that browser. I figure for my current purposes, I don't care enough about IE6 to ensure that it gets the prettiest possible borders (no loss of functionality, just a little aesthetics, for that site), and if I did want to do something about it the best fix would probably to use conditional comments to produce an IE6-only stylesheet that replaces all the position: fixed CSS into position: absolute, so that the CSS matches the actual effect and PIE doesn't get fooled. (Or alter the styles with a quick bit of jQuery magic - after all, if PIE works, so does javascript, and since I've used some jQuery anyway...)

Now, I'll just build my own version of PIE to incorporate the fix, and I think I'm good to go.

So, can anyone guess at problems I might have missed? Either that my fix hasn't covered, or that I may have introduced with my fix? I'm guessing that there might be issues with fixed-position children of absolutely-positioned elements, but haven't done my testing to check.

And might I suggest that such a change as I've made be incorporated into a future version of PIE? If it's a good solution and hasn't introduced further problems, of course.


Tue Aug 31, 2010 5:47 am
Profile

Joined: Wed Jul 14, 2010 11:46 am
Posts: 1446
Post Re: Fixed-position elements and mispaced PIE rendering
Thanks a lot for this, Travis, it's a great help.

Would you mind opening an issue ticket in GitHub for this? That will make sure it doesn't get lost and serves as a checklist for me.

Reading over your code changes I think you're right that it works fine if the position:fixed element is a child of the body, but if the position:fixed element is a descendant of another positioned element then it won't work right because it still subtracts the position of that parent element.

Actually I think that if it's position:fixed we can shortcut past all the getBoundingClientRect stuff and just use the left/top/bottom/right currentStyle properties of the target element directly (except in IE6 of course, which we'd let fall through to the current code). Do you see any problems with that?

I'd also want to verify that this method of positioning responds correctly when the element moves due to animation etc.


Tue Aug 31, 2010 11:25 am
Profile

Joined: Tue Aug 31, 2010 2:33 am
Posts: 3
Post Re: Fixed-position elements and mispaced PIE rendering
jason wrote:
Would you mind opening an issue ticket in GitHub for this? That will make sure it doesn't get lost and serves as a checklist for me.

Sure, will do (though probably not until late tonight).

jason wrote:
Reading over your code changes I think you're right that it works fine if the position:fixed element is a child of the body, but if the position:fixed element is a descendant of another positioned element then it won't work right because it still subtracts the position of that parent element.

Yep, that's what I've been suspecting.

jason wrote:
Actually I think that if it's position:fixed we can shortcut past all the getBoundingClientRect stuff and just use the left/top/bottom/right currentStyle properties of the target element directly (except in IE6 of course, which we'd let fall through to the current code). Do you see any problems with that?

Yes, you're probably right there. That'd cover both the descendent-of-positioned-element case and the descendent-of-window case, wouldn't it? I did think about reading the style of the target element, but at that stage wanted to make as few changes to the original code as possible. (I'm not yet familiar enough with how it works to want to makethose bigger changes.)

jason wrote:
I'd also want to verify that this method of positioning responds correctly when the element moves due to animation etc.

I haven't tried it with animation as such, but I have used it with an element being moved via javascript. The way I noticed this was I had an element that I wanted to move with the window scroll until it reached a certain point and then stop there. At that point in the scroll, I changed how it was positioned, and suddenly my PIE-rendered background jumped to a completely different position on the screen. After my fix, it doesn't do that, so I know the new positioning method works when an element is repositioned via script.

But retesting for actual animation would be wise. It could look quite odd to have an element and its background move from one position to another via different routes and meet up at the end.


Tue Aug 31, 2010 7:31 pm
Profile

Joined: Wed Jul 14, 2010 11:46 am
Posts: 1446
Post Re: Fixed-position elements and mispaced PIE rendering
Thanks, Travis, I'll try to get your changes integrated when I have time.


Wed Sep 01, 2010 8:38 am
Profile

Joined: Tue Aug 31, 2010 2:33 am
Posts: 3
Post Re: Fixed-position elements and mispaced PIE rendering
Yeah, no problem. Don't rush yourself. The reason I put some work into diagnosing the issue is so that I can fix it myself, for my own purposes, straight away, so I'm not affected by the wait for you to fix it. With the sample code I posted, others can do their own temporary fixes too.

And thank you for what you've already done on PIE. Even if it isn't (yet) perfect, it's still a lot less work than implementing the same stuff from scratch.


Wed Sep 01, 2010 4:37 pm
Profile

Joined: Thu Sep 09, 2010 9:06 pm
Posts: 1
Post Re: Fixed-position elements and mispaced PIE rendering
Using the latest GIT code [Version 1.0beta3-SNAPSHOT Sep 10 2010] - I was having fixed-position problems.

I added the single line below (===>) to RootRenderer.js:

Code:
    updatePos: function() {
        if( this.isActive() ) {
            var el = this.targetElement,
                par = el,
                docEl,
                elBounds, parRect,
                s = this.getBox().style, cs,
                x = 0, y = 0;

            // Get the element's offsets from its nearest positioned ancestor. Uses
            // getBoundingClientRect for accuracy and speed.
            do {
                par = par.offsetParent;
            } while( par && par.currentStyle.position === 'static' );
            elBounds = this.boundsInfo.getBounds();
            if( par ) {
                parRect = par.getBoundingClientRect();
                cs = par.currentStyle;
                x = elBounds.x - parRect.left - ( parseFloat(cs.borderLeftWidth) || 0 );
                y = elBounds.y - parRect.top - ( parseFloat(cs.borderTopWidth) || 0 );
            } else {
                docEl = doc.documentElement;
                x = elBounds.x + docEl.scrollLeft - docEl.clientLeft;
                y = elBounds.y + docEl.scrollTop - docEl.clientTop;
            }

===>        s.position = el.currentStyle.position === 'fixed' ? 'fixed' : 'absolute';
            s.left = x;
            s.top = y;
            s.zIndex = el.currentStyle.position === 'static' ? -1 : el.currentStyle.zIndex;
            this.isPositioned = true;
        }
    },


This change fixed my layout + positioning problem!
Prior to this code change, I had elements 'growing' large.


Thu Sep 09, 2010 9:21 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 6 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.