Fluid layout with optional sideboxes

I want a layout with three boxes (two optional) like this:

[side box 1] [ main content

[side box 2] . main content ]

or

[ main content spans 100% if side boxes aren't provided ]

I want the main content box to span the entire height and width available in #load (minus margins) except if the side boxes are there, then I want it to only span up until those boxes (and their right margin).

My CSS:

#load {
    margin: 10px;
    height: 100%;
    min-width: 1080px;
}
#primary,#secondaryOne,#secondaryTwo {
    border-radius: 8px;
    background: #f5f5f5;
    border: 1px solid #ccc;
}
#primary {
    float: right;
    height: inherit;
    width: 75%;
    height:500px;
    background:red;
}
#secondaryOne,#secondaryTwo {
    min-width: 250px;
    max-width: 300px;
    height: 220px;
    margin-right: 10px;
    width: 20%;
    clear:left;
    float:left;
}
#secondaryTwo {
    margin-top: 10px;
}

Simple HTML

<div id='load'>
    <div id='primary'></div>
    <div id='secondaryOne'></div>
    <div id='secondaryTwo'></div>
</div>

JSFiddle

Problems

  • *SOLVED*Making #primary span the entire width if the sideboxes are missing.

  • *SOLVED*Is there a way to line the two sideboxes (#secondaryOne,#secondaryTwo) on the left side of #primary without nesting them in a separate div? If I use float: left on them, they line side by side, if I don't float them, the #primary generates below them, not beside them.

  • Solutions

  • Problem #1 was solved by joeytje50 using the secondary + primary tags and placing the secondary side boxes before the primary in HTML.
  • Problem #2 was solved in more than one way. The way I chose so that the secondary tags were placed together and before the primary was by NoobEditor using clear: left and a negative margin-top .
  • The solution can be found at: http://jsfiddle.net/v4cvv/67/

    The main part of the solution is:

    #primary {
        width: 100%;
    }
    #secondaryOne + #primary, #secondaryTwo + #primary {
        margin-top: -221px;
        width: 75%;
    }
    

    Alternate Solution

    One problem I found with the above solution, is it requires the two boxes and them to be the same height. A solution around this is by grouping the boxes in their own div. This solution is:

    HTML

    <div id='load'>
        <div id="sideboxes">
            <div id="boxOne" class="box"></div>
            <div id="boxTwo" class="box"></div>
            <div id="boxThree" class="box"></div>
        </div>
        <div id="primary" class="box"></div>
    </div>
    

    CSS

    .box {
        border-radius: 8px;
        background: #f5f5f5;
        border: 1px solid #fff;
    }
    #primary {
        float: right;
        display:block;
        height: 97%;
        width: 100%;
    }
    #sideboxes + #primary {
        width: 75%;
    }
    #sideboxes {
        float: left;
        height: 97%;
        width: 23%;
        margin-right: 10px;
    }
    #sideboxes .box {
        float: left;
        height: 220px;
        margin-bottom: 10px;
        width: 100%;
    }
    

    The alternate solution no longer requires clear and can be extended for other uses. You may now also have 1, 2, 3, or however many boxes you want in the sideboxes div.

    Thanks all for their help.


    To answer your question about the primary box being 100% width when the secondary boxes are not there, you could do the following:

    #primary {width:100%;}
    .secondary + #primary {width:75%;}
    

    If you put that CSS code at the bottom of your stylesheet, and then put the primary div tag after your first secondary div tag, then it'll by default be 100% wide, unless there's an element that has class="secondary" . This won't change anything about the position the div is rendered, but it will fix your problem.

    Alternatively, if your secondary divs are possibly hidden instead of not being there, you could do this:

    #primary, .secondary.hidden + #primary {width:100%;}
    .secondary + #primary {width:75%;}
    

    That is, assuming you hide the secondary tabs via a class such as .hidden .

    Here is a working version that becomes 100% width when the secondaries are removed, but still is 75% width when there is a .secondary element before it.


    Keeping your HTML markup smae, here is the solution for your problem : demo

    CSS

    html.body {
        height:100%;
    }
    #load {
        margin: 10px;
        height: 100%;
        width:100%;
    }
    
    #primary, #secondaryOne, #secondaryTwo {
        border-radius: 8px;
        background: #f5f5f5;
        border: 1px solid #ccc;
    }
    #primary {
        float: right;
        display:block;
        height: 100%;
        max-width:100%;;
        width: 68%;
        margin-top:-70%; /* this is the key */
    }
    #secondaryOne, #secondaryTwo {
        width:30%;
        height: 220px;
        margin-right: 10px;
    
    }
    #secondaryTwo {
        margin-top: 10px;
    }
    

    Problem #1

    To get your #primary div to adapt it's width, you can use jquery to verify the presence of the .secondary divs and to set the an other width to the #primary div.

    With .secondary demo

    without .secondary demo

    JQUERY:

    if ($('.secondary').length){
        $('#primary').css('width', '75%');  
    }
    

    Problem #2

    You can use clear:left; and by changing the order of the divs in your html markup you will have your 2 divs stacked on the left and your content div on the right.

    FIDDLE

    HTML:

    <div id='load'>
        <div id='primary'></div>
        <div id='secondaryOne' class="secondary"></div>
        <div id='secondaryTwo' class="secondary"></div>
    </div>
    

    CSS :

    .secondary{
        clear:left;
        float:left;
    }
    
    链接地址: http://www.djcxy.com/p/76442.html

    上一篇: 如何返回一个泛型类?

    下一篇: 具有可选侧箱的流体布局