Overflow scroll without specifying height? - html

In my app targeting mobile devices (with cordova but that shouldn't matter)
I want to show a scrolling div that fills the page except for a top and bottom navbar:
jsfiddle example
As far as I understand, I need to specify the height of the div in order for the div to scroll. (line 30 in the css - currently commented out):
#long {
background: -webkit-linear-gradient(red, blue);
width: 90%;
/* scroll */
overflow-y: scroll;
/* for the navbar */
margin-top: 48px;
float: left;
/* to make the scroll work */
/*height: 347px;*/
-webkit-overflow-scrolling: touch;
}
I would really prefer if I would have to because using discrete intervals for media queries will always risk some obscurely sized phones to have broader bottom margins than intended.
An additional requirements that might constrain potential solutions:
- The app has several "pages" which are div's that are moved out of the viewport to the left or right when not needed but not removed from the document.
Any ideas how to solve this? Preferably using only CSS.

If the page fit the viewport dimensions, I’d create a wrapper with some padding to position the navbar absolutely and then make an inner container scroll. This will always fit the viewport height and so doesn’t require a fixed height.
html,
body {
height: 100%;
overflow: hidden;
}
.wrapper {
height: 100%;
padding-top: 48px; // Allow space for navbar
}
.inner {
height: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.navbar {
height: 48px;
position: absolute;
top: 0;
right: 0;
left: 0;
}
The HTML would look like:
<div class="wrapper">
<div class="navbar"></div>
<div class="inner"></div>
</div>
Demo

Related

CSS width 100% limited to browser window (it doesn't extend to right scrolling area)

This site is full-width and adapts to the size of the browser window. However, once the browser window is smaller than the content displayed, the title gets cut off once you scroll to the right.
The default width of 100% seems to be working for the width of the browser window only, not the width of the page! The same also seems to apply on the vertical axis.
Example
#title
{
height: 50px;
color: white;
background-color: #404040;
}
#content
{
width: 800px;
background-color: #f0f0f0;
}
<div id="title">
TITLE
</div>
<div id="content">
CONTENT
</div>
Actual result
This is what it looks like when the page is scrolled to the left
(For the sake of simplicity and privacy, content irrelevant to the question is censored.)
After fiddling a lot with positioning, I eventually came up with something.
body
{
position: absolute;
min-width: 100%;
min-height: 100%;
}
#menu-background
{
z-index: -1;
position: absolute;
width: 250px;
height: 100%;
background-color: #404040;
}
and the menu background HTML
<div id="menu-background"></div>
<body> needs absolute positioning, otherwise the table of the content div will overflow out of the content div. Also, it needs a min-width of 100% to cover both cases: Either the window is smaller, or it's larger.
The menu works the same way, except that it is a single <div> that spans the entire page.
This solution works perfectly for both X and Y (menu and title) stretching and background color.
It's clear that width: 100% takes the width of the window, but not the document.
This behavior is not entirely clear in the spec as far as I can tell.
10.2 Content width: the width
property
<percentage>
Specifies a percentage width. The percentage is calculated with
respect to the width of the generated box's containing block. If the
containing block's width depends on this element's width, then the
resulting layout is undefined in CSS 2.1.
Two methods around the problem involve CSS positioning.
1. position: fixed
Fixed positioning makes the width relative to the viewport.
#title {
height: 50px;
color: white;
background-color: #404040;
position: fixed; /* NEW */
width: 100%; /* NEW */
}
DEMO
2. position: absolute
Absolute positioning also works:
#title {
height: 50px;
color: white;
background-color: #404040;
position: absolute;
width: 100%;
}
DEMO
For me it worked with this two little friends:
width: auto;
min-width: 100%;
No positon: fixed/absolute needed

How can I scale a list to the device height in landscape and not to the list content height

