How to get a floating-DIV to fill available space within its parent DIV?
If you use floats, you pretty much need to give them widths. Floats are fine if you specify the width or you're happy with whatever the browser calculates as the minimum required width. As soon as you need them to expand to fill available space you're out of luck.
In fact you're using the wrong tool.
So you have two possibilities:
- Fix the size of the floats; or
- Use a table.
With tables this is a trvial problem to solve (waits for the anti-table pure-CSS fanatics to go nuts).
EDIT: Ok, you want to do verticall centering as well. Now you're really in trouble. See Can you do this HTML layout without using tables? for how hard even simple layout can be with pure CSS, particularly when you want to do vertical centering (when the container or the child aren't fixed height) or side by side content.
Again, tables make this trivial with vertical-align: middle
.
If you want more information on vertical centering with pure CSS, see:
- Vertical Centering in CSS: three levels of nested divs... just to get vertical centering;
- How to: vertical centering with CSS; and
- Vertical centering with CSS.
Make div fill remaining space of parent
Getting the correct position and width of .bottom
appears to be the biggest hurdle for a cross-browser, CSS solution.
Options
1. Floats
As @joeellis demonstrated, the flexible widths can be achieved by floating only the left column, and applying overflow:hidden
to the right column.
The position of .bottom
cannot be achieved in any browser. There's no CSS solution for floated columns with equal, variable height. An absolutely positioned .bottom
element must be inside the right column div, so that 100% width would give it the correct size. But since the right column won't necessarily be as tall as the left column, positioning .bottom
with bottom:0
won't necessarily place it at the bottom of the container.
2. HTML tables and CSS tables
The flexible widths can be achieved by giving the left cell a width of 1px and not specifying a width for the right cell. Both cells will grow to fit the content. Any extra space will be added to the right cell alone.
If .bottom
is inside the right table cell, the position can't be achieved in Firefox. Relative position has no effect in a table cell in Firefox; absolute position and 100% width would not be relative to the right table cell.
If .bottom
is treated as a separate table cell in the right column, the correct heights of the right and bottom table cells cannot be achieved in any browser other than Firefox. Table cells aren't flexible in height the same way they are in width (except in Firefox).
3. CSS3 flexbox and CSS3 grids
Flexbox and grids are the promising layout tools of the near future. But flexbox isn't supported by IE9 or earlier, and grids aren't supported by any browser other than IE10. Haven't tested if either can achieve this layout, but browser support may prevent them from being an option at present.
Summary
- Floats don't offer a solution for any browser.
- HTML tables and CSS tables don't offer a cross-browser solution.
- Flexbox doesn't offer a potential solution for IE9 or earlier (and may or may not offer a solution to other browsers).
- Grids only offer a potential solution to IE10 (and may or may not offer a solution there).
Conclusion
There doesn't appear to be an adequate CSS solution at present, one that would work in enough relevant browsers, with the possible exception of flexbox (if support for IE9 and earlier isn't required).
jQuery
Here's a couple modified demos that use jQuery to force the columns to have the same height. The CSS and jQuery for both demos is the same. The HTML only differs by how much content is in the left and right column. Both demos tested fine in all browsers. The same basic approach could be used for plain JavaScript.
- Taller content on the left
- Taller content on the right
To keep things simple, I moved the internal padding for the left and right div to a child element (.content
).
Floating child div to fill only remaining space
The problem is the float: left
makes the yellow area not "stretch." To make the image float to the right of the text, it has to come before the text. So we change the order of the content blocks:
<div class="content-block-body">
<div class="content-block-image"> <img src="image-1.jpg"> </div>
<div class="content-block-text">
<div>月額固定と成果報酬が選べます</div>
<div>成果報酬額に上限おもうけられます</div>
<div>料金が明瞭で予算に合わせた対策が可能</div>
</div>
</div>
And then adjust the css:
.content-block-body {
width: 100%;
background-color: brown;
overflow:auto;
}
.content-block-text{
/*float:left;*/ /* this we remove */
background-color: red;
padding:2%;
/* this we add: */
overflow: auto;
}
.content-block-image{
background-color: greenyellow;
float: right;
}
Note that whenever you float things you'll most likely need to add what's called a "clearfix". In this case, apply the clearfix to the .content-block-body
to make it extend vertically to fit the floated element http://nicolasgallagher.com/micro-clearfix-hack/
floating div spanning parents width
Given that you want the second of the child div
elements to be the full remaining-width of the parent, you've no need to float
it. Given the following mark-up:
<div id="parent">
<div id="one">The first div, fixed width</div>
<div id="two">The second, taking up the rest of the space.</div>
</div>
And CSS:
#parent {
width: 90%; /* adjust to taste */
padding: 10px;
background-color: #ffa; /* just to see where each element is in the document */
overflow: hidden; /* to ensure the parent encloses the floated child div */
}
#one {
float: left;
width: 100px; /* whatever width you need */
background-color: red;
}
#two {
background-color: #f90;
}
This seems to give the effect you're looking for: JS Fiddle demo, though tested only in Chromium 17 on Ubuntu 11.04.
Edited in response to comment from OP, below:
When I remove the float from my second div or in the jsfiddle example of mine .title the background fills the entire parent. Not sure what I'm doing wrong...
The problem is that the float
-ed element is taken out of the document's flow, and the second div
(.title
in your JS Fiddle) extends 'behind' it.
To prevent that you need to both remove the float
from the second div (it's still there in the link you posted) and also give a margin-left
to the .title
element, in order to prevent it taking the full width:
.title{
padding: 17px 20px 0;
background-color: red;
height:54px;
margin-left: 200px;
}
JS Fiddle demo.
If you're unable to give a margin-left
for any reason, you could, instead, use height: 100%;
on the float
-ed div
(.time
), although this is problematic due to the padding (given that the height of the element is defined-height + padding):
.time{
padding: 17px 20px 0;
float:left;
margin-right: 20px;
height: 100%;
background-color: black;
}
JS Fiddle demo.
To correct the height
problem, in compliant browsers, you could use the box-sizing
CSS property to include the padding
in the height
:
.time{
padding: 17px 20px 0;
float:left;
margin-right: 20px;
height: 100%;
background-color: black;
box-sizing: border-box;
}
JS Fiddle demo.
Set a floating div's width to take up remaining space
Remove float and clear from .display-field
. Now the .display-field div starts from the left side of the browser so you need to add the desired colors to the divs to manipulate the output.
.display-label {
float:left;
clear:left;
min-width:160px;
background:white
}
.display-field {
background:red
}
DEMO
why this floating div do not goes into its parent element?
Swap the order of the left and float_r elements. Divs are block elements.
See fiddle: http://jsfiddle.net/hL8tvet8/4/
<div class="header">
<div class="float_R"></div>
<div class="left"></div>
</div>
How to make a floated div 100% height of its parent?
For #outer
height to be based on its content, and have #inner
base its height on that, make both elements absolutely positioned.
More details can be found in the spec for the css height property, but essentially, #inner
must ignore #outer
height if #outer
's height is auto
, unless #outer
is positioned absolutely. Then #inner
height will be 0, unless #inner
itself is positioned absolutely.
<style>
#outer {
position:absolute;
height:auto; width:200px;
border: 1px solid red;
}
#inner {
position:absolute;
height:100%;
width:20px;
border: 1px solid black;
}
</style>
<div id='outer'>
<div id='inner'>
</div>
text
</div>
However... By positioning #inner
absolutely, a float
setting will be ignored, so you will need to choose a width for #inner
explicitly, and add padding in #outer
to fake the text wrapping I suspect you want. For example, below, the padding of #outer
is the width of #inner
+3. Conveniently (as the whole point was to get #inner
height to 100%) there's no need to wrap text beneath #inner
, so this will look just like #inner
is floated.
<style>
#outer2{
padding-left: 23px;
position:absolute;
height:auto;
width:200px;
border: 1px solid red;
}
#inner2{
left:0;
position:absolute;
height:100%;
width:20px;
border: 1px solid black;
}
</style>
<div id='outer2'>
<div id='inner2'>
</div>
text
</div>
I deleted my previous answer, as it was based on too many wrong assumptions about your goal.
Related Topics
Bootstrap Tables Overflowing with Long Unspaced Text
Hide Check Radio Button with CSS
Changing Spacing Between Paragraphs and Inside of Paragraphs
How to Use SCSS/Sass to Increase Animation-Delay for Concurrent Divs
Less Immediate Parent Selector
What Is the Use Case of :Host-Context Selector in Angular
Center a <Ul> List with a Left Float <Li>'s with CSS
How to Use Two-Column Layout with Reveal.Js
Responsive Canvas in Bootstrap Column
How to Disable Stacking of Bootstrap Justified Tabs on Small Screens
Recording and Saving an Svg Animation as an Animated Gif
Reset/Remove All Styles for Input, Select and Button Across All Browsers Including Mobile
How to Align Input Field and Submit Button (Also Differences Between: Ie, Ffox, Chrome)