Reputation: 2524
I have actually two issues, but lets resolve the primary issue first as I believe the other is easier to address.
I have a fixed position div on the left side of the scroll for a menu. Right side is a standard div that scrolls properly. The issue is that when the browser view-port is too small to see the entire menu.. there is no way to get it to scroll that I can find (at least not with css). I've tried using different overflows in css, but nothing makes the div scroll. The div that contains the menu is set to min-height:100% and position:fixed.. both attributes I need to keep.
The div containing the menu is inside another wrapper div that is positioned absolutely and height set to 100%.
How can I get it to scroll vertically if the content is too tall for the div?
That leads me to the other issue, that i don't want a scroll bar to display.. but I think I may already have an answer to that (only it doesn't work yet because I can't get the div to scroll to begin with).
Any solutions? Perhaps javascript is needed? (of which i know little about)
and the relevant code that is causing the issue (since posting the whole thing in here is waaay too long):
.fixed-content {
min-height:100%;
position:fixed;
overflow-y:scroll;
overflow-x:hidden;
}
Also tried adding height:100% as well just to see if that was an issue but it didn't work either... nor did a fixed height, such as 600px.
Upvotes: 240
Views: 526213
Reputation: 11
Please refer to section 10.6.4 of https://www.w3.org/TR/2011/REC-CSS2-20110607/visudet.html#Computing_heights_and_margins
For the style
.fixed-content {
min-height:100%;
position:fixed;
overflow-y:scroll;
overflow-x:hidden;
}
Here, all of top, height and bottom have initial values which are "auto" - as all these 3 are non inherited. So, browser would set "top" to the "static position 'top'" which would be 0px in your case as there is no content in the visual order before your fixed content.
Now, it would proceed to the six rules mentioned in the same section. Currently, top is set by the browse to be "static position 'top'", height and bottom are still "auto". So, it would pick rule 3 and assign height as per section 10.6.7 which would be enough to contain all its inflow content and floats which are its immediate children. That is why your fixed content container has almost the same height as its content. So, browser does nt apply a scroll bar for the fixed content container.
But if you directly set top and bottom to 0 as suggested in the accepted answer, browser would pick rule 5 from 10.6.4 and set height to 100% of the containing block which is viewport for fixed position elements - based on the equality
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block
.
So, browser applies a scrollbar now.
Upvotes: 0
Reputation: 1276
Here are both fixes.
First, regarding the fixed sidebar, you need to give it a height for it to overflow:
HTML Code:
<div id="sidebar">Menu</div>
<div id="content">Text</div>
CSS Code:
body {font:76%/150% Arial, Helvetica, sans-serif; color:#666; width:100%; height:100%;}
#sidebar {position:fixed; top:0; left:0; width:20%; height:100%; background:#EEE; overflow:auto;}
#content {width:80%; padding-left:20%;}
@media screen and (max-height:200px){
#sidebar {color:blue; font-size:50%;}
}
Live example: http://jsfiddle.net/RWxGX/3/
It's impossible NOT to get a scroll bar if your content overflows the height of the div. That's why I've added a media query for screen height. Maybe you can adjust your styles for short screen sizes so the scroll doesn't need to appear.
Upvotes: 10
Reputation: 905
Generally speaking, fixed section should be set with width
, height
and top
, bottom
properties, otherwise it won't recognise its size and position.
If the used box is direct child for body and has neighbours, then it makes sense to check z-index
and top, left
properties, since they could overlap each other, which might affect your mouse hover while scrolling the content.
Here is the solution for a content box (a direct child of body
tag) which is commonly used along with mobile navigation.
.fixed-content {
position: fixed;
top: 0;
bottom:0;
width: 100vw; /* viewport width */
height: 100vh; /* viewport height */
overflow-y: scroll;
overflow-x: hidden;
}
Upvotes: 23
Reputation: 609
The solutions here didn't work for me as I'm styling react components.
What worked though for the sidebar was
.sidebar{
position: sticky;
top: 0;
}
Hope this helps someone.
Upvotes: 38
Reputation: 446
Leaving an answer for anyone looking to do something similar but in a horizontal direction, like I wanted to.
Tweaking @strider820's answer like below will do the magic:
.fixed-content { //comments showing what I replaced.
left:0; //top: 0;
right:0; //bottom:0;
position:fixed;
overflow-y:hidden; //overflow-y:scroll;
overflow-x:auto; //overflow-x:hidden;
}
That's it. Also check this comment where @train explained using overflow:auto
over overflow:scroll
.
Upvotes: 1
Reputation: 3720
The problem with using height:100%
is that it will be 100% of the page instead of 100% of the window (as you would probably expect it to be). This will cause the problem that you're seeing, because the non-fixed content is long enough to include the fixed content with 100% height without requiring a scroll bar. The browser doesn't know/care that you can't actually scroll that bar down to see it
You can use fixed
to accomplish what you're trying to do.
.fixed-content {
top: 0;
bottom:0;
position:fixed;
overflow-y:scroll;
overflow-x:hidden;
}
This fork of your fiddle shows my fix: http://jsfiddle.net/strider820/84AsW/1/
Upvotes: 356