I have two Elements horizontally aligned, and the left one is a list. If I add some items so that the list should start scrolling, the list just grows larger then my device height is and my second content on the right side scrolls away if I scroll the list downwards. So the list is more then 100% in height... Here is some code for you :
http://codepen.io/anon/pen/qhylB
As I have created this code I just noticed that my both divs don't scale to 100% of the device width. Could you explain me why?
It's because the scrollbar is on the body (or html for firefox I think). Instead you need to have the body's height fix to 100% and then move the scrollbar to the list container (33percent div):
http://codepen.io/jonigiuro/pen/JEkLH
html, body {
margin: 0px;
padding: 0px;
height: 100%;
max-height: 100%;
overflow: hidden;
}
.content33percent {
height: 100%;
max-height: 100%;
overflow: scroll;
}
i changed your 66% to a fixed position, now when you scroll down it looks like you are scrolling the list when you are actually scrolling the whole document, this way you can apply the scrolling over the complete document:
http://codepen.io/anon/pen/KLzvo
.content66percent {
background-color: blue;
height: 100%;
width: 66%;
position: fixed;
right: 5px;
also, i have removed the floating from both the 66%er and the 33%er and adjusted them a little. if you want them to touch each other, change 66% to 66.53%.

How to make Bootstrap sticky footer content go full page height?

I'm using a Boostrap sample to create a sticky footer for a web site using CSS, this all works fine the footer remains in place at the bottom of the page as the page is resized.
On a number of pages I have content that needs to be shown practically full page, barring the footer. The content section of the page therefore needs to be set to 100% height so its content in turn can be sized to full height.
Here's a JSFiddle that demonstrates the problem.
How can we make the green container div full height, so it touches the page top at the top and the top of the footer at the bottom?
Thanks!
<div id="wrap">
<!-- Begin page content -->
<div class="container">
<div class="page-header">
<h1>Sticky footer</h1>
</div>
<p class="lead">This is the sticky footer template taken from the Bootstrap web site.</p>
<p class="lead">How can we make this green .container div the full height of its parent #wrap div?</p>
</div>
<div id="push"></div>
</div>
<div id="footer">
<div class="container"></div>
</div>
#wrap .container {
background-color: lightgreen;
}
/* Sticky footer styles */
html, body {
height: 100%;
/* The html and body elements cannot have any padding or margin. */
}
/* Wrapper for page content to push down footer */
#wrap {
min-height: 100%;
height: auto !important;
height: 100%;
/* Negative indent footer by it's height */
margin: 0 auto -60px;
}
/* Set the fixed height of the footer here */
#push, #footer {
height: 60px;
}
#footer {
background-color: #f5f5f5;
}
I have the solution to your problem. I moved it from JSFiddle to codepen, because I like codepen better. No other reason.
http://cdpn.io/IJHxf
This is essentially where I got the answer from, and they explain it way better than I ever could.
http://v1.reinspire.net/blog/2005/10/11/css_vertical_stretch/
When you implement that answer though, what I found height: auto !important; is the culprit as to why it doesn't immediately work. Comment it out in your #wrap id to see it take full effect. The code pen has additional changes to really see what is going on. What you really need to make your original question work is
#wrap .container {
background-color: lightgreen;
min-height: 100%;
height: auto; /* this line takes care of "more than enough content problem" */
}
html, body {
height: 100%;
background-color: #dedede;
padding: 0;
margin: 0;
}
#wrap {
min-height: 100%;
/* height: auto !important; */
height: 100%;
margin: 0 auto -60px;
}
Actually, what you could do, and would make more sense is instead of commenting out the entire line height: auto !important; You could just take off the !imporant. For example
#wrap {
height: auto !important;
/* changed to */
height: auto;
}
I changed some colors around to make it more apparent what was really happening. You'll see that in the codepen. There are lots more comments in the code pen to see what I really did FYI.
Also, I found that your sticky footer gave my page a scroll bar because of the margin. For me, I got rid of the scroll bar with the code below.
margin: 0 auto -60px;
/* changed to */
margin: 0 auto -80px;

Website layout advice

