118

I have something like that:

<div style="width:100px;float:left">menu</div>
<div style="float:left">content</div>

both floats are neccesary. I want the content div to fill the whole screen minus those 100px for the menu. If i dont use float the div expands exactly as it should. But how do i set this when float is set? If i use sth like

style=width:100%

then the content div gets the size of the parent, which is either the body or another div which i also tried, and so of course it does not fit right of the menu and is then shown below.

Flo
  • 1,445
  • 2
  • 10
  • 12

10 Answers10

143

Hope I've understood you correctly, take a look at this: http://jsfiddle.net/EAEKc/

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Content with Menu</title>
  <style>
    .content .left {
      float: left;
      width: 100px;
      background-color: green;
    }
    
    .content .right {
      margin-left: 100px;
      background-color: red;
    }
  </style>
</head>

<body>
  <div class="content">
    <div class="left">
      <p>Hi, Flo!</p>
    </div>
    <div class="right">
      <p>is</p>
      <p>this</p>
      <p>what</p>
      <p>you are looking for?</p>
    </div>
  </div>
</body>

</html>
jpaugh
  • 6,634
  • 4
  • 38
  • 90
merkuro
  • 6,161
  • 2
  • 27
  • 29
  • 5
    The question states "both floats are neccesary". – Crescent Fresh Jun 19 '09 at 13:31
  • 8
    Yes, you are right and I agree. However I think Flo only mentioned this, because he thinks they are both! needed to get the desired layout and therefore my alternative solution. – merkuro Jun 19 '09 at 13:38
  • @merkuro: good point. I agree, ".right" does not need to be floated to get the desired effect. @Flo: can you confirm, must the content div be floated? Like for other reasons? – Crescent Fresh Jun 19 '09 at 13:41
  • might work i will try a little around with that, you got that reason right, and the float is nicer, but i figure it just wont work – Flo Jun 19 '09 at 13:44
  • 2
    Ahh jeah and i again see the reason why i changed it to float: Ie7 and Firefox do fine, but ie 5.5 and ie 6 start the margin at the right edge of the left div, so it has a 236px (the real width, 100 was an example) gap between both divs – Flo Jun 19 '09 at 13:57
  • ok as i dont really need a padding here i just let the margin be. The only Problem then is, that the first subdiv of the right div needs has a padding issue, but even if its dirty i will just use an empty div for left-padding (others work). css is sick. – Flo Jun 19 '09 at 14:20
  • Is there a way to do this when one is using `border-box` sizing? – Andrew Mao Aug 10 '13 at 01:53
  • I was doing the opposite, (right static, left filling the space). had to move the right element first in the html – Bishoy Hanna Sep 08 '20 at 02:00
103

The most cross-compatible way I've found of doing this is not very obvious. You need to remove the float from the second column, and apply overflow:hidden to it. Although this would seem to be hiding any content that goes outside of the div, it actually forces the div to stay within its parent.

Using your code, this is an example of how it could be done:

<div style="width: 100px; float: left;">menu</div>
<div style="overflow: hidden;">content</div>

Hope this is useful to anyone having this issue, it's what I found works the best for the site I was building, after trying to get it to adjust to other resolutions. Unfortunately, this doesn't to work if you include a right-floated div after the content as well, if anyone knows a good way to get that to work, with good IE compatibility, I'd be very happy to hear it.

New, better option using display: flex;

Now that the Flexbox model is fairly widely implemented, I'd actually recommend using it instead, since it allows much more flexibility with the layout. Here's a simple two-column like the original:

<div style="display: flex;">
    <div style="width: 100px;">menu</div>
    <div style="flex: 1;">content</div>
</div>

And here's a three-column with a flexible-width center column!

<div style="display: flex;">
    <div style="width: 100px;">menu</div>
    <div style="flex:1;">content</div>
    <div style="width: 100px;">sidebar</div>
</div>
Xavier J
  • 4,326
  • 1
  • 14
  • 25
alanaktion
  • 1,326
  • 1
  • 11
  • 18
  • After some further testing, it appears that you don't need to trigger hasLayout with "position: relative" for this to work in IE 6, I'm not sure about IE 5, but it's generally not a problem to include it anyway, just to be safe. – alanaktion Jun 20 '12 at 06:16
  • 1
    This answers seems unappreciated, but it is really good to know. This one does let you float, even with a floating element inside the div. I'ma google "block formatting context." right now. – Carlos Gil Oct 17 '12 at 02:23
  • The best way is to use a simple 2 cols table instead of wasting time adding tons of CSS not-cross-browser-compatibles tricks – Marco Demaio Nov 23 '12 at 10:22
  • @Marco I needed to use CSS for this as my design is responsive. Different screen sizes needed different layouts, so a table would not have worked. Also, this method appears to work in basically any browser anyone still uses. – alanaktion Nov 25 '12 at 22:24
  • @alanaktion: IMHO table width adapts perfectly to different screen sizes (``). Anyway if you feel more confortable entering into your house through the window rather than by using the door, it's your choice.
    – Marco Demaio Nov 28 '12 at 15:06
  • 1
    @MarcoDemaio, my point was that on a screen size where the smaller fixed column would be about as large as the main column, such as on a mobile device, I wanted the two columns to become full-width rows, which could not be done with tables unless I wanted to actually move content around with JavaScript. – alanaktion Dec 15 '12 at 17:21
  • I have a very similar situation and the answer worked well for me. I also needed some offset between the two divs. For some reason, adding margin-left to the 2nd div did not work (would love to know the theory behind this), but adding an inner div into the 2nd div, and setting that inner div's margin, worked just fine. – Eugene Osovetsky May 08 '13 at 13:19
  • IMHO the best answer as it is nearly dynamically. For my solution I have removed the width so it always fits for me. – webprogrammer Jan 08 '15 at 16:17
  • @MarcoDemaio, I agree with "alanaktion". Usually people who are looking for solutions for expanding divs to take the remaining width also want be able to change the div to full width on mobile devices. So on wide screen, the two divs are on one row and two columns, but on smaller screen, they want it to be two rows but one column. This cannot be simply implemented by table element. – lhrec_106 Nov 03 '15 at 23:21
