<div class='main_container' style='overflow:hidden; height:100%; height: auto !important; min-height:100%; width:100%;'>
<div class='float_left' style='width:100px; height:100%;'>
</div>
<div class='float_right' style='width:100px;'>
</div>
<div class='clear'></div>
<div class='content'>
//elastic content that sometimes makes the page longer or shorter
</div>
</div>
No matter how many tutorials or examples I looked at, nothing is helping me. I've tried many different combinations. As soon as I set main_container to a px height, the sidebars then, correctly, take up 100% of the height. But I can't set a px height for the main container.
EDIT:
example
The content box will not have a static height. So far what happens is that main_container adjusts it's height based on the content box, but the two sidebars don't adjust there height based on the main_containers height.
In addition to Adrift's answer, you are also overriding the height: 100% with the following height: auto !important - the latter overrides the height setting, even though it is not the source of the problem.
Here is a Gist that works on Chrome and most likely also on other modern browsers as well.
This solution uses CSS tables cells that allow the left/right sidebars to take on the height of the central .content panel.
The HTML:
<div class='main_container'>
<div class='left_bar'></div>
<div class='content'>
<p>Elastic content that sometimes makes the page longer or shorter</p>
<p>Lorem ipsum dolor sit amet, ...</p>
</div>
<div class='right_bar'></div>
</div>
The CSS:
.main_container {
display: table;
width: 100%;
}
.left_bar {
display: table-cell;
width: 100px;
background-color: lightgray;
}
.right_bar {
display: table-cell;
width: 100px;
background-color: lightgreen;
}
.content {
padding: 0 20px;
}
Demo Fiddle: http://jsfiddle.net/audetwebdesign/zahPD/
As suggested in other comments, you can specify height: 100% or height: inherit to .main_container as required in your application.
Reference for table-cell: https://developer.mozilla.org/en-US/docs/Web/CSS/display
Backwards Compatibility
Works with IE8 and above.
Div not supports height in percent using xhtml document. You use a trick like this:
.main_container{
position:fixed;
top:0;bottom:0;
right:0;left:0;
}
I've write an example here: http://jsfiddle.net/vF6fY/ take a look to it
Related
I'm making a basic header using divs and a nested img in a fluid layout. I'm a bit rusty on this and i can't for the love of me figure out how to ensure that the image nested in the div scales without scaling to the point where it becomes smaller its parent div.
EDIT: Updated the codepen link showing how using min-height won't work as it squeezes the image
HTML:
<div class="container">
<div class="item half">
<p>
Some text
</p>
</div>
<div class="item half">
<img src="http://dummyimage.com/hd1080" class="full-width">
</div>
</div>
CSS:
.container{
margin: 0 auto;
max-width: 1920px;
}
.item{
height: 300px;
float:left;
overflow: hidden;
background-color: gray;
}
.half{
width: 50%
}
.full-width{
max-width: 100%;
}
And for good measure a quick illustration of what is happening:
And an illustration of what i want to happen:
Edit: Note that the image here is not being squeezed, which is what happens if you set the image to have a min-height equal to its parent div. But rather the overflow is hidden. You can also see that i do not mind the images being cropped.
Any help appreciated.
You can add min-height equal to the div.item height to your image CSS
img {
max-width:100%;
min-height:300px;
}
I've managed to find the solution i wanted in this thread. The function i was looking for was object-fit.
I've used the following solution:
img{
min-height: 100%;
object-fit: cover;
}
Edit: quickly found out that this property is only properly supported by Firefox, Chrome and Opera. Use this polyfill to fix this on Safari and IE.
I have a page with following html markup:
<html>
<head>...</head>
<body>
<div class="container">
<header>...</header>
<div class="wrapper">
<div class="row">
<div class="col-md-8">...</div>
<div class="col-md-3 col-md-offset-1 col-aside">
<aside>...</aside>
</div>
</div>
</div>
</div>
</body>
</html>
I set 100% height for:
html, body, body > .container {
height: 100%;
}
.wrapper {
min-height: 100%;
}
.wrapper > .row {
min-height: 100%;
}
.col-aside {
min-height: 100%;
}
So I want that both my columns have minimum height of 100%. While inspecting my page with chrome developer tools I realized that .row and .col-aside don't get 100% height. I am a little bit lost because I saw answers dealing with display: table but I'm pretty sure it's not necessary since I managed to do this layout without bootstrap using just divs and their heights.
So have to stretch columns so that they have min-height: 100% preferably without using display: table and position: absolute?
updated: jsfiddle http://jsfiddle.net/U6H6W/ . Something like that, here you can see that .row doesn't get 100% height in spite of the fact that .wrapper gets 100%
A better solution would be to use viewport height, e.g.:
.col-aside {
height: 100vh;
}
You can easily specify the height of one div, without having to specify the height of the higher level HTML blocks.
Viewport is supported in all modern browsers, and as far back as IE9. IE8 does not support viewport, but if you need legacy support going back that far you can set a fallback to height: 100% (making sure you cover all of the containing blocks.)
Here is a jsbin to demonstrate:
http://jsbin.com/zeyuraka/1/edit
When dealing with heigth:100%, all the parents should be in height:100%. If one isn't, then no child is.
The 100% approach is complicated, especially when it comes to many childs with padding or margins. It could not display what you expect (i.e. exceed screen size).
You could try position: fixed, with bottom:0, but you will have to handle the position of the non-fixed div.
How to size a div's height to its container height, using CSS ?
<div class='container'><br>
<div style='display: block; height: 500px'>left</div><br>
<div id='to-be-sized' >right</div><br>
</div>
You can either:
use the incomplete but philosophically correct path of pure CSS and face every kind of incompatibility between browsers
or
write 3 lines of dirty semantically incorrect and devil made table and have it work perfectly everywhere
Your pick :)
There's a way to do this IF you happen to be using jQuery. As you asked for CSS this might not be an option available to you, but if you can utilise it it will do exactly what you want.
$(divToResize).css('height',$(container).innerHeight());
$(divToResize) is the selector for the DIV you wish to match the height of it's container and $(container) is logically the container whose height you want to get.
This will work regardless of if the container's height is specified in CSS or not.
I know this was answered forever ago, but when I run into this issue nowadays, I use Flex Box. It's awesome. See A Complete Guide to Flexbox by Chris Coyier
.parent {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
width: 100%;
}
.child {
flex-grow: 1;
}
.child1 {
min-height: 200px;
background-color: #fee;
}
.child2 {
background-color:#eef;
}
<div class="parent">
<div class="child child1">Child 1</div>
<div class="child child2">Child 2</div>
</div>
The Flexbox Layout (Flexible Box) module aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word "flex").
The main idea behind the flex layout is to give the container the ability to alter its items' width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.
Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).
If my understanding is correct and the default height of a div where no height is specified is auto then this is not possible without setting an explicit height on the containing div. If an explicit height is set on the containing div then height:100% on the contained div will mean that it grows to the height of the container.
It seems like you are trying to get equal height columns. You could use the fauxcolumns method where a background image is used to fake the equal height. There are other methods out there.
You can tell the container div to display as table and have the inner div to display as a table cell.
The HTML
<body>
<div id="wrap">
<div id="header">
<h1>
My Header</h1>
</div>
<div id="main">
<ul id="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div id="primaryContent">
</div>
</div>
<div id="footer">
<h1>
My Footer</h1>
</div>
</div>
The CSS
#wrap
{
width: 800px;
margin: auto;
}
#header
{
background: red;
}
#main
{
display: table;
}
#nav
{
background: gray;
width: 150px;
display: table-cell;
}
#primaryContent
{
background: yellow;
padding: 0 .5em;
display: table-cell;
}
Fixes for IE
#wrap
{
width: 800px;
margin: auto;
}
#header, #footer
{
background: red;
}
#main
{
background: url(../bg.png) repeat-y;
}
#nav
{
background: gray;
width: 150px;
float: left;
}
#primaryContent
{
background: yellow;
margin-left: 150px;
padding: 0 .5em;
}
It's a tricky thing to do--there's no clear-cut best approach, but there are a few common ones.
If we assume that what you REALLY need is for the height of the right column to be (or appear to be) equivalent to the height of the left column, you can use any of the techniques frequently used to get equal height columns. This piece contains a few tricks to get the right look and behavior. I recommend reading it to see if it solves your problem.
The other approach uses Javascript to determine the height of the container, and setting your right-hand column to that. That technique has been discussed on SO here. As long as your container's size is not the only thing determining the size of your outer container, that should be a valid approach (if that's not the case, you'll have a chicken-egg problem that could cause weird behavior).
Sample code, you need to start from the html element so you can make use of the flexible height in the containers.
<!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>
<title>100% Test</title>
<style type="text/css">
html, body, #inner { height: 100% }
#inner { border: 4px blue solid }
#container { height: 200px; border: 4px red solid }
</style>
</head>
<body>
<div id="container">
<div id="inner">
lorem ipsum
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<style type="text/css">
.container{
position:relative;
background-color:#999;
}
#to-be-sized{
position:absolute;
top:0;
height:100%;
background-color:#ddd;
}
</style>
<body>
<div class='container'>
<br>
<div style='display: block; height: 500px'>left</div>
<br>
<div id='to-be-sized' >right</div><br>
</div>
</body>
</html>
CSS files use the 'padding' function to determine the height and depth of containers. To change the height of the container field simple insert of adjust the padding fields for the specified containers.
The code excerpt below is an example of the CSS used for a container class (you'd find this as in the html file.
.container{padding-top:100px;padding-bottom:50px}header
i use the overflow:hidden it work properly.
.bu {
overflow: hidden;
background-color:blue;
}
<div class="bu">
<button>english</button>
</div>
try adding this to the div to be resized
.layout-fill {
margin: 0;
width: 100%;
min-height: 100%;
height: 100%;
}
I did something similar to KyokoHunter:
$('div.row').each(function(){
var rowHeight = $(this).innerHeight();
$(this).children('div.column').css('height',rowHeight);
});
This goes through every row in a div "table" and makes the heights all match, as long as the divs are classed accordingly.
I want to put two <div>s next to each other. The right <div> is about 200px; and the left <div> must fill up the rest of the screen width? How can I do this?
You can use flexbox to lay out your items:
#parent {
display: flex;
}
#narrow {
width: 200px;
background: lightblue;
/* Just so it's visible */
}
#wide {
flex: 1;
/* Grow to rest of container */
background: lightgreen;
/* Just so it's visible */
}
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
This is basically just scraping the surface of flexbox. Flexbox can do pretty amazing things.
For older browser support, you can use CSS float and a width properties to solve it.
#narrow {
float: right;
width: 200px;
background: lightblue;
}
#wide {
float: left;
width: calc(100% - 200px);
background: lightgreen;
}
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
I don't know if this is still a current issue or not but I just encountered the same problem and used the CSS display: inline-block; tag.
Wrapping these in a div so that they can be positioned appropriately.
<div>
<div style="display: inline-block;">Content1</div>
<div style="display: inline-block;">Content2</div>
</div>
Note that the use of the inline style attribute was only used for the succinctness of this example of course these used be moved to an external CSS file.
Unfortunately, this is not a trivial thing to solve for the general case. The easiest thing would be to add a css-style property "float: right;" to your 200px div, however, this would also cause your "main"-div to actually be full width and any text in there would float around the edge of the 200px-div, which often looks weird, depending on the content (pretty much in all cases except if it's a floating image).
EDIT:
As suggested by Dom, the wrapping problem could of course be solved with a margin. Silly me.
The method suggested by #roe and #MohitNanda work, but if the right div is set as float:right;, then it must come first in the HTML source. This breaks the left-to-right read order, which could be confusing if the page is displayed with styles turned off. If that's the case, it might be better to use a wrapper div and absolute positioning:
<div id="wrap" style="position:relative;">
<div id="left" style="margin-right:201px;border:1px solid red;">left</div>
<div id="right" style="position:absolute;width:200px;right:0;top:0;border:1px solid blue;">right</div>
</div>
Demonstrated:
left
right
Edit: Hmm, interesting. The preview window shows the correctly formatted divs, but the rendered post item does not. Sorry then, you'll have to try it for yourself.
I ran into this problem today. Based on the solutions above, this worked for me:
<div style="width:100%;">
<div style="float:left;">Content left div</div>
<div style="float:right;">Content right div</div>
</div>
Simply make the parent div span the full width and float the divs contained within.
UPDATE
If you need to place elements in a row, you can use Flex Layout. Here you have another Flex tutorial. It's a great CSS tool and even though it is not 100% compatible, each day its support is getting better. This works as simple as:
HTML
<div class="container">
<div class="contentA"></div>
<div class="contentB"></div>
</div>
CSS
.container {
display: flex;
width: 100%;
height: 200px;
}
.contentA {
flex: 1;
}
.contentB {
flex: 3;
}
And what you get here is a container with a total size of 4 units, that share the space with its children in a relation of 1/4 and 3/4.
I have done an example in CodePen that solves your problem. I hope it helps.
http://codepen.io/timbergus/pen/aOoQLR?editors=110
VERY OLD
Maybe this is just a nonsense, but have you tried with a table? It not use directly CSS for positioning the divs, but it works fine.
You can create a 1x2 table and put your divs inside, and then formatting the table with CSS to put them as you want:
<table>
<tr>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
</tr>
</table>
Note
If you want to avoid using the table, as said before, you can use float: left; and float: right;and in the following element, don't forget to add a clear: left;, clear: right; or clear: both; in order to have the position cleaned.
div1 {
float: right;
}
div2 {
float: left;
}
This will work OK as long as you set clear: both for the element that separates this two column block.
I ran into the same problem and Mohits version works. If you want to keep your left-right order in the html, just try this. In my case, the left div is adjusting the size, the right div stays at width 260px.
HTML
<div class="box">
<div class="left">Hello</div>
<div class="right">World</div>
</div>
CSS
.box {
height: 200px;
padding-right: 260px;
}
.box .left {
float: left;
height: 200px;
width: 100%;
}
.box .right {
height: 200px;
width: 260px;
margin-right: -260px;
}
The trick is to use a right padding on the main box but use that space again by placing the right box again with margin-right.
I use a mixture of float and overflow-x:hidden. Minimal code, always works.
https://jsfiddle.net/9934sc4d/4/ - PLUS you don't need to clear your float!
.left-half{
width:200px;
float:left;
}
.right-half{
overflow-x:hidden;
}
As everyone has pointed out, you'll do this by setting a float:right; on the RHS content and a negative margin on the LHS.
However.. if you don't use a float: left; on the LHS (as Mohit does) then you'll get a stepping effect because the LHS div is still going to consume the margin'd space in layout.
However.. the LHS float will shrink-wrap the content, so you'll need to insert a defined width childnode if that's not acceptable, at which point you may as well have defined the width on the parent.
However.. as David points out you can change the read-order of the markup to avoid the LHS float requirement, but that's has readability and possibly accessibility issues.
However.. this problem can be solved with floats given some additional markup
(caveat: I don't approve of the .clearing div at that example, see here for details)
All things considered, I think most of us wish there was a non-greedy width:remaining in CSS3...
This won't be the answer for everyone, since it is not supported in IE7-, but you could use it and then use an alternate answer for IE7-. It is display: table, display: table-row and display: table-cell. Note that this is not using tables for layout, but styling divs so that things line up nicely with out all the hassle from above. Mine is an html5 app, so it works great.
This article shows an example: http://www.sitepoint.com/table-based-layout-is-the-next-big-thing/
Here is what your stylesheet will look like:
.container {
display: table;
width:100%;
}
.left-column {
display: table-cell;
}
.right-column {
display: table-cell;
width: 200px;
}
To paraphrase one of my websites that does something similar:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style TYPE="text/css"><!--
.section {
_float: right;
margin-right: 210px;
_margin-right: 10px;
_width: expression( (document.body.clientWidth - 250) + "px");
}
.navbar {
margin: 10px 0;
float: right;
width: 200px;
padding: 9pt 0;
}
--></style>
</head>
<body>
<div class="navbar">
This will take up the right hand side
</div>
<div class="section">
This will fill go to the left of the "navbar" div
</div>
</body>
</html>
just use a z-index and everything will sit nice. make sure to have positions marked as fixed or absolute. then nothing will move around like with a float tag.
Is there a way to have two columns, that match each other in height, without using table cells, fixed heights or Javascript?
Using a TABLE
<table>
<tr>
<td style="background:#F00;">
This is a column
</td>
<td style="background:#FF0;">
This is a column<br />
That isn't the same<br />
height at the other<br />
yet the background<br />
still works
</td>
</tr>
</table>
Using DIVs
<div style="float:left;background:#F00" >
This is a column
</div>
<div style="float:left;background:#FF0" >
This is a column<br />
That isn't the same<br />
height at the other<br />
yet the background<br />
still works
</div>
<div style="clear:both;" ></div>
The goal is to make both backgrounds extend the full height regardless of which side is taller.
Nesting one in the other wouldn't work because it doesn't guarantee both side are the correct height.
Unfortunately, the preview showed the working HTML, but the actual post stripped it out. You should be able to paste this into an HTML file and see what I mean.
http://www.xs4all.nl/~peterned/examples/csslayout1.html
this is the kind of thing you want, give them both a height of 100% (using this css trick) and they'll stretch out to the height of the containing div!
edit: forgot to mention, put them in a container div!
Edit:
<html>
<head>
<style>
html, body
{
margin: 0;
padding: 0;
height: 100%; /* needed for container min-height */
}
#container
{
background-color: #333333;
width: 500px;
height: auto !important; /* real browsers */
height: 100%; /* IE6: treaded as min-height*/
min-height: 100%; /* real browsers */
}
#colOne, #colTwo
{
width: 250px;
float: left;
height: auto !important; /* real browsers */
height: 100%; /* IE6: treaded as min-height*/
min-height: 100%; /* real browsers */
}
#colOne
{
background-color: #cccccc;
}
#colTwo
{
background-color: #f4f5f3;
}
</style>
</head>
<body>
<div id="container">
<div id="colOne">
this is something</div>
<div id="colTwo">
this is also something</div>
<div style="clear: both;">
</div>
</div>
</body>
</html>
Just because nobody's said this, a lot of times people just fake the existence of even columns, by having a background image which tiles itself all the way to the bottom of the outer container.
This gives the appearance that the content is in two equal columns, even though one ends before the other.
Use the Faux Column CSS technique to solve this problem.
Given the following:
<div class="contentSidebarPair">
<div class="sidebar"></div>
<div class="content"></div>
</div>
You can use the following styles:
/* sidebar.gif is simply a 200x1px image with the bgcolor of your sidebar.
#FFF is the bgcolor of your content */
div.contentSidebarPair {
background: #FFF url('sidebar.gif') repeat-y top left;
width: 800px;
margin: 0 auto; /* center */
zoom: 1; /* For IE */
}
/* IE6 will not parse this but it doesn't need to */
div.contentSidebarPair:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
div.sidebar {
float: left;
width: 200px;
}
div.content {
float: left;
width: 600px;
}
There! Simple and effective. Absolutely zero JavaScript involved. And if you want to create more complex layouts (liquid layouts), you can adapt this technique using background-position. A tutorial is available here.
display:inline-block
With a trick, it even works in IE:
<div><span>
col1
</span></div>
<div><span>
col2
</span></div>
div {display:inline;}
span {display:inline-block;}
Yes, it is possible - pure CSS and no hacks - equal height columns.
Check this this article - it is very well written.
It's straightforward if you are dealing with browsers which support CSS2.1 (IE8 and above, all other major browsers). If this is your markup:
<div>
This is a column
</div>
<div>
This is a column<br />
That isn't the same<br />
height at the other<br />
yet the background<br />
still works
</div>
This would be your CSS:
div { display: table-cell; }
If you need more than one row in the layout you will have to add some wrapper elements in there, but otherwise this works straight off.
Theres a simple way of achieving this with clever HTML and CSS.
First the HTML:
<div id="container">
<div id="col1">
this is column 1
</div>
<div id="col2">
this is column 2<br />
it is obviously longer than the first column <br />
YEP!
</div>
</div>
Please note the lack of clear:both unsemantic div.
Now the CSS:
#container { background:#f0f; overflow:hidden; width:400px; }
#col1, #col2 { float:left; width:50%; }
#col2 { background:#ff0; }
The overflow hidden in the container rule makes sure that the container expands to the size of the contained floated divs (and gets rid of the unsematic clearing div that everyone loves so much).
The background of the container applies to the first column. The background of the col2 div applies only to the second div. This is what gives us the illusion that both divs are always the same height.
Simple, semantic solution in 3 lines of CSS. Enjoy
EDIT: Please comment on reason to vote down, otherwise I have to guess why my answer is wrong. In this case I had forgot to add the width property to the container so that it plays nice with IE6/7. Please check the revised CSS above.