I'm working on a website that fits perfectly in the browser window. Below is a basic blueprint of the website layout:
So far, the Red area is just display:block. The Green area is also display:block with margin-right:200px. The Blue areas(nested in a div) is float:right.
So I've got the width sorted. It's the height I need advice on. The Red and Dark Blue areas are a set height, but I need the Green and Light Blue areas to fit the height of the browser window view.
I'm trying to use box-sizing, but it exceeds the height of the window view because it's extending to the max height of the window. Sorry for my poor explanation. Any advice if would be excellent. Thank you!
For green div set height: calc(100%-{red-div-height}); and for the light blue div set height: calc(100%-{dark-blue-div-height}-{red-div-height});
This is kinda the legacy version of C-Link's answer.
jsFiddle and fullscreen
This has the limitation of any content falling below one page-full falling outside of its container (you can see if you scroll down in the fiddle, but not on the fullscreen).
Make sure our page stretches to its full height.
body, html { height: 100%; width: 100%; margin: 0; padding: 0;}
Set a static-height header.
header {
height: 101px;
background: red;
}
Create a box for everything under the header. You were on the right track with the box-sizing. We can add padding to it, in the same amount as our header. Then percentages inside it work nicely.
.content {
position: absolute;
box-sizing: border-box;
padding-top: 111px;
padding-bottom: 10px;
top: 0; left: 0;
height: 100%; width: 100%;
}
We float our aside (may or may not be the correct element, depending on contents) and set some styles on it.
aside {
float: right;
width: 20%;
height: 100%;
padding-bottom: 111px;
box-sizing: border-box;
}
.top {
height: 100px;
background: blue;
}
.bottom {
margin-top: 10px;
height: 100%;
background: skyblue;
}
This is our main, large, content area, which we float to the left. The width could be specified exactly if we wanted exact padding at the cost of additional HTML.
[role="main"] {
width: 78%;
background: limegreen;
height: 100%;
float: left;
box-sizing: border-box;
}
You can also set overflow-y: auto on our main or aside elements, to have them scroll when they run out of space. There should also be mobile styles for this page that remove the floating, absolute positioning, absolute styling, and widths should be nearly 100%.
you can always set the green box height to the window height minus the red box height.
accordingly the light box height to the window height minus the (red box height + the dark blue box height)
Edit 1: I haven't mentioned that has to be done with javascript.
Edit 2: Consider any paddings and margins too.
Could you not just give the divs a max or min height depending on their purpose?
I use a main container or wrapper div that the others would be contained in, that div is then my effective page or screen area.
<div id="wrapper">
<div id="content">
<div id="sidebar">
</div>
</div>
</div>
#wrapper{
min-height: Whatever value you want here;
max-height: Whatever value you want here;
}
It might be a good idea to set up your page using main container divs, hot only for the content but for the header and footer as well.
As an example, I have a main wrapper that is the whole page, within that is the header div, the content div, the nav div and the footer div. These are the main ones. Everything else can then be contained within them.
So, you can set the layout out using percentages so you have a fluid design that'll react to each browser size. The other elements will then 'fit' inside the main divs and be constrained to them. You may need to look into positioning etc but this is certainly the direction you should head towards.
<div id="wrapper">
<div id="header">Header Here including any divs to be contained within this space</div>
<div id="content">All content etc here</div>
<div id="nav">This is your sidebar</div>
<div id="footer">Footer, as per header</div>
</div>
Then use the css to re deisgn the above layout focusing only on those main divs. Use % instead of px to maintain fluidity.
#wrapper{
width: 100%;
height: 100%
}
#header{
width: 100%;
height: 20%
}
#content{
width: 70%;
height: 60%;
float:left;
}
#nav{
width: 30%;
height: 60%;
float:left;
}
#footer{
width: 100%;
height: 20%
}
A pretty common trick is to give the green (and light blue) box absolute positioning, a padding AND a negative margin. Because 100% width is relative to the containing box (could be a parent div, or just the window itself) this is not suitable. When the header was a relative height, say 10%, it would've been easy. The padding makes sure the content will not disappear behind the header, the negative margin puts the box back in place. Don't forget the z-index (otherwise the content (green part) will overlap the header).
The css looks like this:
.header { position: absolute; width: 100%; height: 100px; background: red; z-index: 1; }
.content { position: absolute; width: 100%; height: 100%; padding: 100px 0 0; margin-top: -100px; background: green; z-index: 0; }
The fiddle looks like this: http://jsfiddle.net/2L7VU/

