响应式2列CSS布局,包括固定宽度的侧边栏?

时间:2013-03-15 16:14:51

标签: html css layout fluid

无法在任何地方找到解决方案(我猜这一定是一个非常常见的问题)。

我正在使用侧边栏创建响应式设计,其中侧边栏需要具有200px的固定宽度并且具有未知高度。我怎样才能使主要内容区占据所有剩余的宽度,而不会出现任何不当行为。

我最接近它的是以下内容,但问题是侧边栏可以与页脚重叠。任何人都可以建议修复我的代码,或与我分享一些有效的代码吗?

            * {
            padding: 0;
            margin: 0;
            outline: 0;
            -moz-box-sizing: content-box;
            -webkit-box-sizing: content-box;
            box-sizing: content-box;
        }
        body {
            background: orange;
        }
        #container {
            max-width: 1000px;
            min-width: 768px;
            margin: 0 auto;
            background: yellow;
            position: relative;
            height: 100%;
        }
        #header {
            background: purple;
            color: white;
            text-align: center;
            padding: 10px;
        }
        #main {
            position: relative;
        }
        aside {
            background: blue;
            width: 200px;
            color: white;

            position: absolute;
            top: 0;

            /* change this to "right: 0;" if you want the aside on the right. Also, change the "margin-left" code, below. */
            left: 0;

            padding-top: 20px;
            padding-bottom: 20px;

            padding-left: 10px; /* If you change this value, remember to change the margin-left value of #primary */
            padding-right: 10px; /* ditto */
        }
        #primary {
            background: red;

            /* change this to margin-right if you want the aside on the right. Also change the "left" code, above. */
            margin-left: 220px; /* aside_width + aside_left_padding + aside_right_padding = 200px + 10px + 10px */
            padding: 1em; /* whatever */
        }
        #footer {
            background: green;
            color: white;
            padding: 10px;
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
        }

        <div id="container">
        <div id="header">
            <h1>LAYOUT TEST #2</h1>
        </div>
        <div id="main">
            <div id="primary">
                <h2>THIS IS THE MAIN CONTENT ** THIS IS THE MAIN CONTENT ** THIS IS THE MAIN CONTENT</h2>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <h2>sub heading</h2>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <h2>sub heading</h2>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
            </div>
            <aside>
                <h3>navigation (left)</h3>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
                <p>lorem ipsum</p>
            </aside>
        </div>
        <div id="footer">
            <h1>LAYOUT TEST #2</h1>
        </div>
    </div>

5 个答案:

答案 0 :(得分:8)

1 =使用flexbox:http://jsfiddle.net/rudiedirkx/CjWbv/2/

#main {
    display: flex;
}
#primary {
    background: #bbb;
    flex: 1;
}
aside {
    background: #ddd;
    flex: 0 0 200px;
}

2 =使用calc()http://jsfiddle.net/rudiedirkx/CjWbv/

#main:after { clearfix here }
#primary {
    float: left;
    background: #bbb;
    width: calc(100% - 200px);
}
aside {
    background: #ddd;
    float: right;
    width: 200px;
}

两者都需要旧版浏览器的回退(以及供应商前缀)。从其他答案中选择。

答案 1 :(得分:4)

我认为所有这些position: absolute的方法并不是最好的方法。

  1. 您希望拥有一个包含max-widthmargin: 0 auto的容器元素。不确定为什么你也想要一个min-width;你当然可以。

  2. 您自动放置的任何块元素都会占用父元素的所有width。因此,标题页脚没有问题,只需将它们放在正确的位置即可正常渲染。

  3. 正如您所做的那样,请为主要部分使用容器元素。由于元素是从左向右呈现的,因此您可能希望在aside之前编写#primary

  4. float: left应用于您需要的固定宽度的aside

  5. 主要内容#primary元素将自动占用剩余空间(或仅应用width: auto注意: 剩余空间是父元素的剩余空间,因此,如果您在父元素上设置min-width,则不要指望#primary更窄!

  6. 现在您将遇到问题:容器元素#main将无法获得正确的高度。 That's because of an issue with float。要强制父元素达到其浮动子元素的高度,请使用overflow: hidden

  7. 你应该准备好了。这是slightly modified version of your code

答案 2 :(得分:4)

在我们获得flexbox之前,我认为最好的方法就是使用css display: table;。您需要将容器设置为display: table;,然后将每个列设置为display: table-cell;。这将消除使用浮点数或任何其他JS魔法的需要。此外,这可以回到IE8。我知道使用“&#34; table&#34;布局,但只是尝试一下。

Check out this link for more info.

Here is an updated version of your code.

编辑:示例代码

html:假设有这个标记

<div id="main">
    <div id="sidebar"></div>
    <div id="content"></div>
</div>

<强>的CSS:

#main {
    display: table;
    width: 100%;
}
#sidebar {
    display: table-cell;
    width: 200px;
}
#content {
    display: table-cell;
    /* no need to specify width. 
     * width will auto fill remaining width of parent `table` #main.
     * so 100% - 200px */
}

答案 3 :(得分:0)

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

这会阻止边栏行为不端。

答案 4 :(得分:0)

您可以通过向margin-bottom: FOOTER_HEIGHT添加aside来修复此问题,或者使用以下方法:

<div id="container">
    <div id="header">
        YOUR_HEADER
    </div>
    <div id="body>
        <div id="sidebar">
            YOUR_SIDE_BAR_CONTENT
        </div>
        <div id="main">
            YOUR_CONTENT
        </div>
        <br />
    </div>
    <div id="footer">
        YOUR_FOOTER
    </div>
</div>

CSS:

#sidebar {
    width: ...;
    height: ...;
    float: right;
}
#main {
    margin-right: WIDTH_OF_SIDE_BAR;
}
#body > br {
    clear: both;
}