tags:

views:

191

answers:

4

Hi, i have following HTML structure:

<div class="container">
   <div class="sidebar"></div>
   <div class="content"></div>
   <div class="subscript"></div>
</div>

I need following layout:

┌─────────┬───────────────────────┐
│         │                       │
│ sidebar │       content         │
│         │                       │
│         │                       │ 
├─────────┤                       │
│         │                       │
│    w    ├─────────┬─────────────┤
│         │subscript│      w      │
└─────────┴─────────┴─────────────┘

w - is white-space

Container must have fixed width and flexible height (must expand to fit its content)

Sidebar must have fixed width and height and be top-aligned.

Content must be on the right hand side of sidebar and take all free horizontal space. It must be vertical expandable, to fit its text

Subscript must be positioned right below content and be left-aligned with it. Also, it must be expanded horizontally, to fit its text (subscription)

How it can be done, using pure CSS?

A: 

That seems like something that could be implemented without too much trouble using 960.gs or other CSS grids out there without too much trouble.

You get the whitespace pretty well for free, so we'll ignore those.

You need to fix the width of sidebar, and it needs to have flexible height, so you just want a "cell" with a width (say 9 of the 24 columns). content then takes the remaining (e.g. 15) columns.

You need to prefix the subscript cell with some columns (the same as taken up by the sidebar cell), and then give subscript a fix number of columns.

This would involve some adjustments to your markup, something like this:

<div class="container_12">
   <div class="sidebar grid_9"></div>
   <div class="content grid_15"></div>
   <div class="clear"></div>
   <div class="subscript prefix_9 grid_7"></div>
   <div class="clear"></div>
</div>
Dominic Rodger
A: 

It looks like you could use a simple two column layout, with sidebar on the left and content on the right, which contains a child of subscript.

<style type="text/css">
    #container { width: 800px; overflow: hidden; } 
    #sidebar { width: 200px; float: left; }
    #content { width: 600px; float: right; }
    #subscript { display: inline; }
</style>

<div id="container">
    <div id="sidebar">
        <p>Left</p>
    </div>
    <div id="content">
        <p>Right</p>
        <div id="subscript">
            <p>Bottom</p>
        </div>
    </div>
 </div>
dazhall
`#subscript` and `#content` need to be two independent entities. There would be no whitespace next to `#subscript` if it was contained within `#content`.
dhabersack
Actually, i've solved the problem exactly the same way now. But this solution forces me to include subscript below content. When in future i will create a new skin for that, for example, place subscript below sidebar (author's avatar), i will get problems
AntonAL
I can't see a way of making it so that you'll be able to switch the position of the subscript div from the right to the left column. You could have it under the content div and use margins, but that only works if you know the sidebar will always be shorter than the content.
dazhall
A: 

I disagree with Dominic Rodger: a framework would be massive overkill for something that simple. Sure, you should have some kind of underlying grid, but you don't need the entirety of 960.gs, blueprint or any other "framework" that just pollutes your markup with unnecessary classes.

Frameworks require the use of predefined class names like .grid_2, .grid_12 and the like, eternally binding you to exactly that layout. This kind of defeats the decoupling of HTML and CSS: a redesign would require you to alter both your stylesheet AND your markup, which gets out of hand pretty quickly. I generally just wouldn't recommend it.

Your requirements are pretty basic and can do without frameworks just fine. Basically, all you have to do is add another container to your markup (also, you should use id instead of class if only one of these elements can exist on any given page):

<div id="container">
  <div id="sidebar">
  </div><!-- #sidebar -->

  <div id="main">
    <div id="content">
    </div><!-- #content -->

    <div id="subscript">
    </div><!-- #subscript -->
  </div><!-- #main -->
</div><!-- #container -->

(I use these comments to be able to match closing tags with their counterpart, feel free to omit them.)

Now all you have to do is float the elements according to your needs:

#container {
  overflow: hidden; /* don't collapse (floated children) */
  width: 960px; /* fixed width for entire site */
}

#sidebar {
  float: left; /* floating to the left in #container */
  height: 200px; /* fixed height */
  width: 320px; /* fixed width */
}

#main {
  float: right; /* floating to the right of #container */
  overflow: hidden; /* don't collapse (floated children) */
  width: 640px; /* width of #container - width of #sidebar */
}

#content {
  /* you shouldn't even need rules for this one */
}

#subscript {
  float: left; /* floated to be only as wide as needed for content */
}

divs are block elements, so unless they are either floated or have a fixed width, they take up all available space (see #content).

Now floated elements on the other hand don't have a height, so their parent container would just collapse (i.e. you wouldn't be able to fill the whitespace-areas with a color with #container { background: red }. To prevent #container from collapsing, overflow: hidden is required.

Basically, every time you float an element somewhere on your page, its parent container should have overflow: hidden (see #container and #main).

Obviously, you would have to change the dimensions according to your needs.

dhabersack
This markup forces me to keep subscript inside of content, what is not good, when i decide to place subscript below sidebar. See my comment to "dazhall"
AntonAL
+1  A: 

Advanced? Hardly. Most simply:

/* Fix page width. As per requirements, but questionable IMO. Why not liquid? */
.container { width: 750px; margin: 0 auto; }

/* Sidebar on left, other elements moved to the right */
.sidebar { float: left; width: 150px; }
.content, .subscript { margin-left: 150px; }

/* Make subscript shrink its width to fit its content */
.subscript { display: inline; }

This is cheating a bit in making the subscript inline in order to make its dimensions ‘shrink-to-fit’ its text. This might or might not be acceptable depending on what .subscript actually is.

There are a few other ways you can do that if you want .subscript to remain a block-display element. For example, float: left without an explicit width on the .subscript. Then you'd need either an explicit clear: left on a new element just before the end of the container, or, if you prefer not to change the markup at all, a self-clearing hack on .container (such as the overflow: hidden hack as mentioned by dhabersack; check the hasLayout fixes for that if you need IE6 support).

bobince