I have an element that I am making sticky with position sticky:
#header {
position: sticky;
width: 100vw;
top: 0;
}
<app-header id="header"></app-header>
And that works fine, but I realised that if I use:
body {
overflow-x: hidden;
}
That breaks sticky, and I need to set body overflow-x to hidden, how can I fix that, with only CSS solution, no JS solutions?
Setting the overflow-x property to value clip helped me achieve position sticky and prevent scrolling.
Here is more explanation in this article
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.
Unfortunately the spec is not too clear about the implications of overflow-x: hidden; on position sticky, but there is a way to fix this. Thankfully there is an issue to hopefully fix this: https://github.com/w3c/csswg-drafts/issues/865.
The simple solution is to remove or unset overflow-x: hidden; from every ancestor of the element you want to have position: sticky;. Then you can have overflow-x: hidden; on the body and it will work!
Also double check that you don't have overflow set on both the body and html tags which I posted about more in depth here: https://stackoverflow.com/a/54116725/6502003
Here is a pen if you want to play around with it: https://codepen.io/RyanGarant/pen/REYPaJ
/*
Try commenting out overflow on body style and uncommenting
overflow on .overflow-x-hidden class and you will see
position sticky stop working!
*/
body {
overflow-x: hidden;
}
.overflow-x-hidden {
/* overflow-x: hidden; */
border: 1px solid blue;
}
h1 {
background: palevioletred;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
.tall {
background: linear-gradient(to bottom, paleturquoise, white);
height: 300vh;
width: 100%;
}
<div class="overflow-x-hidden">
<h1>I want to be sticky!</h1>
<div class="tall"></div>
</div>
The sticky doesn't work inside element with overflow: hidden or auto.
Refer to this https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky
A workaround can be working with this library
body, html { overflow-x: clip; }
This works well with position: sticky
Im using transform: translateX(-100px) for load animations and overflow-x:clip prevents expanding the viewport and showing horizontal scrollbar..
Not sure if this helps, but I struggled with this for mobile (where the page would "overflow" and scroll past the boundaries) for so long and finally fixed it.
I tried the body {overflow: hidden;} solution, but it would disable my sticky elements. So I then created a <div class="container"> that contained all of my other divs of the page inside the <body>, and that seemed to do it!
I just want to add this here if anyone runs into a similar issue. position:sticky was not working for me because we are applying overflow-y:scroll on tablet/mobile screen resolutions. overflow: and position:sticky do not work together. This article explains the 2 workarounds to fix it. I went with setting a fixed height on the table and then hiding the vertical scroll bar with
::-webkit-scrollbar {
width: 0;
background: transparent;
}::-webkit-scrollbar {
width: 0;
background: transparent; /*
}
This is how I make it work for me:
Create a parent wrapper/container element that should contains all your other page elements, and give it a fixed height (mostly height: 100vh) with overflow-y: auto and overflow-x: hidden as it's described in the code/snippet below ..
and make the body overflow: hidden to avoid any extra scroll bars ..
This solution may comes with some consequences/restrictions, for example:
if you're used to use the CSS scroll-behavior property in the html element you will need then to move it to the #page_wrapper element instead ..
body {
margin: 0;
overflow: hidden;
}
.page-wrapper {
height: 100vh;
overflow-y: auto;
overflow-x: hidden;
}
.sticky {
position: sticky;
left: 0;
padding: 4px;
text-align: center;
background-color: forestgreen;
}
.sticky-header {
top: 0;
}
.sticky-footer {
bottom: 0;
}
.long-content {
padding: 2rem;
min-height: 100vh;
}
.break-overflow-x {
min-width: 200vw;
padding: 2rem;
background-color: red;
}
<body>
<div class="page-wrapper">
<div class="sticky sticky-header"><button>Sticky Header</button></div>
<div class="long-content">Long vertical content</div>
<div class="break-overflow-x">Long horizontal content</div>
<div class="long-content">Long vertical content</div>
<div class="sticky sticky-footer"><button>Sticky Footer</button></div>
</div>
</body>
I think you have to fix :
body {
overflow-x: clip;
}
I hope this works .
can you try with the following...
#one { position: sticky; top: 10px; }* {
box-sizing: border-box;
}
body{overflow-x: hidden;}
dl > div {
background: #FFF;
padding: 24px 0 0 0;
}
dt {
background: #B8C1C8;
border-bottom: 1px solid #989EA4;
border-top: 1px solid #717D85;
color: #FFF;
font: bold 18px/21px Helvetica, Arial, sans-serif;
margin: 0;
padding: 2px 0 0 12px;
position: -webkit-sticky;
position: sticky;
top: -1px;
}
dd {
font: bold 20px/45px Helvetica, Arial, sans-serif;
margin: 0;
padding: 0 0 0 12px;
white-space: nowrap;
}
dd + dd {
border-top: 1px solid #CCC;
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/position -->
<dl>
<div>
<dt>A</dt>
<dd>Andrew W.K.</dd>
<dd>Apparat</dd>
<dd>Arcade Fire</dd>
<dd>At The Drive-In</dd>
<dd>Aziz Ansari</dd>
</div>
<div>
<dt>C</dt>
<dd>Chromeo</dd>
<dd>Common</dd>
<dd>Converge</dd>
<dd>Crystal Castles</dd>
<dd>Cursive</dd>
</div>
<div>
<dt>E</dt>
<dd>Explosions In The Sky</dd>
</div>
<div>
<dt>T</dt>
<dd>Ted Leo & The Pharmacists</dd>
<dd>T-Pain</dd>
<dd>Thrice</dd>
<dd>TV On The Radio</dd>
<dd>Two Gallants</dd>
</div>
</dl>
For those who have the same issue. I added overflow: hidden to the div below the header holding all the contents.
<div class="header" style="position: sticky;">
//navs
</div>
<div class="content-div" style="overflow: hidden;">
//contents
</div>
Related
I'm having an issue here where I constantly have an overflow-x whenever I set my side navigation off screen using translate. The real problem is that if I set an overflow-x:hidden; to all the ancestors div. It will stop my position sticky logo to work.
I've done my research and some of the following recommendation for fix was to add an overflow-x:hidden to the body itself and it would work. However it doesn't work in my case since there is a side navigation that is off screen.
The odd thing is that after adding overflow-x:hidden to the body. It fixes the overflow issue and the sticky logo is working but only on desktop mode. The moment I switch to mobile (Ctrl + Shift + M on Firefox and enable touch simulation), the overflow-x starts to scroll once again and the position sticky doesn't stick.
Here is a code snippet that I've found online in which I've added an additional side nav on the right so simulate my case.
HTML
<body>
<main>
<div class="overflow-x-hidden">
<h1>I want to be sticky!</h1>
<div class="sidenav"></div>
<div class="tall"></div>
</div>
</main>
</body>
CSS*
body {
overflow-x: hidden;
position: relative;
}
.overflow-x-hidden {
border: 1px solid blue;
}
h1 {
background: palevioletred;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
.tall {
background: linear-gradient(to bottom, paleturquoise, white);
height: 300vh;
width: 100%;
}
.sidenav{
width: 250px;
height: 100%;
background: black;
position: absolute;
right: 0;
transform: translateX(100%)
}
Here are some of the similar issues that I've found.
Position sticky not working with body{ overflow-x: hidden; }
body { overflow-x: hidden; } breaks position: sticky
https://github.com/w3c/csswg-drafts/issues/865
https://bugzilla.mozilla.org/show_bug.cgi?id=1329203
For anyone struggling with this issue, I have similar issues and found a solution at https://stackoverflow.com/a/71268988/14151733.
Setting the overflow-x property to value clip helped me achieve
position sticky and prevent scrolling.
Here is more explanation in this article
CSS
.overflow-x-clip {
overflow-x: clip;
}
.sticky {
position: sticky;
top: 0;
}
HTML
<body class="overflow-x-clip">
<nav class="sticky">
...
</nav>
</body>
One example is better than a thousand words, so here you go:
https://jsfiddle.net/jesuxapo/os53cyc1/
As you can see, the height is responsive, but not completely. The problem is the <div id="k"> with fixed height of 150px. Try to play with it and I think you'll understand exactly what I mean. I want to get rid of this 'problem' somehow.
I could use the calc() of the css3, however it's not cross-browser(especially android and IE8-9).
Perhaps there's some other solution for this using html and css languages?
You may use the display:table properties (IE8 and later):https://jsfiddle.net/os53cyc1/1/
it will grow if content is more than 100vh all together
html, body {
padding: 0;
margin: 0;
height: 100%;
background: #333;
font-weight: bold;
color: #fff;
}
body {
display:table;
width:100%;
}
body>div {
display:table-row;
}
div {
border: solid 2px #FFFF00;
}
div#a {
position: relative;
background: #800000;
width: 100%;
height: 100%;
}
div#b {
position: absolute;
top: 0;
}
div#c {
position: absolute;
bottom: 0;
}
div#k {
height: 150px;
background: #008000;
}
<div id="k">
Hello, I'm K and I just broke your code
</div>
<div id="a"><br><br><br><br>
This is relative div with height of 100% and max-height of 500px
<div id="b">
This div is aligned to the top of the Red div
</div>
<div id="c">
This div aligned to bottom of the Red div
</div>
</div>
I have a simple div wrapper with four spans inside.
<body>
<main>
<div>
<span>One</span>
<span>Two</span>
<span>Three</span>
<span>Four</span>
</div>
</main>
</body>
The div is positioned absolutely so that I can get it to touch the bottom of the screen, and text-align is justify so the spans inside are evenly spaced. This works fine until I try to make my spans height: 100%, then a mysterious white space appears outside of the actual flow on the very bottom. I think this has something to do with my div:after psudo-element but I have absolutely no idea what's going on.
* {
padding: 0;
margin: 0;
}
main {
position: relative;
height: 100vh;
width: 100%;
background-color: rgb(45, 45, 65);
text-align: center;
}
div {
position: absolute;
top: 50%;
left: 25%;
right: 25%;
bottom: 0;
text-align: justify;
display: block;
}
div:after {
display: inline-block;
width: 100%;
content: '';
}
span {
background-color: rgb(25, 25, 45);
box-sizing: border-box;
display: inline-block;
font-size: 1em;
padding: 10px;
height: 100%;
}
span:hover {
background-color: white;
}
Do I not understand how :after works, or is this some kind of a glitch? Where in the world is that white spacing coming from on the bottom?
Here's a reproduction of the problem: http://codepen.io/anon/pen/qdpERR?editors=110
simply add an overflow: hidden; to the main or even the parent of the main should works.
Check the link
http://codepen.io/TibicenasDesign/pen/yNpyLr?editors=110
Uncomment overflow: hidden; or box-sizing: border-box then, the white space at the end of the web will be removed.
Also the box-sizing works ! i always have it with border-box so forgot it haha, and maybe its a better solution
Another option may be to add box-sizing:border-box, becauase you have padding on those link elements.
This question already has answers here:
CSS overflow-x: visible; and overflow-y: hidden; causing scrollbar issue
(9 answers)
Closed 6 years ago.
When I set overflow-y on a block, it seems to be affecting the overflow-x property. I've made a JSFiddle with an example of this problem. It seems to be happening in all browsers, so I think I'm missing something that should be obvious.
I have two non-overlapping blocks (blue and green) along with a third block (red) with the following requirements:
The blue and red blocks are adjacent
The red block is contained in the blue block, but it overlaps the green block
The blue block must allow vertical scrolling, but not horizontal scrolling
However, if I set overflow-x: visible so the red block overlaps to the right, instead it behaves as though I set it to scroll. However, if I remove the overflow-y property or set it to visible, the red block behaves as I expect.
I do need vertical scrolling, so I'm at a loss for what to do.
With the code below
HTML:
<div id="container">
<div id="left">
<div id="floater"></div>
</div>
<div id="right">
</div>
</div>
CSS:
#container {
height: 200px; width: 200px;
position: relative;
background-color: #ccc; border: solid 5px black;
}
#left {
position: absolute;
top: 0; left: 0; bottom: 0; width: 100px;
overflow-x: visible;
overflow-y: auto; /** REMOVING THIS CHANGES THE RESULT **/
background-color: blue;
z-index: 2;
}
#right {
position: absolute;
top: 0; right: 0; bottom: 0; width: 100px;
z-index: 1;
background-color: green;
}
#floater {
position: absolute;
right: -20px; top: 30px; height: 40px; width: 40px;
background-color: red;
}
See: CSS overflow-x: visible; and overflow-y: hidden; causing scrollbar issue
If you are using visible for either overflow-x or overflow-y and
something other than visible for the other, the visible value is
interpreted as auto.
I have this container which can scroll the content. I would like the header in this container to always stay in the top.
http://jsfiddle.net/z9ze5/
Container:
.lists {
width: 300px;
height: 250px;
margin: 30px auto;
background: #39C;
overflow: scroll;
position: relative;
}
Header:
.box_header {
width: 100%;
height:30px;
overflow:hidden;
position: absolute;
margin: 0;
background: #DDD;
z-index: 999;
}
If you are willing to alter your mark-up, here is one way of doing it:
<div class="lists">
<header class="box_header">
<h1>HEADER 2</h1>
<div class="setting" id="btn2"></div>
</header>
<section class="content">
<p>Lorem Ipsum ....</p>
</section>
</div>
Wrap your scroll area in a <section> (or other block level element).
For your CSS:
.lists {
width: 300px;
height: 250px;
margin: 30px auto;
background: #39C;
position: relative;
}
section.content {
width: 300px;
height: 220px;
margin: 0 auto;
background: #39C;
position: relative;
top: 30px;
overflow: scroll;
}
Please see fiddle: http://jsfiddle.net/audetwebdesign/nGGXx/
More Advanced Example
If you study the following example:
http://jsfiddle.net/audetwebdesign/fBNTP/
uou can see how your scrolling boxes could be applied in a semi-flexible layout.
I lined up two scrolling boxes side by side and made their width proportionate to the width of the page.
The height is trickier to adjust. I fixed the height of the parent container, see the following rule:
.contentWrapper {
border: 1px solid red;
margin-top: 1.00em;
padding: 30px 0;
overflow: auto;
height: 400px;
}
If you change the height from 400px to some other value, the scrolling boxes will adjust themselves.
Hopefully, these examples will give you and others some more insights into how to build these more advanced layout designs.
If you want a non-css fix, add this listener...
$('.lists').scroll(function() {
$('.box_header', this).css('top', $(this).scrollTop()+'px');
});
and then change .lists css to give relative positioning
.box_header {
width: 100%;
height:30px;
overflow:hidden;
position: relative;
margin: 0;
background: #DDD;
z-index: 999;
}
Any position absolute within a position relative is absolute to the relative container. In order to have a header that stays in position, you'd need to position it above, not within, the scrolling container.
look at adding position: fixed to your header div .box_header. You may have to add padding of the height of the box header div to section.content but as you have that set to 30px that should be fine. IE6 and lower has issues with fixed positioning but hopefully we can live with that now - less people are using that than are still listening to Moby.