44

I'm wondering what the best way to go about doing this is...

I have 3 divs:

  • a div#container with width=100%; that holds 2 inner divs

  • a div#inner_left with width changing dynamically, but no wider than 200px (will hold a product image)

  • an div#inner_right where the width should fill the rest of the space in the container (will contain text to describe the product shown)

    #container {
       width:100%
    }
    
    #inner_left {
        display:inline-block:
        max-width:200px;
    }
    
    #inner_right {
        display:inline-block;
        width:100%; 
    }
    

The problem is that the div#inner_right creates a line break and fills the entire width. How can I make them align next to each other, with the right div accounting for the width taken by the left div (which changes dynamically?). I've gotten this to work other ways, but I'm looking for a clean solution...

Any help for a CSS noob is much appreciated!

Ulf Gjerdingen
  • 1,414
  • 3
  • 16
  • 20
thedeepfield
  • 6,138
  • 25
  • 72
  • 107

8 Answers8

65

I haven't really seen a good solution in the answers here. So I'll share mine.

Best way to do this is by using the table-cell option in CSS. One important thing to add is a 'min-width' to the element that has a pixel width.

Example:

<div id="left">
    Left
</div>
<div id="right">
    right
</div>

CSS:

#left {
    display: table-cell;
    min-width: 160px;
}
#right {
    display: table-cell;
    width: 100%;
    vertical-align: top;
}
messivanio
  • 2,263
  • 18
  • 24
w00
  • 26,172
  • 30
  • 101
  • 147
  • 3
    This was exactly what I needed to do. I changed it around and made my right div fixed, while the left dynamically filling the gap. – Andreas Oct 30 '12 at 12:39
  • 1
    Its about time i found a simple version of this. To my left cell I added `white-space: nowrap` – Valamas Aug 13 '13 at 04:06
  • 25
    Table-cell styles are by far the most reliable way to accomplish things like this across different browsers and platforms... almost as reliable as using tables. It's funny how using tables for layout is seen as such a negative thing nowadays, when all of the fancy new CSS grid libraries like Foundation and Bootstrap are just trying their best to emulate what tables have done basically since W3C introduced them. It's time for a native grid system to be introduced to HTML. – Gavin Sep 11 '13 at 10:37
  • This should be definitly the selected answer, because, this works - the selected answer does not really work good. – r00tandy Feb 04 '15 at 16:01
  • 1
    THANK YOU. I have been wrestling with this for ages. This did it for me. – felwithe Dec 28 '15 at 12:51
17

Have a look at "liquid layouts" it can describe what you're talking about.

You're probably looking for this one.

In your example, try setting your display to inline. However, you won't technically be able to use block level elements in it, so have a look at the links I posted above. :)

The problem with setting the width to 100% if you're using floats is that it is considered 100% of the container, so it won't work either since the 100% includes the left div's width.

Edit: Here is the example of the other answer, I've edited it to include the html/css from the example site above for simplicity's sake.

I'll also include it below:

HTML

<div id="contentwrapper">
    <div id="contentcolumn">
        <div class="innertube"><b>Content Column: <em>Fluid</em></b></div>
    </div>
</div>
<div id="leftcolumn">
    <div class="innertube"><b>Left Column: <em>200px</em></b></div>
</div>

CSS

#contentwrapper{
float: left;
width: 100%;
}

#contentcolumn{
margin-left: 200px; /*Set left margin to LeftColumnWidth*/
}

#leftcolumn{
float: left;
width: 200px; /*Width of left column*/
margin-left: -100%;
background: #C8FC98;
}
5

This can be accomplished using Flex-Box, which has been introduced with CSS3 and according to Can I use is cross-browser.

.container { 
  display: flex; 
}

.left {
  width: 100px; /* or leave it undefined */
}

.right { 
  flex-grow: 1;
}

/* some styling */
.container {height: 90vh}
.left {background: gray}
.right {background: red}
<div class="container">

  <div class="left">100px</div>
  <div class="right">Rest</div>
  
</div>
arc
  • 4,553
  • 5
  • 34
  • 43
2

So even though I wanted to do this with CSS only, I ended up just using tables...

thedeepfield
  • 6,138
  • 25
  • 72
  • 107
0

This is based on @w00 's answer. +1 friend.

My situation was when I wanted to show a couple of icons next to a label. I use the fluid class for that which is where the nowrap comes in. This is so the icons appear on the same line.

.sidebyside-left-fixed, .sidebyside-right-fixed
{
    display: table-cell;
    width: 100%;
}

.sidebyside-left-fluid , .sidebyside-right-fluid
{
    display: table-cell;
    vertical-align: top;
    white-space: nowrap;
}
Valamas
  • 24,169
  • 25
  • 107
  • 177
0

Here is an easy method to achieve this, and this is something that's quite frequently needed. It's also tested to works with all browsers, including the very old ones (let me know if it doesn't on any).

Link to a sample: https://jsfiddle.net/collinsethans/jdgduw6a/

Here's the HTML part:

<div class="wrapper">
    <div class="left">
        Left Box
    </div>

    <div class="right">
        Right Box
    </div>

</div>

And the corresponding SCSS:

.wrapper {
    position: relative;
}

$left_width: 200px;
.left {
    position: absolute;
    left: 0px;
    width: $left_width;
}
.right {
    margin-left: $left_width;
}

If you are not using any CSS preprocessors, then replace the $left_width with your value (200px here).

Credit: This is based on http://htmldog.com/examples/pagelayout2/. There are several other useful ones there.

Ethan
  • 4,915
  • 1
  • 28
  • 36
0

Use floating:

#container{
width:100%
}

#inner_left{
float:left;
max-width:200px;
}

#inner_right{
float:left;
width:100%; 
}

Edit: have a read a this, it's a nice little guide : quirksmode

Damien Pirsy
  • 25,319
  • 8
  • 70
  • 77
0

you need to provide position:absolute style property to both your div's

tristan625
  • 13
  • 1
  • 3