Overflow scroll on y axis with fixed height - javascript

I have an apparently easy problem which is:
<div class="container">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>​
I have 3 divs inside a container: A and B have fixed heights. C must have an extendable height, it extends along with the container height. If the content inside C are too big, I'd like C to scroll but to keep A and B in the same place.
Code in: http://jsfiddle.net/V2c9G/
I'm not able to do it.
I tried:
<div class="container">
<div class="a"></div>
<div class="b"></div>
<div class="xxx" style="overflow-y:scroll">
<div class="c"></div>
</div>
</div>​
without success. The container div it's supposed to resize along the browser.
A complex example would be http://www.sencha.com/examples/#overview (I'm talking about the layout, make the browser smaller and you will see scrolls apperaring hile the headers keeps fixed) but it's not a solution since it uses JS to recalculate the heights.
Any idea?

Edit 3:
This is my recommended solution, which uses CSS from the Edit 2 below as a fallback, but uses JavaScript to resize your divs appropriately onload and when your window size changes. The CSS solution provides a decent starting point if the client has JavaScript disabled, and the JavaScript is such that it really shouldn't affect the performance of the page, so I see no reason not to use JavaScript to perfect what you want to see. A working fiddle can be seen here. Also, here is the appropriate JavaScript code:
var resizeDiv = function(){
document.getElementById('c').style.height = getWindowHeight() - 64 + 'px';
};
//Framework code
var getWindowHeight = function(){
if (window.innerHeight) {
return window.innerHeight;
}
if (document.body && document.body.offsetHeight) {
return document.body.offsetHeight;
}
if (document.compatMode=='CSS1Compat' &&
document.documentElement &&
document.documentElement.offsetHeight ) {
return document.documentElement.offsetHeight;
}
return 740;//provide a default height as a fallback
};
//resize on pageload
window.onresize = resizeDiv;
setTimeout(resizeDiv);
I think you need to adjust the absolute height on your third div to take up the rest of the space (either absolutely or with percentages), set overflow to hidden on the parent div, and let the content in the third inner div determine whether to show the scrollbar or not. Here's an updated fiddle using the absolute height method.
Edit:
From your "Imagine the container is the browser" comment (which to me means the scrollbar should be on the container), all you'd really have to do is set the overflow to 'scroll' and height in the third div to 'auto'. Here's an updated fiddle for that.
Edit #2:
According to your comment on this question, it sounds like you need to go with the percentage method. The most straightforward would be to make the height of a, b, and c a percentage (I had to tweak the margins to get it to fit for all zooms). Unfortunately with this method, the top components will not be fixed, and it sounds like you may be displaying static content there that would look funky. Thus, another option is to pick a minimum supported size for your browser window and adjust the percentage of the third element so that it just fits. Here's a fiddle for that. However, the downside there is that you'll have more empty space at the bottom of the page the bigger the height of the window, and you'll have 2 scrollbars below a certain height. To really do this properly with the fixed sized divs at the top, you'll need to add an event listener to the window.resize method and resize your third div when that happens appropriately based on the new size of the window.
Note: It is times like this where I wish the W3C would approve percentages plus pixels for their height, width, and other sizing properties!

I think you might be searching for something like this: http://jsfiddle.net/QsLFt/.
However, I'm not sure how to get rid of the divs hiding the scrollbar, the easiest solution would probably be to set it a fixed width?

You need to apply overflow-y:scroll in .container
See this,
http://jsfiddle.net/v4ZtN/
Edit (after comments):
Css:
.container{
background-color: red;
width: 90%;
margin: 0 auto;
height:220px;
}
.a{
background-color: yellow;
height: 30px;
margin: 2px;
}
.b{
background-color: blue;
height: 30px;
margin: 2px;
}
.c{
background-color: green;
overflow-y: scroll;
height:inherit;
}
Html:
<div class="container">
<div class="a"></div>
<div class="b"></div>
<div class="c"><img src="http://www.boingboing.net/images/_documents_anemone_images_anemone850-1.jpg" alt=""/></div>
</div>
Edit:2 (after comments)
Change .c style with this.
.c{
background-color: green;
overflow-y: scroll;
height:100%;
}
Check this fiddle:
http://jsfiddle.net/XM4gH/6/

div only show scroll when you put some data in it, here is the result;
jsfiddle

Based on what's currently up on your jsFiddle, I think you can simply add this to the style declarations for your .container class:
overflow:hidden;
You'll have to actually add content to the .c div to see any scrolling however.