31

Solution without fixing size on your margin

.content .right{
    overflow: auto; 
    background-color: red;
}

+1 for Merkuro, but if the size of the float changes your fixed margin will fail. If u use above CSS on the right div it will nicely change size with changing size on the left float. It is a bit more flexible like that. Check the fiddle here: http://jsfiddle.net/9ZHBK/144/

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • 2
    @alanaktion I took the unnecessary auto away. The difference is in the overflow value. Apparently `overflow: hidden` and `overflow auto` result in the same behavior. I also think people appreciate the Fiddle. – Wilt Oct 24 '14 at 07:16
  • If anyone wants to know why this works, see here: http://stackoverflow.com/a/1767270/2756409 – TylerH Nov 18 '15 at 16:07
  • I think this is better than merkuro's solution. – Lying_cat May 20 '19 at 06:14
6

Elements that are floated are taken out of the normal flow layout, and block elements, such as DIV's, no longer span the width of their parent. The rules change in this situation. Instead of reinventing the wheel, check out this site for some possible solutions to create the two column layout you are after: http://www.maxdesign.com.au/presentation/page_layouts/

Specifically, the "Liquid Two-Column layout".

Cheers!

Sean Aitken
  • 1,177
  • 1
  • 11
  • 23
5

this usage may solve your problem.

width: calc(100% - 100px);

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Content with Menu</title>
  <style>
    .content .left {
      float: left;
      width: 100px;
      background-color: green;
    }
    
    .content .right {
      float: left;
      width: calc(100% - 100px);
      background-color: red;
    }
  </style>
</head>

<body>
  <div class="content">
    <div class="left">
      <p>Hi, Flo!</p>
    </div>
    <div class="right">
      <p>is</p>
      <p>this</p>
      <p>what</p>
      <p>you are looking for?</p>
    </div>
  </div>
</body>

</html>
Dmitry
  • 6,716
  • 14
  • 37
  • 39
suathd
  • 51
  • 1
  • 1
4

This is an updated solution for HTML 5 if anyone is interested & not fond of "floating".

Table works great in this case as you can set the fixed width to the table & table-cell.

.content-container{
    display: table;
    width: 300px;
}

.content .right{
    display: table-cell;   
    background-color:green;
    width: 100px;
}

http://jsfiddle.net/EAEKc/596/ original source code from @merkuro

Snowie
  • 41
  • 2
  • +1 finally something that works with the fixed width element to the right, even if it doesnt technically use float. – Karthik T Mar 04 '14 at 10:16
  • +1 so totally yes. after years of struggling with floats and positions and tables, this is the right solution. the accepted solution propagates unsafe css. – horace Feb 13 '18 at 22:40
3

And based on merkuro's solution, if you would like maximize the one on the left, you should use:

<!DOCTYPE html>   
<html lang="en">     
    <head>              
        <meta "charset="UTF-8" />   
        <title>Content with Menu</title>                 
        <style>
            .content .left {
                margin-right: 100px;
                background-color: green;
            }
            .content .right {
                float: right;
                width: 100px;
                background-color: red;
            }
        </style>              
    </head>
    <body>        
        <div class="content">
            <div class="right">  
                <p>is</p>
                <p>this</p>
                <p>what</p>
                <p>you are looking for?</p>
            </div>
            <div class="left">
                <p>Hi, Flo!</p>
            </div>
        </div>
    </body>
</html>

Has not been tested on IE, so it may look broken on IE.

Timo Tijhof
  • 10,032
  • 6
  • 34
  • 48
kubilayeksioglu
  • 469
  • 1
  • 4
  • 14
1

The accepted answer might work, but I don't like the idea of overlapping margins. In HTML5, you would do this with display: flex;. It's a clean solution. Just set the width for one element and flex-grow: 1; for the dynamic element. An edited version of merkuros fiddle: https://jsfiddle.net/EAEKc/1499/

Christoph Bühler
  • 2,795
  • 2
  • 28
  • 43
0

This might work:

    div{
    display:inline-block;
    width:100%;
    float:left;
    }
kirtan-shah
  • 405
  • 7
  • 21
0

Hi there is an easy way with overflow hidden method on right element.

    .content .left {
        float:left;
        width:100px;
        background-color:green;
      }
      .content .right {
        overflow: hidden;
        background-color:red;
      }
<!DOCTYPE html>   
<html lang="en">     
    <head>      
           
        <title>Content Menu</title>         
          
    </head>
    <body>    
    <div class="content">
      <div class="left">
        <p>Hi, Flo! I am Left</p>
      </div>
      <div class="right">  
        <p>is</p>
        <p>this</p>
        <p>what</p>
        <p>you are looking for?</p>
        <p> It done with overflow hidden and result is same.</p>
      </div>
    </div>
    </body>
</html> 
Sanjib Debnath
  • 3,556
  • 2
  • 22
  • 16