Reputation: 27464
Is there a way to do this with CSS?
I want a page layout that looks like this:
+-----+-----------+---------------+
| | B | C |
| A | | |
| +-----------+---------------+
| | |
+-----+ |
| D |
| |
A is a sidebar menu. B is a picture. C is a title for the page, post date, maybe some other header-type info. And D is the main text of the article.
I can set a fixed width on A, but not on any of the other columns.
So I made A {width:200px; float:left;}, D is {margin-left: 200px; float:left;} and B & C are both float:left. Then in the HTML, after B & C I put a break clear=all.
This almost worked. But the catch was that it forced D to be, not just below B & C, but also below A. That is, it gave a gap between the bottom of B & C and the top of D.
If I remove the clear=all, then if B & C are not exactly the same height, the text from D starts directly under whichever is shorter.
So plan #2: I made B & both display: in-line block and eliminated the floats from them, then wrapped them in a larger block. Okay, that almost works. Except that if any line of C is too long to fit in screen_width - A - B, it gets displayed below B rather than the text wrapping to fit in the available space. I can make it wrap by putting a fixed width on it, but that would require me to make assumptions about the user's screen resolution that I don't want to make.
Any thoughts on how to do this? I'm thinking that what I really want is a way to say "float D below B & C but don't worry about A". But there is no "break clear=B+C", it's just clear=left, right, or all.
I could easily do this with tables but I'm trying to avoid having to include table tags in the HTML. I wanted a "pure CSS" solution.
Update
Here's a simplified version of my first try, stripped down to show just the relevant points. (I've cut out all the fonts and margins and everything else that is not necessary to demonstrate where it's breaking. I've put borders around the sections so you can see where they fall. I've stuck the CSS in a script tag in the HTML file instead of a separate CSS file. And I've stuck in a block of X's instead of an image.)
<html><title>3-Col Test</title>
<style type="text/css">
.sidebar, .head1, .head2, .body {border: 1px solid black;}
.sidebar {float:left; width: 200px;}
.head1 {float: left;}
.head2 {float: left;}
.body {margin-left: 202px; clear: both;}
</style>
<div class="sidebar">
<p>Menu</p>
<p>Item 1</p>
<p>Item 2</p>
<p>Item 3</p>
<p>Item 4</p>
<p>Item 5</p>
</div>
<div class="head1">
<p>XXXX<br/>
XXXX<br/>
XXXX<br/>
XXXX</p>
</div>
<div class="head2">
<h1>This is the title</h1>
<h2>This is the subtitle</h2>
</div>
<div class="body">
<p>To be, or not to be, that is the question. Whether tis nobler in the mind to suffer the
slings and arrows of outrageous fortune, or to bear arms against a sea of troubles, and by
opposing, end them. To die, to sleep, no more! And by a sleep to say we end the heartache,
and the thousand natural shocks that flesh is heir to. Tis a consummation devoutly to be
wished. To die, to sleep, to sleep ... aye, there's the rub. For in that sleep of death
what dreams may come when we have shuffled off this mortal coil must give us pause.
There's the respect that makes calamity of so long life. Etc.</p>
</div>
</html>
Note that this results in the content area being forced below the sidebar.
So okay, keeping the same HTML, I changed the style sheet to this:
<style type="text/css">
.sidebar, .head1, .head2, .body {border: 1px solid black;}
.sidebar {float:left; width: 200px;}
.head1 {display: inline-block;}
.head2 {display: inline-block;}
.body {margin-left: 202px;}
</style>
This almost works. The one catch is that if you shrink the browser window until it is no longer wide enough for the sidebar plus head1 plus the longest line in head2, instead of head2 wrapping, it gets pushed below head1. What I want to happen is that the width of head2 shrinks.
Oh, and note that you have to have some text in the blocks to see the issue. You can't just slap a "width: 100px" on it to force it to take some space, because the results of putting a width on it are very different from having text that takes up actual space. I'm pulling the image and the text from a database, the images are different sizes for different pages and of course the lengths of the titles are different for different pages.
Upvotes: 0
Views: 64
Reputation: 96
If you add this to your code:
<script>
var height = document.getElementById("c").offsetHeight;
document.getElementById("b").style.height = height +"px";
</script>
you should be able to get rid of the break clear = all
.
PS: Replace the "c
" and "b
" with whatever id
s your divs have.
Upvotes: 1
Reputation: 430
So you need to think of the box method only larger. So A with be a box and B,C,D will all be in the same box. Then B and C will be a smaller box etc.
<div class="container">
<div class="A">
</div>
<div class="mainContent">
<div class="headerArea">
<div class="B">
</div>
<div class="C">
</div>
</div>
<div class="D">
</div>
See it here http://jsfiddle.net/Zy7Bq/
Upvotes: 1