did this anser is match to your request ? enter link description here
.container{
background-color: red;
width: 90%;
margin: 0 auto;
height: 315px;
}
.a{
background-color: yellow;
height: 30px;
margin: 2px;
width: 90%;
}
.b{
background-color: blue;
height: 30px;
margin: 2px;
width: 90%;
}
.c{
background-color: green;
height: 250px;
margin: 2px;
width: 90%;
overflow-y: scroll;
}
​

It's hard to tell exactly what you are trying to do based on the question, but if this is the desired result, these are the problems I discovered in your code:
You needed to hide overflow on the red box, so the green box does not extend beyond the container
In the green box, if there is enough data to extend, you want a scroll bar. This was working, but the height you had set specifically (250px) was enough to extend out of the container. You want a specific height here, the number is whatever is remaining in the container. I got 132px. Then with the overflow scroll applied, anything that extends beyond this height will be scrollable.

Related

HTML - CSS - How to left-align images in a centered and resizable parent

I have a lot of thumbnails in my page: I want them to be centered, but the last line looks awful while resizing and I have something like one or two orphan images floating in the center of the page.
The last line should be left-aligned.
How to do it?
I tried to insert another div with "margin:0 auto 0 auto;" but it doesn't work.
https://jsfiddle.net/4hw4fkm9/
What I try to have:
<div style="text-align:center;">
<img />
<img />
<img />
<img />
etc..
</div>
You should use CSS for this, not the HTML attribute "align", which is pretty old school. You can either float the images left, in which case they will stack to the left, or you could set all the images to display: inline-block, then use text-align: center on their container element (the div in this case).
Here are some references:
http://www.w3schools.com/css/css_float.asp
http://www.w3schools.com/cssref/pr_class_display.asp
I'm not sure if this is what you're looking for - as you mention that you both 'want them centered' but want them left-aligned, too.
What you can do is create another div that will act as a container, set width: 100% on the main div, set the width slightly lower on the container div and set margin: 0 auto; on the container. Then make the images relatively positioned with left:0;.
See Updated Fiddle Here. Is this what you're after?
EDIT: Re-Updated Fiddle for my attached comment. You can use set pixel values on the main and container div to account for the set pixel width of the thumbnails + any spacing that occurs.
Using the selectors in the fiddle.
.center {
text-align:center;
background-color:red;
margin:0 auto;
padding:0 20px;
}
.center:after{
content:'';
display:table;
clear:both;
}
img {
width: 100px;
height: 100px;
float:left;
}
From there the .center element would need a width of some multiple of 100px to include a fixed number of imgs. I added padding to make it look closer to the picture you provided.

Get height, or width, of a div with overflow property and use that to set a limit on the scroll bar

This might be a simple question, but unfortunately I can't figure out how to do this.
Let's say I have a div with an overflow property, so that when I add some text to it that is bigger than its dimensions, a scroll bar appears to fit the text within it, as so...http://jsfiddle.net/Lddxgzvz/
What I want to do is use plain javascript to get the new dimensions of the div with the scroll bar and use that to set a limit on how much text can be added to the div.
I'll try to illustrate this...
Let's say the limit on how much can be added to the div is 200px, meaning I want the scroll bar to remain static once the div reaches this size. So, for example, if the following text width is 250px:
Hello World Foo Bar
and the word Bar is 50px, I want only this text to appear within the div:
Hello World Foo
I tried using javascript to get the height and width of the div, but it does not take into consideration the overflow property. It only gets the height and width which I set the div to be initially.
I hope you all understand what I am trying to do, I'll re-edit if necessary.
You can try adding an inner wrapper with this CSS:
display: inline-block;
max-width: 200px; /* Maximum scrollable amount */
overflow: hidden;
.outer-wrapper {
border: solid 2px black;
height: 100px;
width: 100px;
overflow: auto;
}
.inner-wrapper {
display: inline-block;
max-width: 200px;
overflow: hidden;
}
<div class="outer-wrapper">
<div class="inner-wrapper">
LongLongLongLongLongLongLongLongLongLongLongLong
</div>
</div>
<div class="outer-wrapper">
<div class="inner-wrapper">
Short
</div>
</div>
As I understood you search scrollWidth and scrollHeight
console.log(document.getElementById('div').scrollWidth);
console.log(document.getElementById('div').scrollHeight);
Demo: http://jsfiddle.net/Lddxgzvz/1/

Single window application with 100% height and no scrollbars

