Jump to content

Change to position fixed on iOS Safari while scrolling

Posted in CSS/SASS · 1 minute read

If you ever had to fix element on scroll, you probably had an issue on iOS Safari (and other mobile devices). Element will usually flicker, and disappear until scrolling has stopped completely.

Just force GPU acceleration by adding transform: translate3d(0,0,0); to your element.

You will have something like this:

.Element-header {
  transform: translate3d(0,0,0);
}

.Element-header--fixed {
  top: 0;
  position: fixed;
}

Enjoy ¯\_(ツ)_/¯

Update, if the element inside fixed one flickers #

In the comments Matt made a great tip, so I'm adding it here as well:

If you are styling the element within fixed element, you need to apply the translate3d hack to the nested element in order for it to not flicker/disappear.

Thanks Matt!

Comments (27)

5. January 2021
LXX

Cool !!!

3. February 2020
Dasha

I have the same issue.

When I have a input at the bottom of the page and on its focus, I get extra white space while scrolling. How to get rid of this white space.

Has someone found a solution ?

Thanx)

25. October 2019
Krish

Matt, when I have a input at the bottom of the page and on its focus, I get extra white space while scrolling. How to get rid of this white space.

The parent div is fixed.

6. September 2019
Edison Neo

You are a genius, thanks for saving my life

8. August 2019
David

Hi, Why is this not working for me? ive got my button fixed to the bottom with CSS: position: fixed; bottom: 0; left: 0; border-radius: 0;

within a div with CSS: margin-top: 1.5em; text-align: left;

I can provide more information if that is not enough

18. June 2019
Stanko

Hi Sean,

That is correct, position: fixed won't work if any parent element has a transform applied. Unfortunately, without a example it is hard to see what is going on in your case. Try applying transform: translate3d(0, 0, 0) and backface-visibility: hidden hacks, but it is hard to tell if that is going to help.

Cheers!

18. June 2019
Sean

I've got the transform on the parent of a child that is fixed to the top of a modal whose contents are scrollable, which is set to be 100% of the width and height of the viewport, interestingly, the transform seems to just prevent the child element from being fixed, it no longer scrolls with the page, if I remove the transform from the parent, the child will scroll with the page, but it's flickering real bad. Can you think of any reason why this would happen? I'm stumped.

23. April 2019
Rohit Arora

This saved my life, how do you find out this hidden feature :)

5. December 2018
Mark

I had an element whose styling would change from relative to fixed but would sometimes fade out and no longer work after a few events on MacBook Air Safari OS 10.14.1. Adding this CSS styling to the element resolved the issue.

9. July 2018
Roslan

Works great! thank you.

12. May 2018
Stanko

Hello @thangavel,

I've stripped huge chunk of code you posted in your comment. It was unreadable, next time please try making example on codepen or jsbin.

Cheers!

12. May 2018
thangavel

Hi Stanko,

I have tried with your solution. But in our side is not working in iPhone. Please let me know what i wrong in below code

My code is

[code stripped]

2. January 2018
Lubos

Hi Stanko! No feedback on the article, just leaving an online trail as I somehow ended up here and you’re somehow 1 of 2 people I follow on GitHub so I recognised you.

17. October 2017
Suzy

Worked great! Wonderful solution. Thank you!

31. August 2017
Jeka

God bless you, my friend! It's works like a miracle!

29. June 2017
Stanko

Hello Michael,

Not sure what you are asking, but my guess is - should you apply translate3d to children of the element with position: fixed? It depends of the usecase, like Matt suggested, if children elements are flickering you should apply translate3d on them.

Hope that answers your question, cheers!

28. June 2017
Michel

Hey, I need to understand one thing, i must to apply translate3d at every element that it will pass scroll through the fixed element?

5. May 2017
Johnthan

Wow, fast reply, thank you! OK it was because I put them in one single class, but still I got these flickering...

I also tried with backface visibility hidden, but no chance.

5. May 2017
Stanko

Hello Jonathan, probably something else in your code removed it. CSS property can't be canceled by itself.

5. May 2017
Johnthan

Thanks for the article I tried it directly on my element fixed, but the fixed position somehow got canceled?

31. March 2017
Stanko

Haha thanks a lot Zack! :) no worries, you made my day, that's enough!

30. March 2017
Zack

Wow, if you had a donate button on this article I would pay you. You fixed my issue of hours of research!

3. March 2017
Nacho

Great! You resolve me a huge problem! Txh a lot!

16. February 2017
Harsha

works cool for position absolute too, thanks

12. January 2017
Stanko

Thank you both, Matt for the tip and anarchimedes for the feedback.

I hope you don't mind I added it to the article as well.

12. January 2017
anarchimedes

works like charm -- after Matt's suggestion

10. January 2017
Matt Robitaille

This was helpful for me – however, I found that if I had a fixed position on an element but was styling the element within it, I had to apply the translate3d to the nested element in order for the element to not flicker/disappear. This may be helpful to some others.