Trying to make large background image remain centered with an auto margin centered content div, but bg image should not affect layout

i want a background image that is larger than the content, which will remain centered with the content, but will not affect the layout (meaning no scrollbars to accomodate the background image). the content must be centered using margin: auto; so that the left side will remain flush with the left side of the viewpane, when the viewpane becomes smaller than the content.
I have seen this question asked several times, and have tried quite a few solutions, but none of the accepted answers have actually worked.
Edit to Clarify
This question is still a bit murkey, so I will attempt to clarify with some images showing what I need. In these images, green is the background image, red is the main content, and blue is the browser's viewpane.
A: When the viewpane is smaller than both the background image and the main content, the left side of the content remains flush with the left side of the viewpane, the background image remains centered to the main content, the viewpanes scrollbars will only scroll out to the right edge of the main content (and not to the right edge of the background).
B: When the viewpane is larger than both the background image and content, both remain centered to the viewpane.
C: When the viewpane is the same size as the main content, the background image should remain centered to the main content, no scrollbars should be present.
Updated Answer: I still have spent way too much time on this :-), especially when it ended up so simple. It allows for a background to be sized based on the height of the container, which seems to be different than yunzen's solution. Now does use margin: 0 auto;. Still grows with container height.
View the new answer.
You can view the original, more complex answer which does not use auto margin.
HTML:
<div id="Bkg">
<div id="Content">Content goes here. </div>
</div>
CSS:
#Bkg {
width: 100%;
min-width: 300px; /* equals width of content */
background:url('http://dummyimage.com/400x20/ffff00/000000&text=Center') repeat-y top center;
padding-bottom: 50px;
}
#Content {
width: 300px;
margin: 0 auto;
}
I guess this is what you want
HTML
<div id="content">
content<br/><br /><br/>
content<br/>
</div>
<div id="background"><div></div></div>
CSS
html, body {
height: 100%;
}
#background {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
/* this is the height of the bg image */
min-height: 600px;
z-index: -1;
}
#background > div {
margin: 0 auto;
background: url("http://lorempixel.com/800/600/sports/2") no-repeat 50% top gray;
width: 100%;
height: 100%;
/* this is the height of the content */
min-width: 500px;
/* this is the width of the bg image */
max-width: 800px;
/* this is the height of the bg image */
max-height: 600px;
z-index: -1;
}
#content {
/* these are just some numbers */
width: 500px;
height: 400px;
border: 1px solid gold;
margin: 0 auto;
background: rgba(255,255,255,0.2);
}
Well, if it expands past the browser's window size, it's going to create a scrollbar for the entire window. I wasn't sure exactly what scrollbar you're trying to prevent.
max-width tells it "under no circumstances should this box be bigger than this width." So a box bigger than that will simply expand past the parent's boundaries.
See the jsFiddle.
If I'm understanding the question right, I believe this is what you're wanting.
.main-container
{
height: 1005px;
left: 50%;
margin-left: -560px;
position: relative;
width: 1120px;
}
To hide the scrollbars, you can add
overflow: hidden;
For horizontal only:
overflow-x: hidden;
Try this then:
<div id="wrapper" style="position:relative;margin:auto;width:200px;height:200px;">
<div id="image" style="position:absolute;top:0px;left:-100px;width:400px;height:400px;background-image:url(your_bgimage);background-repeat:no-repeat;background-position:top center;">
<div id="content" style="position:absolute;top:0px;left:100px;width:200px;height:200px;"><p>
<p>/* YOUR CONTENT */</P>
</div></div></div>
For some reason I couldn't get the z-index work, but if you can, you can put your content in the wrapper too, and content is not needed.
Given your original diagram I assumed that the background image was intended to be that - an image, possibly hi-res, rather than a repeated pattern. You may want to play with css3 background-size property which is handy for this specific purpose. It is well supported by modern browsers and regresses reasonably well if you have to support IE8 and under.
body {
background-image:url(/*nice higher res picture*/);
background-size:cover;
background-repeat:no-repeat;
}
http://jsfiddle.net/YyzAX/