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">
In this simplified HTML, I have a fixed div that is meant to be the exact width of the window. But there is also a very long word in the content above the div that messes up the layout.
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1">
<style>
div {
position: fixed;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
}
</style>
</head>
<body><p>Veryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongword</p>
<div><b>0%</b><b>25%</b><b>50%</b><b>75%</b><b>100%</b></div>
</body>
</html>
It looks as if the long word causes the "viewport" to stretch to be wider than the window, so the div (fixed to the viewport) ends up being wider than the window.
Now this only happens on mobile devices, even using Chrome Dev Tools. In Desktop mode, all is fine:
But change to Mobile and the fixed div stretches:
So two questions:
How can I prevent the div from stretching wider than the window?
What is Chrome Dev Tools doing differently when I switch to Mobile view?
1) I've managed to fix all the issues I can create with your code by:
p {
max-width: 100vw;
overflow: hidden;
}
2) Chrome does very strange things with the width of that div as I mess with the css and refresh the page. It does not render at all consistently even with the same css. In fact, I have two tabs open that show the page differently from the same code in the same file, even while refreshing. I think the behavior of a div when smaller than the viewport may be unspecified, and you must use something like my solution to tell Chrome what to do.
this problem is caused by justify-content: space-between. You dont actually set a width, and different things add different amounts of spacing.
If you were to set a width for the div like this: width: 300px, the width wouldn't change on mobile or pc.
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>.
The width of my page is too wide, so that you can scroll to the right and it will pass all the page elements. Here's a screenshot:
The black part is the footer, as you can see, you can scroll right past it.
I have used overflow-x: none; to prevent horizontal scolling, however you can still scroll this way by holding down the middle mouse button and scrolling.
How can I confine my pagewidth? Setting it to 100% will make it native to the screen's resolution; however for some reason it has gone past that. Thanks in advance!
If I have understood you right, you should be able to do this in your css:
body {
width: /*the width you want*/;
}
I maybe understood you wrong or maybe I didn't!
Edit:
Try adding this to your <head>:
<meta name="viewport" content="width=device-width, initial-scale=1">
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.