I have a div which needs to fill out the height of the browser's viewport,but still says in the same position when the user scrolls the web page up and down. position: fixed; does this, but I am unable to use it as it's making the overflow scroll bar of the div jerky and slow. Is there an position or method that I can use so for example I currently have:
div.panel {
position: absolute;
top: 36px;
right: 0;
overflow: auto;
background: #636362;
padding: 0 0 20px 0px;
width: 290px;
height: 100%;
}
I'm not sure what you mean with "jerky and slow", because all scrollbars act the same. This is how I would resolve your issue:
HTML:
<div class="fixed">I'm fixed!</div>
<p>Rest of page</p>
CSS:
html, body {
/* make sure the page is at least height of viewport */
height: 100%;
}
body {
/* because the fixed div is no part of the flow,
make sure it is not overlapping the webpage */
padding: 0 0 0 100px;
}
.fixed {
height: 100%;
width: 100px;
left: 0;
position: fixed;
background: #e0e0e0;
/* only vertical-scrolling, but can be changed of course */
overflow-y: scroll;
}
JSfiddled Live example
Works in at least IE7, IE8 and Firefox.
Related
I have an image that could be smaller than the user's browser, or larger, vertically centered in a div. I'd like a CSS-only solution, but based on the amount of research I've done I am beginning to be skeptical.
More precisely: if the image is smaller (height-wise) than the browser's height, it should be vertically centered -- if the image is taller than the browser's height, there should be a scroll bar to see the rest of the image. This works perfectly in Firefox, but not in Chrome -- and I cannot figure out why.
On Chrome, the image is vertically shifted above the scrollbar so it is still being centered, even though it is too tall. Any ideas? Minimum browser requirements is IE9+, Firefox, Chrome, and Safari (all latest versions of those).
/* This element just fills the entire browser window */
.container {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1000;
}
/* This has a little bit of horizontal spacing, but is centered and takes up the full height of the screen. */
.item {
position: absolute;
min-height: 100%;
top: 0;
left: 0;
overflow-y: auto;
text-align: center;
width: calc(100% - 200px);
margin: 0 100px;
}
.item img {
max-width: 100%;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
<div class="container">
<div class="item">
<img src="dummy.jpg">
</div>
</div>
So, I've got something working -- but it still has one problem (reduced a bigger problem to a smaller one).
/* This element just fills the entire browser window */
.container {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1000;
}
/* This has a little bit of horizontal spacing, but is centered and takes up the full height of the screen. */
.item {
position: absolute;
height: 100%;
top: 0;
left: 0;
overflow-y: auto;
text-align: center;
width: calc(100% - 200px);
margin: 0 100px;
}
.item-box{
background-image: url(dummy.jpg);
background-position: center;
background-size: 100% auto;
background-repeat: no-repeat;
width: 100%;
min-height: 100%;
}
.item img {
max-width: 100%;
opacity: 0 !important;
max-width: 100%;
}
<div class="container">
<div class="item">
<div class="item-box">
<img src="dummy.jpg">
</div>
</div>
</div>
This works as the original problem was posed, in that now if the image is smaller, the box will be centered, but if the image is too tall there will be a scrollbar. No cutoff in non-firefox browsers. The new issue is that the image is not entirely selectable, because the invisible image is fixed to the top instead of centered (the original problem), so you can't "right-click to download image" or any of the stuff that the entire point of using an img tag, was meant for.
Any further ideas on how to use this solution?
This should be easy and has been answered 100 times, but for some reason it's not working in my code.
I want to have my footer always be at the bottom of the page, but for cases when the content doesn't fill up the full page, it should still sit at the bottom (eg: not always fixed at bottom:0)
HTML
<div class="home-wrapper">
<div ui-view="nav#home"></div>
<div ui-view="content#{{$state.current.name}}" class="content-div"></div>
<div ui-view="footer#home" class="footer-bar"></div>
</div>
CSS
html
{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow-x: hidden;
}
body {
width: 100%;
min-height: 100%;
overflow-x: hidden;
margin: 0;
padding: 0;
}
.home-wrapper {
min-height: 100%;
position: relative;
}
.footer-bar {
height: 3em;
width: 100%;
overflow:hidden;
position: absolute;
bottom: 0;
left: 0;
}
I thought by setting the min-height on the home-wrapper we'd have no issues... it works fine when the content area is large, but on elsewise it's shoved right up at the top of the page! I suspect this might be related to the fact that I'm using AngularJS with UI-Router for state routing, and my CSS is loaded on a per-page basis.
You can see a live example up at: http://letsdolunch-web-dev.azurewebsites.net/, click the Legal link at the bottom to see the issue present itself, http://letsdolunch-web-dev.azurewebsites.net/#/legal
Assume, that I have three boxes (divs) on website (see image below):
header with logo
content with some text
footer with contact info
Each box have unique color (in order: yellow, orange and blue) and black border.
I would like to website always fills the entire screen, the logo was on the top and the footer was at the bottom. So if there is not enough text in content, content should be extended, so that the footer was on the bottom. And if will be a lot of text in content, slider should appear on the right.
How do this in CSS? Important is that boxes have backgrounds. I found many solutions, but none doesn't work properly with backgrounds.
Solution Explained
The black box in your diagram gets min-height 100%, is the scrolling container, and is position relative, to allow child positions to be respective to it.
The red box in your diagram is actually composed of 2 boxes:
one for your dynamically-sized content; this has sufficient top and bottom padding to make room for your header and footer, and force the scrolling container to expand
one for the background; this is position absolute, with top and bottom position specified relative to the black box, its parent.
The yellow and blue boxes in your diagram can be position: absolute, top: 0 and bottom: 0, respectively... or however you choose to position them.
Here's a fiddle of it: http://jsfiddle.net/syndicatedshannon/F5c6T/
And here is another version with explicit viewport elements just to clarify, matching colors, and borders added to replicate the OP graphics (although per the OP the black border is actually the window).
Sample HTML
<html>
<body>
<div class="background"></div>
<div class="content"></div>
<div class="header"></div>
<div class="footer"></div>
</body>
</html>
Sample CSS
html { position: absolute; height: 100%; left: 10px; right: 10px; overflow: auto; margin: 0; padding: 0; }
body { position: relative; width: 100%; min-height: 100%; margin: 0; padding: 0; }
.background { position: absolute; top: 120px; bottom: 120px; background-color: red; width: 100%; }
.content { position: relative; padding: 120px 0; }
.header { position: absolute; top: 10px; height: 100px; width: 100%; background-color: yellow; }
.footer { position: absolute; bottom: 10px; height: 100px; width: 100%; background-color: cyan; }
Also note that this assumes you cannot rely on CSS3 yet.
If you're only targeting modern browsers, you can use calc()
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
}
.footer {
height: 100px;
margin-top: 20px;
}
.content {
min-height: calc(100% - 50px - 10px - 100px - 20px);
}
The drawback is that you need to know the header and footer sizes and they need to be fixed. I don't know any way around this without using Javascript. For slightly less modern browsers, you can use border-box to get the same effect as above.
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
z-index: 5;
position: relative;
}
.footer {
height: 100px;
margin-top: -100px;
z-index: 5;
position: relative;
}
.content {
box-sizing: border-box;
padding: 60px 0 120px 0;
margin-top: -60px;
min-height: 100%;
z-index: 1;
position: relative;
}
Lastly, here is the JS solution:
$(function(){
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight() - $('.content').marginTop()
- $('.content').marginBottom());
});
EDIT: My JS solution assumed border-box and no border. This solution should be more robust:
function setContentSize() {
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight()
- ($('.content').outerHeight()
- $('.content').innerHeight()));
}
$(setContentSize);
$(window).on('resize', setContentSize);
If you look at this fiddle: http://jsfiddle.net/bastien/PybrF/1/
#header {
position: fixed;
top: 0px;
left: 0px;
height: 50px;
width: 100%;
background-color: yellow;
}
#content {
top: 51px;
left: 0px;
bottom: 0px;
width: 100%;
height: 100%;
position: fixed;
overflow: auto;
background-color: orange;
}
If you resize the window then the vertical scrollbar gets visible in the content div. BUT it gets only visible (so it seems for me...) when I have exceeded the height in pixel of the header while resizing the window.
How can I get the vertical scrollbar correctly?
UPDATE
I want a header which stays fixed.
I want a content which has inside scrollbars.
something like this: http://jsfiddle.net/bastien/PybrF/7/
but the vertical scrollbars should start inside the content div and not start at the header/body.
Try this in your css:
* { margin: 0; padding: 0 }
#header, #content { width: 100%; position: absolute; }
#header {
height: 50px;
background-color: yellow;
}
#content {
top: 50px;
height: 70%;
overflow-y: auto;
background-color: orange;
}
Will produce this:
As for the height of the content to use all the space left, I would to a js function wired to the resize event to set the height of the content to the page height minus the height of the header. I honestly don't know another solution for this.
Due to your use of fixed positioning and application of overflow settings, only the #content area will scroll.
Consider this:
1) Add the orange background color to the body element and remove its margins:
body {
margin:0px;
padding:0px;
background-color: orange;
overflow-x: hidden;
overflow-y: auto;
}
2) Position the other elements relatively:
#header {
position: relative;
height: 50px;
background-color: yellow;
}
#container {
position:relative;
}
http://jsfiddle.net/PybrF/6/
EDIT:
I'm still unclear on what you're looking for, but here's another method.
This one keeps the header fixed and puts the scrollbar inside the #content area.
body {
background-color: orange;
margin:0px;
}
#header {
position: fixed;
top: 0px;
left: 0px;
height: 50px;
width: 100%;
background-color: yellow;
z-index:1; /* keep the header on top of the content */
}
#content {
position:relative;
padding-top:50px; /* height of the header */
}
http://jsfiddle.net/PybrF/8/
ok I knew it must work:
Still found some old similar code and refactored it:
have fun! :)
Sorry for telling crap.
Remove the width/height percentage settings and use the left/right/bottom etc settings. Thats enough.
Forget about the main div which was from this other project long ago.
http://jsfiddle.net/bastien/PybrF/12/
I've created a banner for my website that's made up of 3 iPhone images side-by-side, using background images and relative positioning for each. However, I'm having issues with the horizontal scrolling. That is even though the div's containing each iphone image extend beyond the width of the parent .content div, I don't want there to be a scrollbar when the overflow content isn't able to fit the browser width. Scrollbars should only be shown if the browser width is below 960px.
A similar effect is presently seen on Apple's homepage, where the hand/wrist reside "outside" the website's container, but no horizontal scrollbars are visible unless the browser's width is below 990px wide.
I hope I've explained this clearly, please let me know if it's not clear.
Here's the code I'm using:
<div class="content">
<div id="iphone-a"></div>
<div id="iphone-b"></div>
<div id="iphone-c"></div>
</div>
.content {
margin: 0 auto;
width: 960px;
height: auto;
text-align: left;
overflow-x: visible;
}
#iphone-a {
z-index: 1;
position: relative;
left: 50%;
bottom: 0;
margin-left: -306px;
height: 657px;
width: 590px;
background: url(images/banner.png) 0px 0px;
}
#iphone-b {
z-index: 0;
position: relative;
top: -545px;
left: 50%;
margin-left: -732px;
height: 319px;
width: 590px;
background: url(images/banner.png) 0px -658px;
}
#iphone-c {
z-index: 0;
position: relative;
top: -864px;
left: 50%;
margin-left: 144px;
height: 319px;
width: 590px;
background: url(images/banner.png) 0px -658px;
}
change
overflow-x: visible;
in .content to
overflow-x : hidden;
Edit : If that's not what u mean, and u just want visible to work correctly try using overflow instead of overflow-x