EDIT/UPDATE: 7th June 2019
I've determined this is a bug in Safari, as the CSS works perfectly in all other browser. For anyone who finds this, if you're creating a sliding menu (which slides offscreen to the right of the viewport), as of Safari 12.1.1, adding overflow-x to the body tag will not work (it does work on Chrome, Firefox etc) - this means that when your menu div is positioned offscreen to the right, the user can scroll horizontally and see the menu.
I've found a (sort of) workaround is to give the parent container of the menu dive a position:fixed attribute - this obviously only works if you intend for your header to be fixed.
Original Question
I'm building a simple header with a menu that slides from right to left when the menu button is pressed. However, when I position the menu div offscreen (left: 100%), on Safari, I can scroll horizontally right to see the menu div. (No scroll bars appear, but I can scroll right via the Mouse)
If I set overflow-x:hidden on the header, then it hides the offscreen div, but also won't show it if you set the left:0 (ie. overflow-x seems to be hiding x and y directions).
Even more perplexing, if I change the header to position:fixed, then it works and you can't scroll right to see the offscreen menu div.
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.header {
width: 100%;
padding: 10px;
background: #CCC;
position: relative;
}
.slideMenu {
position: absolute;
top: 100%;
left: 100%;
width: 100%;
padding: 10px;
background: #666;
}
<div class="header">
Header ---> Scroll to Right
<div class="slideMenu">
Menu is visible offscreen- :(
</div>
</div>
Here's an example of the problem: https://jsfiddle.net/ar7qyfgt/
I ran into a similar issue with Safari. Solution that appears to be working is to apply overflow-x: hidden; to the html AND body tags.
Adding to body resolved issue in all browsers expect Safari. Applying it to both seems to do the trick with Safari while still supporting the other browsers.
I have the same issue in my Safari(Version 12.1.1) when I set my div to position: absolute and right: -15rem;
To fix it, I added a to include all elements within and have the CSS like this:
.wrapper {
position: relative;
overflow-x: hidden;
}
Hope this help.
What you currently have works, you just need to set overflow-x:hidden on the body instead of the .header
What are you trying to accomplish? This?:
JSFiddle: (https://jsfiddle.net/pzeqfb51/)
HTML:
<div class="header">
Header ---> Scroll to Right
<div class="slideMenu">
Menu is visible offscreen- :(
</div>
</div>
CSS:
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.header {
width: 100%;
padding: 10px;
background: #CCC;
position: relative;
}
.slideMenu {
position: absolute;
top: 100%;
left: 100%;
width: 100%;
padding: 10px;
background: #666;
}
div {
display:inline-block;
}
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>
Let me first try to illustrate the problem
I have a webpage which contains a header and a sidenav. The sidenav is fixed in css, since I don't its content to move when scrolling.
When the page isn't scrolled down it works as intended, somewhat like this
However when I scroll i don't want whitespace on top of the sidenav. Currently when I scroll down the page, it looks somewhat like this
The intended behavior should be something like this
How do I go about this in css? Do I mess with the z-index of the elements? so the sidenav is behind the header when the page isn't scrolled? Or do I dynamically add to the sidenav's size when scrolling?
And how would either of these options be done in css?
As I understand, you have to set z-index of the header higher than the sidenav
Stack Snippet
.header {
height: 100px;
background: #000000;
position: relative;
z-index:999;
}
body {
margin: 0;
}
.sidebar {
position: fixed;
left: 0;
top: 0px;
width: 100px;
background: red;
height: 100%;
padding-top:100px;
}
.content {
height: 1000px;
background: yellow;
}
<div class="header"></div>
<div class="main">
<div class="sidebar"></div>
<div class="content"></div>
</div>
I could use some help solving this css problem. Basically, I have 3 sections.
div class="app-container">
<div class="menu">
</div>
<div class="content">
</div>
</div
The menu div, should contain my menu. It should be displayed on the left side with a fixed width. The height should also be 100%.
The content div, should use what's rest of the width available.
This is how my site looks like now.
The problem happens when there it more content to the right, and you have to scroll down to view it. When this happens, my menu does not follow along.
This is how it looks when there are way more content. (you can see to the right that I have scrolled down)
Code
html, body {
}
.app-container {
}
.menu {
height: 100%;
width: 16rem;
top: 0;
left: 0;
background-color: #2D3E50;
color: white;
padding: 1rem;
position: absolute;
}
.content {
padding: 1rem;
padding-left: 17rem;
background-color: white;
height: 100%;
}
As you can see, I have made a padding-left on the content, and filled in the menu in the absolute position.
What should I do so the menu keeps continuing no matter how far you scroll down?
Update
Try using position: relative; to body and position: absolute; to your menu element. Set height of the menu to 100%.
I have the following layout:
On the left side I have a menu and big gray part on the right side is the body content. The problem is on the left menu I have a bunch of buttons. I want this menu to be fixed position and body scrollable. I Have the following css:
#menu {
position: fixed;
}
#content {
position: inherit;
margin-left:300px;
}
The problem is that on the red part of my menu all button unavailable, I can't click on it. looks like body overrides the menu.
Any ideas what the problem might be?
Thanks
Including the html would give a better sense of the stacking order and likely yield a better answer. Given what you've provided, this should fix:
#menu {
position: fixed;
z-index: 1;
}
In order to fix it to the top and not scroll, you don't use position: fixed;. You need to use position: absolute;. If you don't want it at the very top, then you use position: relative; and place it inside an element.
Then, in order to scroll, you use position: fixed;.
When you use position: fixed, it places the element fixed within the visible page.
However, when you use position: absolute, what this does is put it on an absolute position on the page regardless of scroll. For example, if you added the css top:0; then it would be 0 pixes from the absolute top of page, and if you scroll down it will disappear from view because it is all the way at the top of the actual page, not just the top of the visible page.
I understand it seems a bit counter-intuitive to you. However, you can see it working in the jsbin below.
Working jsbin:
http://jsbin.com/Uwuyuha/1
page.html
<body>
<div id="container">
<div id="menu">
1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>
</div>
<div id="content">
</div>
</div>
</body>
style.css
body {
width: 100%;
height: 100%;
}
#container {
width: 1000px;
height: 1000px;
}
#menu {
width: 250px;
height: 2000px;
position: fixed;
background: #999;
}
#content {
width: 650px;
height: 300px;
position: absolute;
margin-left: 251px;
background: #444;
}
I am experiencing some strange behaviour when attempting the following (see jsfiddle: http://jsfiddle.net/9nS47/).
HTML:
<div id="slider">
<div id="wrapper">
<div id="navigation"></div>
<div id="container">
<div id="button"></div>
</div>
</div>
</div>
CSS:
HTML,BODY
{ width:100%; height:100%; }
* { margin: 0; padding: 0; }
#slider
{
position: fixed;
top: 0;
bottom: 0px;
left: 100px;
overflow-y: auto;
background-color: red;
}
#wrapper
{
position: relative;
height: 100%;
background-color: #000000;
min-height:400px;
}
#navigation
{
display: inline-block;
width: 80px;
height: 100%;
background-color: #0000FF;
}
#container
{
display: inline-block;
height: 100%;
background-color: #00FF00;
}
#button
{
width: 22px; height: 100%;
float:right;
background-color: #CCFFCC;
cursor:pointer;
}
What I am trying to do is making a left side navigation bar that spans the whole visible window height and only Shows a scrollbar if its height is smaller than for example 400px. The scrollbar for that div seems to be always visible due to some resizing problems (there is an extra pixel at the bottom I can't explain[color:red]).
Firefox also moves the second child element below the first when the scrollbar is visible because the scrollbar seems to be part of the content area and thus takes up to around 20px space. This does not happen if Overflow: Auto is replaced with Overflow: scroll however.
ATM changing the layout (specifically the Container with Position: fixed) is not an option.
Don't mind the space between the green and the blue box. Seems to be a whitespace problem.
Since it seems like you are unable to change your 'wrapper' code much, I tried to change your original code as little as possible. In fact, the only thing I did was to add some jQuery.
Check out this updated jsfiddle. I have included jQuery and the javascript I added was this:
$(window).bind("load resize", function(){
//this runs as soon as the page is 'ready'
if($(window).height() < 400){
$("#slider").css("overflow-y","scroll");
}else{
$("#slider").css("overflow-y","hidden");
}
});
Basically, 'onload' and 'onrezise', the jQuery figures out if you should show the scrollbars or not.
The reason that your "auto" isn't working is because of the "fixed" position of the slider element. The browser cannot perfectly figure out the heights.