I'd like to create a webpage layout with the sidebar to the right and the main content flowing around the sidebar.
Requirements:
This could be achieved without the third requirement: if the sidebar is before the main content in the markup and is within the same containing element, a simple right float does the job. A sidebar before the main content in the markup is not an option here. The sidebar will contain supplemental information and adverts. If this is before the main content in the markup it will be annoying to CSSless browsers and screenreader users (even with 'skip to ...' links).
This could be achieved without the fourth requirement. If the sidebar had a fixed height I could put a containing element before the main content, float it right and give it a suitable width and height and then use absolute positioning to put the sidebar on top of the pre-made space.
Example markup (without CSS, relevant bits only):
<body>
<div id="content">
<p>
Lorem ipsum ....
</p>
<p>
Pellentesque ....
</p>
<div id="sidebar">
/* has some form of fixed width */
</div>
</div>
</body>
Example layout:
alt text http://webignition.net/images/layoutexample.png
I'm not sure if this is possible. I'm happy to accept an authoritative answer stating that this cannot be achieved. If this can't be achieved I'd appreciate an explanation - knowing why it can't be achieved is much more valuable than just being told it can't.
Update: I'm happy to see answers that don't meet all of the five requirements, so long as an answer states which requirement is being ignored plus the consequences (pros and cons) of ignoring the requirement. I can then make an informed compromise.
Update 2: I can't ignore requirement 3 - the sidebar cannot precede the content.
Simple floating w/ opposite source order just can't be done (w/o CSS3 draft specs). The pragmatic approach is to first build a nice layout that supports your desired source order. HTML:
<div id="content" class="noJs">
<div id="floatSpace"></div>
<p>Lorem ipsum ....</p>
<p>Pellentesque ....</p>
<div id="sidebar">content</div>
</div>
CSS:
#content {position:relative;}
#sidebar {width:150px; position:absolute; top:0; right:0;}
.noJs {padding-right:150px;}
.noJs #floatSpace {display:none;}
.js #floatSpace {float:right; width:150px;}
This satisfies all but 1 and 2. Now, we add the JS:
$(function () {
// make floatSpace the same height as sidebar
$('#floatSpace').height($('#sidebar').height());
// trigger alternate layout
$('#content')[0].className = 'js';
});
This will make the contents float around #floatSpace, and #sidebar will remain positioned on top of it. This is better than moving #sidebar because source order remains the same (for screenreaders that support Javascript, etc.).
Here's a JSFiddle of this in action. This layout does come with the unfortunate requirement of keeping the floatSpace height in sync with the sidebar height. If the sidebar is dynamic or has lazy-loading content, you must re-sync.
I believe you're gonna have to change the order for this, putting the sidebar first. Then, use CSS's float
property (without changing order, div#sidebar
would end up below the paragraphs vs next to them). div#sidebar
should stretch as needed for height.
CSS:
#sidebar {
float: right;
width: 50px;
}
HTML:
<body>
<div id="content">
<div id="sidebar">
/* has some form of fixed width */
</div>
<!-- paragraphs -->
</div>
</body>
@Jon Cram [comment]
Ok...nvm. You stated your own answer and rejected it at the same time.
You can't float an element around other elements that are defined before it. The browser has to be able to answer "float around what?" And it looks to the next element to start, continuing as far as necessary.
Ok, here's another answer then, since we can ignore one of the requirements, skip out the first requirement where the content wraps underneath the sidebar.
#sidebar {
float: left;
width: 100px;
}
#actualContent {
width: 700px;
float: left;
}
The only change to your code is that you have to put your actual content in another wrapper.
<div id="content">
<div id="actualContent">
<p>...</p>
<p>...</p>
</div>
<div id="sidebar">
<p>...</p>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With