styke
styke

Reputation: 2174

Expand the parent div of floated elements to fit their total width?

I am trying to put together a page that will have a horizontally scrolling pane on it - here is an example of the layout I am looking to get: enter image description here The content is dynamically added and has varying dimensions. .

Here's some HTML:

<div class="container">
    <div class="inner">
        <div></div>
        <div></div>
        <div></div>
    </div>
</div>

Base CSS:

.container {
    width: 100%;
    height: 100%;
}

.container .inner {
    position: relative 
}

.container .inner > div {
    float: left;
}

Currently the only way I can get it working is by setting an explicit width for .inner. Otherwise, closest I've come is this answer, but it's still pretty far off my desired effect. Is it possible to achieve what I'm looking for with HTML/CSS alone or will I have to resort to javascript?

Upvotes: 10

Views: 6377

Answers (6)

Tomas
Tomas

Reputation: 59597

Is this what you expected? http://jsfiddle.net/GE5Hf/4/

enter image description here

Just use white-space: nowrap together with the inline-block and vertical-align: top. You don't need your .inner div to achieve the desired effect - just use one container with overflow-x: auto:

<div class="container">
        <div id="i1"></div>
        <div id="i2"></div>
        <div id="i3"></div>
</div>

CSS

.container {
    width: 100%;
    height: 100%;
    overflow-x: auto;
    white-space: nowrap; 
}

.container > div {
    display:inline-block;
    vertical-align: top;
}

Note: it is better to use overflow-x: auto than scroll just in case the scrollbar is not needed.

EDIT: We were speculating whether you actually need that .inner div. If you need it, you can just add it back with no special style required: http://jsfiddle.net/GE5Hf/5/

EDIT 2: To have the .inner div the width as its children, simply give it display:inline-block: http://jsfiddle.net/GE5Hf/8/

EDIT 3: Tried what you suggested in your last deleted comment, i.e. remove the fixed width of the child. This was really tricky, I had to wrap each child element to special div with display: table-cell and the inner div gets dislay: table-row: http://jsfiddle.net/GE5Hf/12/

Upvotes: 8

ER144
ER144

Reputation: 690

Take a look at this, no script was necessary:

.container {
    width: 300px;
    height: 100%;

    background-color: silver;
}

.container .inner {
    white-space:nowrap;
    padding: 10px;
    overflow-x: scroll;

    background-color: gray;
}

.container .inner > div {
    display: inline-block;
    vertical-align:top;

    background-color: red;
    border: 1px solid black;
}

Demo: http://jsfiddle.net/er144/4FLWK/

Upvotes: 0

Mathijs Flietstra
Mathijs Flietstra

Reputation: 12974

This can be done using CSS only.

Here's a jsFiddle.

The solution is to set position: relative; on .container, which creates a new stacking context inside the .container, setting position: absolute; and white-space: nowrap; on .inner ensures that .inner's content div's will not wrap to the next line and that .inner will grow with its content, adding display: inline-block; and vertical-align: top; on the .inner > div's ensures that they are treated as inline elements and stick to the top of their containing element.

I believe this is what you are after, I have checked on the latest versions of IE, Chrome, Firefox and Safari and it works fine on all of them, I have no reason to believe that it won't work on older versions.

HTML

<div class="container">
    <div class="inner">
        <div></div>
        <div></div>
        <div></div>
    </div>
</div>

CSS

.container {
    position: relative;
    width: 220px;
    height: 400px;
    overflow-x: scroll;
}
.container .inner {
    position: absolute;
    white-space: nowrap;
    background-color: #FFCCFF;
}
.container .inner > div {
    vertical-align: top;
    display: inline-block;
    margin: 10px;
}

Upvotes: 1

n1kkou
n1kkou

Reputation: 3142

@styke You can do that with display:inline-block(and some font-size on .inner > div) and font-size:0 to div.inner.

Provided fiddle here: http://jsfiddle.net/zepva/4/ , ignore the colors, i used them only for demonstration

font-size:0 will remove the gaps between the element using display:inline-block so when you will get the total width of the div.inner, that will be the sum of children divs

Upvotes: 0

vals
vals

Reputation: 64264

Is position: relative mandatory ?

.container .inner {
    position: fixed;
    overflow: hidden;
}

demo

Upvotes: 0

user3160799
user3160799

Reputation: 23

display:inline-block, with vertical-align:top , that way your text wont fall at the bottom of the container.

.container .inner > div {
    display:inline-block;
vertical-align:top;
}

Upvotes: -1

Related Questions