Position sticky not working with body{ overflow-x: hidden; } [duplicate]
Asked Answered
K

3

8

I am trying to use bootstrap's sticky header. But when I added body {overflow-x: hidden; } it stopped working.

Now I seen on different pages that position: sticky with it's parent having overflow set to something else as visible not showing up, is (or was) a common problem. But all of the posts were like 1 year old. Like this post: "Position Sticky with overflow-x set for parent div"

Is there a solution by now? Since bootstrap 4 started using it, I would think that it's more supported right now.

$('button').click(function() {
  if($('body').css('overflow-x') !== "hidden"){
    $('body').css('overflow-x', 'hidden');
  } else {
    $('body').css('overflow-x', 'unset');
  }
});
h1 {
  top: 50px;
  width: 100vw;
  text-align: center;
  position: absolute;
}

span{
  font-size: 15px;
}

button{
  position: fixed;
  right: 20px;
  top: 10px;
  z-index: 10;
}

nav {
  position: sticky;
  top: 0;
  height: 40px;
  background-color: green;
  margin-top: calc(100vh - 40px);
}

nav ul li {
  float: left;
  list-style-type: none;
  line-height: 40px;
  margin-right: 15px;
}

article {
  height: 200vw;
}

html {
  overflow-x: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>

<body>
  <h1>Scroll down.. <br><span>and toggle the button</span></h1>
  <button>toggle body{overflow-x;}</button>
  <nav>
    <ul>
      <li>Link#1</li>
      <li>Link#2</li>
      <li>Link#3</li>
    </ul>
  </nav>
  <article>
    Some content...
  </article>
</body>

</html>
Kammerer answered 7/5, 2018 at 12:35 Comment(0)
L
0

As far as I know, you cannot use it by now. It is still only partially supported in some browsers.

When you want to know how far it is with this feature, I can advise you to check it on caniuse.com.

Sticky Feature: https://caniuse.com/#feat=css-sticky

Lazaro answered 7/5, 2018 at 15:30 Comment(4)
Oh, but then how does it work on my chrome, and I have seen kinda big websites use the sticky-top class from bootstrap, so that makes me think that it would be somewhat supported..Kammerer
They are probably using JS in addition. w3schools.com/howto/tryit.asp?filename=tryhow_js_sticky_headerLazaro
Alright, thanks for the info. Then I guess I can't use the sticky class. I think then I will just use the fixed-position when scrolled over 100vh off the page.Kammerer
A year later and position: sticky is no longer experimental with good cross browser (minus IE).Neysa
N
2

UPDATE:

This has been successfully tested on Safari v12.0.2, Firefox v64.0, and Chrome v71.0.3578.98

Added position: -webkit-sticky; for Safari.


The simple solution is to have only overflow-x: hidden; on the body and NOT the html element. Here is the amazing comment buried in the discussion on making the spec clearer regarding overflow and position sticky that helped me to figure this out.

So make sure to remove it from the html element and also any ancestor elements of the element you want to be sticky. I posted about the ancestor issue in more depth here: https://mcmap.net/q/319218/-body-overflow-x-hidden-breaks-position-sticky.

I have tested this on Firefox, Chrome, & Safari. Make sure to prefix for Safari as well.

I copied your snippet here with the adjustment that I mentioned and it works in both scenarios when you toggle on and off overflow-x: hidden; on the body.

$('button').click(function() {
  if($('body').css('overflow-x') !== "hidden"){
    $('body').css('overflow-x', 'hidden');
  } else {
    $('body').css('overflow-x', 'unset');
  }
});
h1 {
  top: 50px;
  width: 100vw;
  text-align: center;
  position: absolute;
}

span{
  font-size: 15px;
}

button{
  position: fixed;
  right: 20px;
  top: 10px;
  z-index: 10;
}

nav {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  height: 40px;
  background-color: green;
  margin-top: calc(100vh - 40px);
}

nav ul li {
  float: left;
  list-style-type: none;
  line-height: 40px;
  margin-right: 15px;
}

article {
  height: 200vw;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>

<body>
  <h1>Scroll down.. <br><span>and toggle the button</span></h1>
  <button>toggle body{overflow-x;}</button>
  <nav>
    <ul>
      <li>Link#1</li>
      <li>Link#2</li>
      <li>Link#3</li>
    </ul>
  </nav>
  <article>
    Some content...
  </article>
</body>

</html>
Neysa answered 9/1, 2019 at 19:6 Comment(1)
I changed with $('body, html').css('overflow-x', 'hidden'); does not works.Creamcups
L
0

As far as I know, you cannot use it by now. It is still only partially supported in some browsers.

When you want to know how far it is with this feature, I can advise you to check it on caniuse.com.

Sticky Feature: https://caniuse.com/#feat=css-sticky

Lazaro answered 7/5, 2018 at 15:30 Comment(4)
Oh, but then how does it work on my chrome, and I have seen kinda big websites use the sticky-top class from bootstrap, so that makes me think that it would be somewhat supported..Kammerer
They are probably using JS in addition. w3schools.com/howto/tryit.asp?filename=tryhow_js_sticky_headerLazaro
Alright, thanks for the info. Then I guess I can't use the sticky class. I think then I will just use the fixed-position when scrolled over 100vh off the page.Kammerer
A year later and position: sticky is no longer experimental with good cross browser (minus IE).Neysa
B
-1

There is still no native solution to this problem.

However, I wrote a fallback script for these cases: fl_sticky

Beret answered 8/1, 2019 at 17:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.