I am currently developing a web application using jQuery.
The layout for the same goes as shown in the figure given below:
The orange color box at the very back should be 100% in height and width with some margin like 5px or so.
The logo and the tab-bar are placed as shown and are about 50px in height. But tab-bar should take size as shown with some margin.
The tab content should occupy the remaining height and should scroll for the contents it occupies.
Similar structure is required for the internal menubar and tab content.
Can anyone please suggest the layout method to employ?
Or how can I manipulate different heights/widths?
The requirement also suggests a responsive window i.e. the width/height to manipulate on resize.
The jsFiddle I said I'd make.
As you'll see, I make use of jQueryUI for the "tabs" layout and simply "add" a few things. The few things I "Add" are simple and the jQueryUI alreqady provides a strong CSS with which to manipulate to get desired result. Also attached to that page is a theme-switcher, so you could see what it would look like using different jQueryUI Default Themes.
I'll try to explain the process as shortly as possible without being to vague.
HTML
I first start with a basic page wrapper. Not too necessary, but it provides a nice "element" with which to work inside of and possibly make manipulations for page layout change in otherways in the future. For now it simply holds our page "padding" of 5px. The HTML and BODY tags will be set to a default and should not be manipulated beyond that as height and other properties begin to take different meanings for these tags in different browsers.
I then place 2 divs inside this wrapper, again, these could be done without depending on your needs. I like these 2 divs and use this alot because it provides "vertical align -> middle" as one might expect. The first, parent, is a div with class table. This will have its display set to table to provide a "table-like" layout but still have the ability to do things like "round the corners" or, as in my case, set height! The second, child, is the same except it will have a class and style as table-cell, respectively. This allows us to set something like vertical-align: middle; and ensure that this element is in the vertical middle of the page/table element. Again, with your layout, this may seem unneccessary, but I don't know your full expected end result and I'm trying to give as much "fluid dynamics" to the page as possible.
Finally, I first insert the jQueryUI tabs HTML in their expected layout, with 2 small differences. I place our "logo" in a custom span tag just before the ul. I also take the ui-tab-panel(s) and place them in their own container. This helps us adjust the height of our tabs area as needed. I also gave this container overflow, so even tho overflow maybe hidden on the body, it's still available for the tabs. (see also: small blog i wrote on jQueryUI Tabs)
<div class="page-wrapper">
<div class="table">
<div class="table-cell">
<div id="tabs">
<span class="my-logo">
<img src="http://www.w3.org/html/logo/downloads/HTML5_Logo_512.png" alt="logo here" />
</span>
<ul>
<li>Nunc tincidunt</li>
<li>Proin dolor</li>
<li>Aenean lacinia</li>
</ul>
<div class="ui-tabs-panel-container">
<div id="tabs-1">
<<p> ... </p>
</div>
<div id="tabs-2">
<p> ... </p>
</div>
<div id="tabs-3">
<p> ... </p>
</div>
</div>
</div>
</div>
</div>
</div>
CSS
As I mentioned before, jQueryUI provides us with a strong CSS to work with already. As you might have noticed, I made use of some of this by using their predefined class names throughout the HTML. This established things like background, color, and even font-family and more! Now that that is over with, let's layout our page mechanics first. As I mentioned, I give a very "direct" set of properties to HTML and BODY. This will help eliminate "Cross-browser-issues". I also provided a background color, tho you could set that at one of the children levels. This was done just to show you where HTML, BODY exist.
I then set our "frame" elements. .page-wrapper will provide our page wrapping, sizing will come from within, so there is no need to deal with it here. The .table and .table-cell provide display exactly as their name suggest. As previously mentioned, this provides a nice ability to maintain an element in the exact "center" of something, even vertically!
Now we manipulate our tabs and content. I use #tabs throughout to maintain "name-spacing". This will not only help with any "css overrides" on jQueryUI presets, but also helps keep page layout confusions to a minimum. This is always a good thing.
The first thing I manipulate is the placement and setting of our custom span for the logo. Then, of course, I have to change the ul to next to it. Thus I look at the CSS for the uls class. If I open edit tools in a browser, I can see the ul is given the classname ui-tabs-nav and I can see it has a margin setting. If I play with the margin-left of this ul I can see that nothing is affected but the left side of the ul. PERFECT! Here is what I must manipulate to set our log in its "own space".
Finally, I simply set our tabs container (given custom class name, ui-tabs-panel-container, made to match jQueryUI) to have overflow, so that if any content exceeds our page height, it can still be scrolled within this element.
html, body {
background-color: #ADDFFF;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
width: 100%;
}
.page-wrapper {
padding: 5px;
}
.table { display: table; }
.table-cell { display: table-cell; vertical-align: middle; }
#tabs .my-logo {
display: inline-block;
float: left;
height: 2em;
margin: .5em 0 0;
padding: 0;
width: 2em;
}
#tabs .my-logo img {
max-height: 100%;
max-width: 100%;
float: left;
}
#tabs .ui-tabs-nav {
margin-left: 2em;
}
#tabs .ui-tabs-panel-container {
overflow: auto;
}
JS
Finally, the easy work. I write a function to set the height of our tabs content area, since it will be "filling" the rest of the page. This take a little thought, but not hard to figure out. With the function written, I simply add it to the window resize event and call that event right after. This way it's resized on load, thus giving us our "end height" for first view. I also establish the tabs, although not much work there since I'm just making "default tabs". Feel free to experiment, go wild!
// the following will resize our tabs content area and account for all the spacing neccessary
function setContentHeight(e) { return $(window).innerHeight() - $(this).offset().top - 10; } // -10 to account for padding
$(function() { // our on page load call
$("#tabs").tabs(); // establish tabs
// add ability to resize tabs content area on window resize, then call resize event
$(window).resize(function(e) { $("#tabs .ui-tabs-panel-container").height(setContentHeight) }).resize();
})
As for the layout of tab content, it's all up to you and your imagination. Hopefully this will give you a good idea of where to get started though! Good luck!
You could use something like Blueprint CSS:
http://www.blueprintcss.org/
Here's a very quick and dirty layout (not using blueprint CSS, just plain CSS), as a general guideline. It still needs work, but it could be used as a starting point:
<html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden; /* hide page scrollbars */
}
div {
margin: 0 auto;
padding: 0;
border: 1px solid black; /* for debugging */
text-align: center;
}
#header {
width: 100%;
position: relative;
overflow: auto;
}
#header > div {
height: 5%;
float: left;
}
#logo {
width: 23%;
}
#spacer {
width: 1%; /* -1% for borders */
}
#tabbar {
width: 75%;
}
#tabContent {
}
#tabContent > div {
width: 100%;
}
#tabContentMenuBar {
height: 5%;
}
#tabContentMain {
min-height: 80%;
}
</style>
</head>
<body>
<div id="header">
<div id="logo">Logo</div>
<div id="spacer"></div>
<div id="tabbar" class="fullWidth">Tab bar</div>
</div>
<div id="tabContent">
Tab content
<div id="tabContentMenuBar">Tab content - menu bar</div>
<div id="tabContentMain">Tab content - main content</div>
</div>
</body>
</html>

