akonsu
akonsu

Reputation: 29538

how to stack elements using CSS

I have four div elements in a container:

<div id="container">
    <div id="top"></div>
    <div id="bottom-left"></div>
    <div id="bottom-center"></div>
    <div id="fill"></div>
</div>

I need to position them as follows:

The top edge of the top element should be at the top edge of the container. The bottom-left element should be in the bottom-left corner of the container. The bottom-center element should be centered at the bottom of the container. The fill element will have a fixed width and should take the remaining space vertically.

The problem is that the fill element will contain arbitrary text and can be of arbitrary height. I need to put it under the top element and place the bottom-center under it. the bottom edge of bottom-left must align with the bottom of bottom-center.

I tried absolute positioning, but it does not work for arbitrary text length.

I would appreciate any help.

EDIT: here is jsfiddle code: http://jsfiddle.net/gCg29/ it creates the layout that I want to achieve but with a table.

how to get rid of the table and have the same functionality? notice that if the width of the browser window is insufficient then the elements do not overlap. also notice that if the text grows in length then the left-bottom and under-text elements stick to the text's bottom.

                           +-----------------------+
                           |  top (fixed size)     |
                           +-----------------------+
                    +-----------------------------------+
                    |                                   |
                    |                   fill            |
                    |        (arbitrary height,         |
+-----------------+ |         fixed width)              |
|                 | |                                   |
|  bottom-left    | |                                   |
|  (fixed size)   | |                                   |
|                 | |                                   |
|                 | |                                   |
|                 | |                                   |
|                 | |                                   |
|                 | +-----------------------------------+
|                 |      +--------------------------+
|                 |      |bottom-center (fixed size)|
+-----------------+      +--------------------------+

Upvotes: 1

Views: 1249

Answers (4)

user123444555621
user123444555621

Reputation: 152956

Here you go:

#container {
    position: relative;
    overflow: hidden;
}

#fill {
    margin: 0 auto 50px; /* 50px = height of bottom-center */
    width: 300px;
}

#top, #bottom-center {
    height: 50px;
    width: 200px;
    margin: 0 auto;
}

#bottom-center {
    position: absolute;
    bottom: 0;
    left: 50%;
    margin-left: -100px; /* - width / 2 */
}

#bottom-left {
    position: absolute;
    left: 0;
    bottom: 0;
}

http://jsfiddle.net/nXqQr/1/

The important part is overflow: hidden; on the container which will make the margin on #fill extend its size, so that #bottom-center fits in.

Upvotes: 1

SapphireSun
SapphireSun

Reputation: 9388

I have a horrible idea for you. Essentially you're asking for the page gravity to be inverted. Thus:

jQuery('body').css('transform', 'rotate(180deg)');
jQuery(everythingelse).css('-webkit-transform', 'rotate(180deg)');

That will flip the page and then reflip all the elements in place so that they display right-side-up but in the same position after the invert.

Of course, you'll want to support more than just css3 browsers, and I'm sure this is horribly expensive, but I figured it would be a fun, if not entirely useful, answer. :)

Upvotes: 1

mrtsherman
mrtsherman

Reputation: 39872

It is a lot of css, but I think this is what you want. Quite a few things going on here:

  1. set #container to position: relative so that you can absolutely position the #bottom-left and #bottom-center
  2. give #top and #fill margin: 0 auto so that they center on the page
  3. #bottom-center also gets left: 50% to bring to center. Then margin-left: -width to bring it fully center
  4. #container gets padding-bottom: 75px so that #fill doesn't overlap the bottom div

http://jsfiddle.net/34Jpx/2/

div { 
    border: 1px dotted lightgray; 
}
div#container { 
    text-align: center; 
    width: 100%;  
    position: relative;
    padding-bottom: 75px; 
}
div#top { 
    height: 50px; 
    width: 400px; 
    margin: 0 auto; 
    background: lightgreen;  
}
div#fill { 
    height: 200px; 
    width: 500px; 
    margin: 0 auto;  
    background: lightblue; 
    border: 2px solid red; 
}
div#bottom-left {
    position: absolute;
    bottom: 0;
    height: 200px;
    width: 150px;
    background: gray;
    z-index: 99;
}
div#bottom-center {
    position: absolute;
    bottom: 0;
    left: 50%;
    margin-left: -200px;
    width: 400px;
    height: 50px;
    background: lightyellow;
    z-index: 100;
}​

Upvotes: 1

mastazi
mastazi

Reputation: 1672

Create an invisible div (let's call it inv-div-1) which contains only bottom-left and another one (inv-div-2) which contains all the rest, give them both a float:left; positioning. in the html file inv-div-1 must be positioned before inv-div-2.

Upvotes: 0

Related Questions