CSS - "position: fixed" acting like "absolute" in Firefox
Asked Answered
S

10

21

I've been building a website in Safari, and I've just tested it in Firefox and my fixed navigation elements are behaving as if they're position is absolute.

#navigation {
    display: block;
    width: 100%;
    height: 50px;
    position: fixed;
    left: 0px;
    bottom: 0px;
    text-align: center;
    z-index: 99000;
}

This is the CSS I have for the primary navigation wrapper (it's a bottom nav.). In Webkit, it works perfectly: that is, it sticks to the bottom of the window regardless. In firefox, it positions itself at the end of the tags, so, for example, on a long page, I'd have to scroll down just to see it. It is acting as if it's absolute.

I also have a sidebar navigation.

.slidebar {
    display: block;
    position: fixed;
    left: -1px;
    top: -1px;
    width: 1px;
    height: 100%;
    overflow: hidden;
    -webkit-transition: all 300ms ease;
    -moz-transition: all 300ms ease;
    -o-transition: all 300ms ease;
    -ms-transition: all 300ms ease;
    transition: all 300ms ease;
    z-index: 99998;
}

This sidebar is also acting as if it's absolute - that is, it is positioning itself off the screen properly, but it's elongating <body> and thus the horizontal scrollbar appears. The height: 100%; is also responding to the <body> height and not the window height, so, for example, my <header> has a top margin of 20px, and the slidebar observes that margin too (the body has 0 margin). Likewise, instead of the height: 100%; ending at the bottom of the window, it ends at the bottom of the <body>, factoring in the footer's bottom margin.

I cannot understand for the life of me why this is happening. Element inspection shows all the properties are loading fine, and in Chrome and Safari it works. It worked initially, and it worked the last time I even edited either navigation, but it has since stopped working since I built other, irrelevant, parts of the site.

http://www.upprise.com/demo.php - click the Envelope icon to see the sidebar

Stoma answered 29/1, 2014 at 19:23 Comment(2)
Can you provide an example demonstrating this? It would be extremely helpful in solving your problemGodship
upprise.com/demo.php @JoshCStoma
S
22

Through the process of elimination I was able to determine that having the following in my body was causing all the problems with fixed divs in Firefox:

-o-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;

I had originally added this code to prevent flickering in certain CSS transitions throughout the site, but I guess I'll have to add it to each individual class now.

Stoma answered 29/1, 2014 at 22:48 Comment(3)
I can't believe I spent two days on this before discovering this one. Thanks for posting!Laborsaving
Here's the relevant Firefox bug report: bugzilla.mozilla.org/show_bug.cgi?id=876341. It looks the CSS spec says any fixed element with a transform applied to it is treated like a container for absolutely positioned elements. Firefox takes backface-visibility as a transformation, whereas Webkit requires an explicit transform.Laborsaving
Note that filter also creates a containing block. Firefox also seems to persist the containing block when an element had a transform style applied to it, but doesn't have it applied any longer. Worth a read: meyerweb.com/eric/thoughts/2011/09/12/…Bolo
F
26

I had the exact same problem, turns out the following CSS property of a parent element was causing the problem.

transform: translate3d(0px, 0px, 0px);
Fabrienne answered 12/9, 2014 at 13:32 Comment(3)
transforms + position:fixed = bad things. (Source)Oneeyed
Just to add to this, the 'perspective' property also triggers this bug. Very annoying.Myrnamyrobalan
backdrop-filter can cause the same problem tooHandbreadth
S
22

Through the process of elimination I was able to determine that having the following in my body was causing all the problems with fixed divs in Firefox:

-o-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;

I had originally added this code to prevent flickering in certain CSS transitions throughout the site, but I guess I'll have to add it to each individual class now.

Stoma answered 29/1, 2014 at 22:48 Comment(3)
I can't believe I spent two days on this before discovering this one. Thanks for posting!Laborsaving
Here's the relevant Firefox bug report: bugzilla.mozilla.org/show_bug.cgi?id=876341. It looks the CSS spec says any fixed element with a transform applied to it is treated like a container for absolutely positioned elements. Firefox takes backface-visibility as a transformation, whereas Webkit requires an explicit transform.Laborsaving
Note that filter also creates a containing block. Firefox also seems to persist the containing block when an element had a transform style applied to it, but doesn't have it applied any longer. Worth a read: meyerweb.com/eric/thoughts/2011/09/12/…Bolo
S
4

It appears that some browsers will will apply fixed positioning relative to the window, while Firefox is applying it relative to the <body />. You need to make your body 100% tall:

body {
    height: 100%;
}

But the margin from your .header is collapsing outside of the body element. Change this:

margin: 25px auto;

to this:

margin: 0 auto; /* updated - thanks JoshC */
padding: 25px auto;
Sanctum answered 29/1, 2014 at 19:47 Comment(1)
yeah, just noticed. I upvoted yours b/c I overlooked the fact that the "auto" margin was actually being used - DOH!Sanctum
H
4

I solved the issue by moving the element that uses position: fixed; out of its original parent element that uses transform: translateX(-50%);.

Thus...

<div class="transformed-container">
   <div="fixed-element"></div>
</div>

...became...

<div class="transformed-container"></div>

<div class="fixed-element"></div>

Two things led me to this conclusion:

  1. @Pankaj's answer shows that the translate value can cause an issue.
  2. @Wildhoney's comment to another answer references an explanation of the underlying cause: http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/
Hurrah answered 17/7, 2017 at 18:30 Comment(3)
This is a great answer! In my case, I had an element with background-attachment: fixed that was acting like background-attachment: scroll. I noticed that it worked as expected when I moved it out of its parent, but didn't know why. I tried converting it to a position: fixed with a clip-path on its container, but then I ran into position: fixed acting like position: absolute. I learned from this answer that my problem was the parent being animated in and thus having transform set to 0 after animation. Now, I have the animation setting transform to an empty string when it's done.Stebbins
In addition, a filter css attribute will also break fixed position elements.Furan
that link saved me. Thanks. Should include a summary of the info there, in case that link breaks--it's quite old. Short version for future readers: there's a quirk in CSS wherein certain operations, like transform, break 'position: fixed' for any child element, permanently, from then on.Lixivium
G
2

The problem seems to be in your body, i've added width:100%; height:100%; and overflow:hidden; to it in my fire fox and it looked just fine, except for the bottom menu-bar that went half of it's height over the bottom.

Gaskill answered 29/1, 2014 at 19:47 Comment(0)
G
1

Not sure why the browsers were rendering differently, though the solution is pretty simple. You need to give the parent elements (html/body) a height of 100% in order to fill the entire page. It seems like FF rendered the fixed elements at the bottom of the contents as opposed to the bottom of the window. Adding the following will make it work across browsers:

html, body {
    height: 100%;
}

In addition, you should also use padding on .header element as opposed to a margin. This will solve another issue.

.header {
    margin: 0 auto;    /* use a value of 0 rather than 25px */
    padding: 25px 0;
}

I tested all this in the browser, it will work in FF now. It should also render properly in Chrome and others.

Godship answered 29/1, 2014 at 19:47 Comment(0)
G
1

I needed to remove some css classes from the superior container of the fixed-on-scroll element that had a transition, from the animateCSS library.

$(window).on('scroll', function () {
     if (distance <= 65) {
        $('#my-contaniner').removeClass('animated fadeInLeft'); //delete problematic classes for FF
Add your code
 });

Maybe it helps

Glassman answered 25/10, 2016 at 11:8 Comment(0)
C
1

After 5 hours of debugging, if you are using tailwindcss and you have drop-shadow-* (pay attention it's not shadow-*) class on one of your parent elements, it will cause the fixed elements within that element to act like they're absolute positioned.

Not sure why that is happening, maybe due to fact that tailwindcss is using lots of combined CSS variables.

Here's an example of what gets generated with tailwindcss drop-shadow-* utility, seems like filter property on one of the parent elements causes the same unexpected behaviour as transforms:

.drop-shadow-lg {
    --tw-drop-shadow: drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1));
    filter: var(--tw-filter);
}
Centi answered 2/11, 2021 at 6:32 Comment(0)
S
1

I had this same issue in Chrome, and the backdrop-filter property on the parent was causing the issue. I remove that property and position: fixed behaves normally.

Stypsis answered 1/12, 2023 at 13:17 Comment(0)
A
0

I had the same problem. In my case, the root of the problem was an ANIMATION on the body, so take care with "animations" on elements that are parents of the element that you want to be "position: fixed".

I don't know why this happen...

Here you can see more people talking about this issue with position: fixed and animation

Alkyne answered 2/6, 2023 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.