简体   繁体   English

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

[英]Responsive 2-column CSS layout including sidebar with fixed width?

Cannot find a solution for this (what I'm guessing must be a pretty common problem) anywhere.在任何地方都找不到解决方案(我猜这一定是一个非常普遍的问题)。

I am creating a responsive design with a sidebar, where the sidebar needs to have a fixed width of 200px and has unknown height.我正在创建一个带有侧边栏的响应式设计,其中侧边栏需要具有 200 像素的固定宽度并且高度未知。 How can I make it so the main content area takes up all the remaining width, without anything misbehaving.我怎样才能使主要内容区域占据所有剩余的宽度,而不会出现任何行为不端。

The closest I've come to it is the following, but the problem with it is that the sidebar can overlap the footer.我最接近它的是以下内容,但它的问题是侧边栏可以与页脚重叠。 Can anyone suggest a fix for my code, or share with me some code that works?任何人都可以建议修复我的代码,或者与我分享一些有效的代码吗?

            * {
            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>

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

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

2 = with calc() : http://jsfiddle.net/rudiedirkx/CjWbv/ 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;
}

Both will require a fallback for older browsers (and vendor prefixing).两者都需要旧浏览器的回退(和供应商前缀)。 Take your pick from the other answers.从其他答案中选择。

I think the approach with all those position: absolute is not the best one.我认为所有这些position: absolute的方法position: absolute不是最好的。

  1. You want to have a container element with a max-width and margin: 0 auto .您想要一个具有max-widthmargin: 0 auto的容器元素。 Not sure why you might want a min-width as well;不知道为什么你可能也想要一个min-width you can of course.你当然可以。

  2. Any block element that you put automatically takes all the width of the parent element.您放置的任何块元素都会自动占用父元素的所有width Hence, there's no problem with the header and footer , just position them in the right spot and they will render properly.因此,页眉页脚没有问题,只需将它们放在正确的位置,它们就会正确呈现。

  3. As you correctly did, use a container element for your main section.正如您所做的那样,为您的主要部分使用容器元素。 Since the elements are rendered left to right, you might want to write the aside before the #primary .由于元素是从左到右呈现的,您可能希望在#primary之前写下aside

  4. Apply float: left to the aside with your desired fixed-width.应用float: left以您所需的固定宽度aside

  5. The main content #primary element will take the remaining space automatically (or just apply width: auto . Note: the remaining space is the remaining space of the parent element, so, if you set the min-width on the parent element, don't expect your #primary to be narrower!主要内容#primary元素将自动占用剩余空间(或仅应用width: auto注意:剩余空间是父元素的剩余空间,因此,如果您在父元素上设置min-width ,请不要#primary期望您的#primary更窄!

  6. Now you will have a problem: the container element #main will not get the proper height.现在您将遇到一个问题:容器元素#main将无法获得正确的高度。 That's because of an issue with float . 那是因为float存在问题 To force a parent element to get to the height of its floated children, use overflow: hidden .要强制父元素达到其浮动子元素的高度,请使用overflow: hidden

You should be ready to go.你应该准备好了。 Here is a slightly modified version of your code .这是您的代码稍微修改版本

Until we get flexbox, I believe the best way to do what you are looking for is to simply use the css display: table;在我们获得 flexbox 之前,我相信最好的方法就是简单地使用 css display: table; . . You will need to set the container to display: table;您需要将容器设置为display: table; , and then each of the columns, just set to display: table-cell; ,然后是每一列,只需设置为display: table-cell; . . This will eliminate the need for using floats or any other JS magic.这将消除使用浮点数或任何其他 JS 魔法的需要。 Also, this works back to IE8.此外,这也适用于 IE8。 I know it feels sketchy using anything with the word "table" for layout, but just give it a try.我知道使用带有“表格”一词的任何内容进行布局感觉很粗略,但请尝试一下。

Check out this link for more info. 查看此链接了解更多信息。

Here is an updated version of your code.这是您的代码的更新版本。

EDIT: example code编辑:示例代码

html: Assuming this markup html:假设这个标记

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

css: 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 */
}
#main { position: relative; overflow:hidden;}

这会阻止侧边栏的行为不端。

You can fix it with adding margin-bottom: FOOTER_HEIGHT to the aside or use the following method instead:您可以通过在aside添加margin-bottom: FOOTER_HEIGHT来修复它,或者使用以下方法:

<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>

And the CSS:和 CSS:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM