I want to prevent horizontal overflow for the body of the page and allow sticky elements at the same time. The solution seems simple at a first glance:
html {
overflow-x: hidden;
}
Everything works as expected on desktop. If you test it on mobile devices or choose a mobile device in Chrome dev tools, this will fail to work though. Apparantly, because touch devices ignore overflow-x: hidden for html and body tags as it's pointed out in many answers here on SO. So we have to use this instead:
html, body {
overflow: hidden;
}
However, this breaks sticky positioning. I know specifying the body height explicitely should fix the issue:
html, body {
height: 100%;
overflow: hidden;
}
body {
min-height: 100%;
}
Voila, everything seems to work well on mobile and desktop devices. However, this breaks window.onscroll event because it's the body that is scrolling now. So most of the scroll dependant libraries will fail to work (e.g. AOS). I kind of gave up at this point. Anybody has a solution to this? I'd love to avoid JavaScript solutions if possible.
I have a website with a meta tag
<meta name="viewport" content="width=device-width, initial-scale=1.0">
and height:100%; on html and body tags.
When I access this site from Safari (iOS 13.5.1) and do the following:
rotate my device to the landscape mode
then rotate it back to the portrait mode
then a white space appears on the bottom of the screen. This space is not a part of the page html code. It is outside of the html tag.
Minimum reproducible example: https://jsbin.com/cojabiquza
This seems to be related to the Safari behaviour when it hides the address panel and the bottom panel when the device goes to the landscape mode. And when it goes back to the portrait mode the panels are shown again but the browser "forgets" to recalculate something and shows an extra space on the bottom of the page.
Deleting <meta name="viewport"... fixes it. But I can't get rid of it because I have a responsive website.
In other browsers it works well.
Please share your experience if you know how to fix it.
#Jax-p answer
is valid for the bug I described but it causes another problem.
When you use 100vh the content starts to be hidden behind the address bar:
So in my real life app I ended up with a bunch of hacks:
document.addEventListener('orientationchange', () => {
document.documentElement.style.height = `initial`;
setTimeout(() => {
document.documentElement.style.height = `100%`;
setTimeout(() => {
// this line prevents the content
// from hiding behind the address bar
window.scrollTo(0, 1);
}, 500);
}, 500);
});
This hack more or less fixes the problem in iOS Safari 12 and 13
After spending most of the day dealing with this "feature" (again), I created a CSS-only solution for iOS 14.4 on iPad, iPhone, and works normally on all regular browsers. No hacks required. The secret is to use 100vh on the HTML and BODY elements, while using position:fixed on your outermost wrapper element with all of the edges clamped to zero.
Notes: there is a visual artifact when rotating the screen if your BODY background is any different than your wrapper background. This same issue also lets you color the address bar at the top by purposefully giving BODY a different background color (optional).
HTML, BODY {
height: 100%;
width: 100%;
height: 100vh;
width: 100vw;
margin:0;
padding:0;
/* required to prevent rogue scrollbars */
overflow: hidden;
/* cosmetic stuff: */
background-color:#5AE;
}
#wrapper {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
padding:0;
margin:0;
/* if you want the content to scroll normally: */
overflow: auto;
/* cosmetic stuff: */
background-color:#AEA;
border: #6B6 1em solid;
box-sizing:border-box;
}
<html>
<head>
<meta name="viewport" content="height=device-height, initial-scale=1, width=device-width, initial-scale=1" />
</head>
<body>
<div id="wrapper">
Content goes here.
</div>
</body>
</html>
Mobile browsers usually hide their address bar and controls menu while you scroll (or in some cases when you change from portrait to landscape). It might cause some problems while using height: 100%; because sometimes the browser doesn't recalculate percentage values in the right way (it doesn't sum address bar height).
If you want to fill 100% of viewport height you should use height: 100vh; (vh = viewport height). I hope it helps.
As I was also searching for a solution to this problem I found this blog post with the following solution:
window.onresize = function() {
document.body.height = window.innerHeight;
}
window.onresize(); // called to initially set the height.
try this:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
On my laptop I can remove the space right for the element by making it bigger and then set overflow: hidden but on my iPhone it will just make a horizontal scroll bar. How can I fix this? I have tried to use media queries but it doesn't work either.
Try this code-
elementSelector{
width: 100%;
overflow: hidden !important;
}
This can be fixed by using the overflow: hidden attribute on <HTML> like this <HTML style="overflow: hidden">
I'm working on http://preview.j64e7zzvo82p4x6r4fdjze6piimmfgviwsruf9j89pidaemi.box.codeanywhere.com/ and have nearly finished making it responsive.
But for some reason when the browser is sized to anything below 991px in width then it creates whitespace on the right side. All of the content will snap to the screen size but at the end of the day you can still scroll to the right and see a big black background because of all the whitespace.
I thought it was the images on the size that were to big for the viewport but even after removing the images, adding the img-responsive class to the images, and other attempts to fix, the site still has this problem
What is causing all of this whitespace?
The rule for #ctaButtons has a fixed width. Try replace it to auto:
#ctaButtons {
width: auto;
height: 120px;
padding: 20px;
margin: 0 auto;
}
Adding this fixed it for me - you are missing the viewport code from what I can see - for example:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
You can read more at - the third paragraph down http://getbootstrap.com/css/
edited, actually I must have tried that while you applied you fix... I'd still put the viewport in though!...
Try adding overflow-x: hidden; to your container <div>.
I hope you guys can help me cause I cant seem to wrap my head arroud this. I build a one-page site which works fine, except for one thing, which is the overflow-x:hidden on the tablet viewport (and probably smartphone too, havent tested that yet)
Despite the body having body {overflow-x:hidden;} which works fine within normal browsers on the pc, i am able to move to the side for about 25 pixels or so, cause thats the overflow of my rotated div, that sticks out of the screen, which i wanted to hide.
Is there a way to fix this? I supplied below part of the head and html / css
The viewport meta tag.
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
The CSS applied to the media queries and they respective elements that overflow
#media only screen and (max-width: 992px){
#skills, #experience {overflow-x:hidden;}
}
#media (max-width: 479px){
body {overflow-x:hidden;}
}
And the regular CSS applied to the html / body tags
body, html {height: 100%;width: 100%;font-family: 'Source Sans Pro',Helvetica,Arial,sans-serif;color: #757575; overflow-x:hidden;}
The id's #skills and #experience have a class called .hoek which is defined as followed and causes the overflow.
.hoek {margin: 0 -50px;
-webkit-transform-origin:left center;
-moz-transform-origin:left center;
-o-transform-origin:left center;
-ms-transform-origin:left center;
margin-top: -175px;
-webkit-transform:rotate(5deg);
-moz-transform:rotate(5deg);
-o-transform:rotate(5deg);
-ms-transform:rotate(5deg);
z-index: 20;
}
I must point out, I think, that the #skills and #experience are sections and not divs. I am not sure if that might be a problem within the code, but I thought not. If there is anymore information that is needed, please let me know, but I thought I had covered the bases here.
I dont know where to begin with a fiddle, so I supply you just the test link of the site: http://www.jellyfishwebdesign.nl/Joost/index.php
Found the answer actually here on Stack overflow:
The browsers on mobile devices ignore the overflow-x:hidden within the body and html tag if <meta name="viewport"> tag is present, thus i created a wrapper in the body tag covering the rest of my content with a overflow-x: hidden in it, solving the problem.
Documentation:
Overflow-x:hidden doesn't prevent content from overflowing in mobile browsers.
The bad thing is that it prevents the use now of a jquery plugin, that scrolls....
Try setting minimum-scale=1 instead of maximum-scale=1.
minimum-scale controls how far out the user can zoom, while maximum-scale controls how far in they can zoom. To prevent viewing of the overflow you need to limit the user's ability to zoom out, not in.
I had this same problem and tried applying body with overflow-x: hidden;, and lots of other answers, but what did work in my Wordpress, was applying a global CSS rule as below.
body, html {
overflow-x: hidden;
}
This eliminates the movement left to right on mobiles.
The HTML part is needed, not just body!
As pointed out by Dorvalla, body and html tags are ignored by smartphones browsers, although not by "big screen" browsers, I solved the issue by using the first child of the page structure, so no need of an aditional wrapper.
e.g. for my WordPress case:
.site {
overflow-x: hidden;
/* Unnecessary IMHO, uncomment next line to force hidden behavior */
/* overflow-x: hidden !important; */
/* Additional tunning proposed by the community */
position: relative;
width: 100%;
}
Try setting minimum-scale=1 instead of maximum-scale=1 or initial-scale=1.
eg.
<meta name="viewport" content="width=device-width, minimum-scale=1.0">
if you applied overflow-x:hidden to the body, you might wanna apply to html too.
body,html {
overflow-x:hidden;
}
My analysis as of September 2021. Tested on Safari and Firefox 37 (iOS 15).
The accepted answer and its SO link are pretty old (2013-2014) and do not seem valid any more.
Also, I find that adding a "wrapping" div on my body is not really elegant and could lead to unexpected behaviour.
The page on which I am working on is pretty simple, there is just one background image that might overflow on the right of the screen for smaller screens.
Applying minimum-scale=1 to the viewport meta tag did not work. This prevents zooming out, but I could still have this ugly scroll on the right.
Applying overflow-x: hidden; on <html> only did not work.
Applying overflow-x: hidden; on <body> only did not work.
Applying overflow-x: hidden; on both <html> & <body> did work.
This can be resolved without needing to include minimum-scale=1. While that property does prevent the user from zooming and scrolling out, it doesn't resolve the issue of the horizontal scrollbar still appearing, regardless of the fact that the user can't use it.
The way I resolved this issue was by having the following viewport.
<meta name="viewport" content="width=device-width, initial-scale=1">
Next, you need to make sure that your html and body elements have the following properties...
html {
...
overflow-x: hidden;
}
body {
...
position: relative;
overflow-x: hidden;
}
These properties should make it so that any type of horizontal overflow doesn't show, nor will the horizontal scrollbar be present. This also allows you to lock page-scroll in case of a modal or some other reason on both mobile and desktop by simply passing overflow: hidden to the html element.
If you are using tailwind css in next js and you are using a function to display or hide the sidemenu then it will works for you.
const toggleCart = () => {
if (ref.current.classList.contains("hidden")) {
ref.current.classList.remove("hidden");
ref.current.classList.add("translate-x-0");
} else if (!ref.current.classList.contains("hidden")) {
ref.current.classList.add("hidden");
}
};
Set the sidebar or your div initially hidden and will works fine in your phone. Don't use translate-x-full. It will cause the overflow in mobile device in my case
I found that applying:
overflow-x: hidden
to the div wrapper inside the body made the scrolling a little jumpy on iOS Safari so therefore just gave it overflow: hidden and left the body as visible. This worked perfect for me in all browsers and devices I needed.
Even though you are creating a parent container to apply the overflow: hidden; , the overflow property will not work on position: absolute;. Because position absolute moves the targeted element out of context with the document structure.
It has to be position: relative;
Had the same kind of problem with a toggle menu for mobile users, put it off screen so it would appear when the user clicked on the menu bar, solved applying overflow-x:hidden to my section tag.