Vertical Alignment - javascript

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.

Related

css margin-top effecting image and paragraph at same time [duplicate]

I have a very simple html. The red div is inside the blue div and has a 10 px top margin. On non-ie browsers, the blue box is 10 px apart from the top of viewport and the red div is at the very top of the blue div. What I expect is the ie behavior: red div must be 10 px apart from the top of the blue div. Why does non-ie browsers render like this? (I suppose the wrong behavior is the IE's but why?)
And, what is the correct way to do this?
why blank? http://img92.imageshack.us/img92/7662/blankmr7.jpg
<html>
<head>
<style>
body { margin:0; padding:0; }
.outer
{
background-color: #00f;
height: 50px;
}
.inner
{
height: 20px;
width: 20px;
background-color: #f00;
margin: 10px 0 0 10px;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
</div>
</div>
</body>
</html>
As much as strager's answer already explains about as much as you need to know as to why it happens – namely that it happens the way it does in browsers other than IE because the specs say so – I think he picked the wrong quote from the section of the CSS 2.1 specification about collapsing margins.
The point he quoted explains how margins can collapse, not how they can "move" to a parent element.
This is rather what explains it:
If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it. In this case, the position of the element depends on its relationship with the other elements whose margins are being collapsed.
If the element's margins are collapsed with its parent's top margin, the top border edge of the box is defined to be the same as the parent's.
Or, in slightly more human-readable form in the Mozilla developer documentation:
Parent and first/last child:
If there is no border, padding, inline content, or clearance to separate the margin-top of a block with the margin-top of its first child block, or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom of a block with the margin-bottom of its last child, then those margins collapse. The collapsed margin ends up outside the parent.
As for how to fix it, I'd probably go for the overflow: auto solution Chris Lloyd suggested (as much as that may have side-effects).
But then that really depends on what exactly the rest of your code looks like. In this simple example you could easily just change the margin on the child element to a padding on the parent element.
Or you could float the child element, or absolutely position it...
Or how about an inverse clearfix if you want to get really fancy:
.outer:before {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
The margins are being merged. The output produced by IE is probably incorrect.
In the specifications (which are down for me at the moment):
Two or more adjoining vertical margins of block boxes in the normal flow collapse. The resulting margin width is the maximum of the adjoining margin widths.
You can use borders instead of margins, with border-color set to transparent.
There is a pretty fitting answer to this question: overflow: auto;
<html>
<head>
<style>
body { margin:0; padding:0; }
.outer
{
background-color: #00f;
height: 50px;
overflow: auto;
}
.inner
{
height: 20px;
width: 20px;
background-color: #f00;
margin: 10px 0 0 10px;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
</div>
</div>
</body>
</html>
Could it be IE sees the DOM as div.inner having div.outer as it's parent node(and calculates offset from it),
and that other browsers instead has both of them answering to the body element?
Ok, solution without overflow auto:
<html>
<head>
<style>
body { margin:0; padding:0; }
.outer
{
background-color: #00f;
height: 50px;
border: 1px solid transparent;
}
.inner
{
height: 20px;
width: 20px;
background-color: #f00;
margin: 10px 0 0 10px;
padding: 0;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
</div>
</div>
</body>
</html>
The inner element is wanting something to push against, and providing a boder (or forcing the browser to consider the overflow) does this.

How to draw a line from the middle of the page to the right side?

How to draw a line (using css, html or js) from the middle of the page to the right side?
This should work on a different screen resolutions.
The example provided in the picture.
Using a horizontal rule in css.
hr {
color: white;
background: blue;
width: 75%;
height: 5px;
margin-left:25%;
}
<body>
<hr />
<hr/>
</body>
Please see jsfiddle
http://jsfiddle.net/yvytty/jJRAt/
Maybe like this?
HTML
<div class="line"></div>
CSS
div.line {
width: 75%;
height: 1px;
margin-left: 25%;
background: red;
}
Demo
Try before buy
html:
<div id="lineID" class="line"></div>
css:
.line{
background:red;
height: 1px;
margin-left:50%;
}
javascript for more dynamic control:
//you can also put all the css in here
var scr=screen.width/2
var myLine = document.getElementById('lineID');
myLine.style.cssText= "width:"+scr+"px";
fiddle of course!
To my mind the best way to get a line from the middle to the right which scales correctly and is pure CSS is the following:
HTML
<div class="lineblock"></div>
CSS
.lineblock{
width: 50%; /*width can vary yours looks to be ~75% */
height: 20px; /* Random thickness I chose to make sure I saw it on the page */
float: right; /* Always forces to the right-hand side of the parent (so make sure
you're in the top level of the page or have no 'container' div
surrounding your line)*/
background: magenta; /*shows on anything*/
}
This method is both - a) Going to scale to all device screen sizes and be 50% of the viewport, and, b) be dumb enough to be IE 8 + safe (probably more but I only test to 8 it is used by about 10-12% of people internationally* and below that is almost nobody these days).
Sources:
HTML - Simple div
CSS - Experimentation
Browser Stats - Stat Counter's browser version usage for this month past.
Correct at time of writing.

Div to fill remaing vertical space

I have a complex HTML application, so unfortunately cannot really provide a code sample. We are trying to get the div (highlighted in red) to fill the remaining vertical space (see image).
The application consists of a header (in black), a sidebar on the left which can be dismissed or resized (note: the horizontal components resize correctly). To the right of the sidebar is another div (mainDiv). mainDiv contains a div at the top for the controls, and a div underneath it for the table of data (highlighted in red).
This table can potentially contain lots of data, so it needs its own scrollbar if the data doesn't fit on the screen.
We just want the table to fill all of the available horizontal and vertical space. We just can't seem to make it work.
We have created a jsfiddle example to demonstrate our layout as best we can. This can be seen here. We just want this div (in jsfiddle the div is called "tablewrap") to take up all of the remaining space.
Code (from jsfiddle) is as follows:
html
<div class="header">Header</div>
<div class="sidebar">This is the sidebar</div>
<div class="tablewrapper">
<div class="tableheader-controls-etc"></div>
<div class="tablewrap">table</div>
</div>
css
.header { height: 50px; background:black; color:white; }
.sidebar { height:100%; position:fixed; width 200px; background:gray; color:white; }
.tablewrapper{ float:right; width:75%; border:1px solid; margin-top:30px; margin-right:30px;}
.tableheader-controls-etc { height:150px; background:blue; color:white; }
.tablewrap { height: 200px; border: 2px solid red; width:100%; overflow:auto;}
If anyone can provide a solution that would be great. We would prefer CSS but can cope with Javascript.
Thanks,
Phil
The trick is to set position: absolute, then adjust the top, bottom, left and right properties as needed. See fiddle and explanation.
.tablewrap {
position: absolute;
top: 240px;
bottom: 0;
left: 150px;
right: 40px;
height: auto;
width: auto;
...
}
You can try this:
.tablewrap { height: 200px; border: 2px solid red; width:100%; overflow:auto; min-height:300px}
(Set the min-height as you want)
Well, it's time to say what you probably don't want to hear hehe: you can't do this with CSS.
You have to use javascript in order to find out two things:
Viewport height
Controls div height
Once you know those two heights, you can set your table height to:
finalHeight = viewport - (controls+header+footer)
If header and footer have also dynamic heights, use javascript to calculate them.
You will also need to recalculate this height on window resize. And of course your layout won't work if javascript is disabled.

Overflow scroll on y axis with fixed height

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.

Force <div></div> to the bottom of the web page centered

I have a <div>...</div> section in my HTML that is basically like a toolbar.
Is there a way I could force that section to the bottom of the web page (the document, not the viewport) and center it?
I think what you're looking for is this: http://ryanfait.com/sticky-footer/
It's an elegant, CSS only solution!
I use it and it works perfect with all kinds of layouts in all browsers! As far as I'm concerned it is the only elegant solution which works with all browsers and layouts.
#Josh: No it isn't and that's what Blankman wants, he wants a footer that sticks to the bottom of the document, not of the viewport (browser window). So if the content is shorter than the browser window, the footer sticks to the lower end of the window, if the content is longer, the footer goes down and is not visible until you scroll down.
Twitter Bootstrap implementation
I've seen a lot of people asking how this can be combined with Twitter Bootstrap. While it's easy to figure out, here are some snippets that should help.
// _sticky-footer.scss SASS partial for a Ryan Fait style sticky footer
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -1*($footerHeight + 2); /* + 2 for the two 1px borders */
}
.push {
height: $footerHeight;
}
.wrapper > .container {
padding-top: $navbarHeight + $gridGutterWidth;
}
#media (max-width: 480px) {
.push {
height: $topFooterHeight !important;
}
.wrapper {
margin: 0 auto -1*($topFooterHeight + 2) !important;
}
}
And the rough markup body:
<body>
<div class="navbar navbar-fixed-top">
// navbar content
</div>
<div class="wrapper">
<div class="container">
// main content with your grids, etc.
</div>
<div class="push"><!--//--></div>
</div>
<footer class="footer">
// footer content
</footer>
</body>
If I understand you correctly, you want the toolbar to always be visible, regardless of the vertical scroll position. If that is correct, I would recommend the following CSS...
body {
margin:0;
padding:0;
z-index:0;
}
#toolbar {
background:#ddd;
border-top:solid 1px #666;
bottom:0;
height:15px;
padding:5px;
position:fixed;
width:100%;
z-index:1000;
}
I just want to be clear on what your saying here:
bottom of the web page (the
document, not the viewport)
Naturally, a div will be at the bottom of the "document", depending on your layout.
If it's not going to the bottom of a document, or not paying attention to how tall your columns are, is it because your floating? Clear: both; would be in order to solve that.
The sticky footers are what I think your looking for, but when you say document, and not the viewport, I get a bit confused. Sticky footers typically do this: Watch for short pages, and if its shorter than the view port, the sticky footer tacks the footer div to the bottom.
Here's some sticky footers (there's gajillions of em, but this is in order of my favorites):
http://www.cssstickyfooter.com/
http://css-tricks.com/sticky-footer/
http://ryanfait.com/sticky-footer/ (listed previously)
http://brassblogs.com/blog/sticky-footer
http://alistapart.com/ (theres one there I just can't find it)
Maybe if you gave a quick illustration or were a bit more specific on what you want? Hope this helps :D
-Ken
Try this: Fixed footers without Javascript. I don't know if it will be a perfect fit, but I think it's close enough.
You can just give the div a:
clear:both; text-align:center;
and put the div as the last element before the closing body statement. That would force it to be the last element without anything next to it.
Your best bet is to use javascript to determine the size of your page. You can get the height with window.innerHeight with non-IE browsers and document.documentElement.clientHeight with IE. With that value you should be able to absolutely position your element on the page setting top to that value minus the height of your div. If the height of your div is variable you will need to check the div's offsetHeight property to get the real height.
For centering use the following example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
.wrapper
{
width: 100%;
padding-left: 50%;
}
.test
{
width: 400px;
margin-left: -200px;
border: 1px solid black;
padding-left: -200px;
}
</style>
</head>
<div class="wrapper">
<div class="test">This is a test</div>
</div>
</html>
You have a wrapper div around the div you want centered. The wrapper div has a width of 100% the inner div has a width set to whatever you want it to be. Give the wrapper div a left padding of 50% and the inner div a negative left margin equal to half of its width.

Categories