问题
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. 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:
I think the approach with all those position: absolute is not the best one.
You want to have a container element with a
max-widthandmargin: 0 auto. Not sure why you might want amin-widthas well; you can of course.Any block element that you put automatically takes all the
widthof the parent element. Hence, there's no problem with the header and footer, just position them in the right spot and they will render properly.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
asidebefore the#primary.Apply
float: leftto theasidewith your desired fixed-width.The main content
#primaryelement will take the remaining space automatically (or just applywidth: auto. Note: the remaining space is the remaining space of the parent element, so, if you set themin-widthon the parent element, don't expect your#primaryto be narrower!Now you will have a problem: the container element
#mainwill not get the proper height. That's because of an issue with float. To force a parent element to get to the height of its floated children, useoverflow: hidden.
You should be ready to go. Here is a slightly modified version of your code.
回答2:
1 = With 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/
#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.
回答3:
Until we get flexbox, I believe the best way to do what you are looking for is to simply use the css display: table;. You will need to set the container to display: table;, and then each of the columns, just set to display: table-cell;. This will eliminate the need for using floats or any other JS magic. Also, this works back to 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
<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 */
}
回答4:
#main { position: relative; overflow:hidden;}
This stops the sidebar misbehaving.
回答5:
You can fix it with adding margin-bottom: FOOTER_HEIGHT to the aside or use the following method instead:
<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:
#sidebar {
width: ...;
height: ...;
float: right;
}
#main {
margin-right: WIDTH_OF_SIDE_BAR;
}
#body > br {
clear: both;
}
来源:https://stackoverflow.com/questions/15437201/responsive-2-column-css-layout-including-sidebar-with-fixed-width