Vertical Alignment

Please take a look at this: http://sources.freehosting.bg/landing.html
I am trying to vertically align #content so it looks good on larger (1920x1200) and smaller (1024x768) resolutions. By that I mean it does not have a scrollbar.
As you see there is plenty of free space so a scrollbar is unneeded.
The only solution I came up with is to calculate the height of #content with JS and to set a padding, but I realize it is the lamest possible solution.
Please advise me on how to achieve that.
See if this fiddle is what you are looking for. Simple solution IMO.
It works by forcing the containing div to behave as a table-cell, and making use of the vertical-align: middle style. It doesn't require you to know the heights of any elements at all.
Code used in the fiddle are below.
HTML:
<div class="a">
text inside div a
<div class="b">
text inside div b
</div>
</div>
The important styles are:
display: table-cell
vertical-align: middle
The rest are only there for demonstration. CSS:
div.a {
border: 1px solid red;
}
div.b {
border: 1px solid blue;
height: 200px;
display:table-cell;
vertical-align:middle;
}
If your content height is fixed put a div before the content
<div id="distance"></div>
<div id="content">
Vertically centered :D
</div>
and style it like:
html, body {
height:100%;
margin:0;
padding:0;
}
div#distance {
width:1px;
height:50%;
margin-bottom:-300px; /* half of website height */
float:left;
}
div#content {
text-align:left;
margin:auto;
position: relative;
width: 950px;
height: 600px;
clear: left;
}
​
The only way I know of that works using pure CSS, no JS and no hacks requires you to know the height of the thing you're trying to position:
<html>
<head>
<style type="text/css">
/* Give your document height */
body, #content {
height: 100%;
}
/* Give your element height */
.thing {
width: 20px;
height: 300px;
background: #000;
}
/* Position thing */
#content .thing {
position: absolute;
top: 50%;
margin-top: -150px; /* half the height of the thing */
}
</style>
</head>
<body>
<div id="content">
<div class="thing"></div>
</div>
</body>
</html>
EDIT: Updated height of item, container id. Still works just fine.
There is one way to do this without javascript and without knowing the height of the content - but purists will not like it. Then again, sometimes it doesn't matter if it's not approved by the trendy people. Sometimes all you need is to get the job done because you boss wants it that way.
And the solution is: use a table (told you purists wouldn't like it). Do layout the old school way and abuse the fact that HTML specifies lots of capabilities to tables.
A table cell is the only HTML element that has a vertical alignment attribute that does what most people expect it to do. Just give the table 100% width and height (so that is expands with the window size) and use cell alignment to position the content you want.
I've only ever had to use this trick once and it still makes me feel dirty* but when you really need it it works better than anything else.
*note: I'm a purist myself but understand that sometimes a man's got to do what a man's got to do.

Cross browser div center alignment using CSS

What is the easiest way to align a div whose position is relative horizontally and vertically using CSS ? The width and the height of the div is unknown, i.e. it should work for every div dimension and in all major browsers. I mean center alignment.
I thought to make the horizontal alignment using:
margin-left: auto;
margin-right: auto;
like I did here.
Is this a good cross browser solution for horizontal alignment ?
How could I do the vertical alignment ?
Horizontal centering is only possible if the element's width is known, else the browser cannot figure where to start and end.
#content {
width: 300px;
margin: 0 auto;
}
This is perfectly crossbrowser compatible.
Vertical centering is only possible if the element is positioned absolutely and has a known height. The absolute positioning would however break margin: 0 auto; so you need to approach this differently. You need to set its top and left to 50% and the margin-top and margin-left to the negative half of its width and height respectively.
Here's a copy'n'paste'n'runnable example:
<!doctype html>
<html lang="en">
<head>
<title>SO question 2935404</title>
</head>
<style>
#content {
position: absolute;
width: 300px;
height: 200px;
top: 50%;
left: 50%;
margin-left: -150px; /* Negative half of width. */
margin-top: -100px; /* Negative half of height. */
border: 1px solid #000;
}
</style>
<body>
<div id="content">
content
</div>
</body>
</html>
That said, vertical centering is usually seldom applied in real world.
If the width and height are really unknown beforehand, then you'll need to grab Javascript/jQuery to set the margin-left and margin-top values and live with the fact that client will see the div quickly be shifted during page load, which might cause a "wtf?" experience.
"Vertical centering is only possible if the element is positioned absolutely and has a known height." – This statement is not exactly correct.
You can try and use display:inline-block; and its possibility to be aligned vertically within its parent's box. This technique allows you to align element without knowing its height and width, although it requires you to know parent's height, at the least.
If your HTML is this;
<div id="container">
<div id="aligned-middle" class="inline-block">Middleman</div>
<div class="strut inline-block"> </div>
</div>
And your CSS is:
#container {
/* essential for alignment */
height:300px;
line-height:300px;
text-align:center;
/* decoration */
background:#eee;
}
#aligned-middle {
/* essential for alignment */
vertical-align:middle;
/* decoration */
background:#ccc;
/* perhaps, reapply inherited values, so your content is styled properly */
line-height:1.5;
text-align:left;
}
/* this block makes all the "magic", according to http://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align specification: "The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge." */
#container .strut {
/* parent's height */
height:300px;
}
.inline-block {
display:inline-block;
*display:inline;/* for IE < 8 */
*zoom:1;/* for IE < 8 */
}
Then #aligned-middle will be centered within #container. This is the simplest use of this technique, but it's a nice one to be familiar with.
Rules marked with "/* for IE < 8 */" should be placed in a separate stylsheet, via use of conditional comments.
You can view a working example of this here: http://jsfiddle.net/UXKcA/3/
edit: (this particular snippet tested in ie6 and ff3.6, but I use this a lot, it's pretty cross-browser. if you would need support for ff < 3, you would also need to add display:-moz-inline-stack; under display:inline-block; within .inline-block rule.)
Check this Demo jsFiddle
Set following two things
HTML align attribute value center
CSS margin-left and margin-right properties value set auto
CSS
<style type="text/css">
#setcenter{
margin-left: auto;
margin-right: auto;
// margin: 0px auto; shorthand property
}
</style>
HTML
<div align="center" id="setcenter">
This is some text!
</div>
"If the width and height are really unknown beforehand, then you'll
need to grab Javascript/jQuery to set the margin-left and margin-top
values and live with the fact that client will see the div quickly be
shifted during page load, which might cause a "wtf?" experience."
You could .hide() the div when the DOM is ready, wait for the page to load, set the div margin-left and margin-top values, and .show() the div again.
$(function(){
$("#content").hide();
)};
$(window).bind("load", function() {
$("#content").getDimSetMargins();
$("#content").show();
});

Categories