tags:

views:

538

answers:

3

So I'm really trying to use divs exclusively, as opposed to using tables for layout purposes, but I'm still getting stuck here and there. Today I have one of those cases.

Consider the following markup:

<div style="width:943px;margin:0px auto;height:auto">
    <div style="display:block;clear:both">
        <div style="float:left;display:block-inline;clear:none;background:url(tl.png);width:26px;height:25px"></div>
        <div style="float:left;display:block-inline;clear:none;background:url(t.png) repeat-x;width:865px;height:25px"></div>
        <div style="float:left;display:block-inline;clear:none;background:url(tr.png);width:26px;height:25px"></div>
    </div>
    <div style="height:auto;display:block;clear:both">
        <div style="float:left;width:26px;display:block-inline;clear:none;background:url(l.png) repeat-y;width:26px;height:100%"></div>
        <div style="padding:0 15px;height:100%;float:left;width:835px;display:block-inline;background:#FFF;clear:none;">
            <br />
            Some text heeere.
            <br />
            Some more text heeere.
        </div>
        <div style="float:left;width:26px;display:block-inline;clear:none;background:url(r.png) repeat-y;width:26px;height:100%"></div>
    </div>
    <div style="display:block;clear:both">
        <div style="float:left;display:block-inline;clear:none;background:url(bl.png);width:26px;height:25px"></div>
        <div style="float:left;display:block-inline;clear:none;background:url(b.png) repeat-x;width:865px;height:25px"></div>
        <div style="float:left;display:block-inline;clear:none;background:url(br.png);width:26px;height:25px"></div>
    </div>
</div>

Now this is what's its doing:

alt text

Note that it's going slightly past the page height.

This is what I want it to do:

alt text

I want it to fluidly "fit" to the text without me specifying a height. It seems that the problem lies with the two side divs that won't work unless you specify the height as 100%. Is there maybe another/easier way to do this?

Thanks!

+3  A: 

If the data is tabular (meaning it falls into proper rows and columns semantically, not just visually) you should use a table.

If it is just the layout you prefer, there is a css rule that might help, but not for all browsers:

div.column {
   display: table-column;
}

div.cell {
  display: table-cell;
}

This assumes you assign all of your "column" divs the class of column and your "cell" divs the class of cell.

The full list of display options for table-like behavior is:

table   
table-caption
table-cell
table-column
table-column-group
table-footer-group
table-header-group
table-row
table-row-group
Anthony
This seems to be a very hacky way of going about things. The general idea is to use divs for layout, and tables for tabular data. The above is pure layout, and not tabular data, thus I want to use divs. I know how to use table to accomplish this, but I want to learn how to use divs to accomplish this in a more correct way.
Constant M
How is using a CSS rule hacky? Especially when it's explicitly designed to offer table layout (what you want) without actually using tables (your exact goal)??? You are going to have to make a compromise somewhere, as there is no correct way that is going to work on every browser and for every screen size. I thought I'd offer you the one that the w3c designed specifically for your needs. Using floats is hacky, as floats were intended for having text wrap around images, not for doing inline-block. Which, by the way, is yet another "hacky" solution you might want to consider.
Anthony
I am for using tables over div's any day, if just to spite the widespread (and wrong) cliché that tables are evil per se. But in this case, I find the wish to work without tables, and to achieve the desired effect without `table-*` properties, totally valid. In addition, `table-row` and consorts (as Anthony himself points out) will give you trouble in the IE family.
Pekka
@Anthony `table-*` and `display: inline-block` are not really options as long as IE6 and 7 are still around IMO http://www.quirksmode.org/css/display.html Whereas `float` works fine.
Pekka
I am definitely in the "tables are evil" camp, unless tables are actually what you are presenting, which it sounds like Constant has. If the design would make NO sense without table design, then it's probably a table. But if you just want the divs to line up horizontally, just use `display: inline-block;`
Anthony
You can use conditional comments to deal with IE7 and earlier.
Anthony
@Pekka, Foats work fine, but the SO requested the "most correct" way, which means non-compliant browsers are "less correct" by default. Plus I'm mostly reacting to the term "hacky". Floats may work across more browsers, but so do tables. Don't ask for knowledge and then call it hacky because you haven't heard of it.
Anthony
@Anthony I am against using tables for layout too, but I find it horrible when people start displaying *tabular data* in `div`s because tables are "out". I just wanted to point out that this is not the case in the OP's question. Regarding correctness, my view is that if it doesn't work in IE6 or at least 7, it, sadly, is not a solution - yet. It'll look different the day IE6 is gone for good.
Pekka
Personally, I would probably opt for something other than the `table-*` just because I hate getting feedback from people on IE as it is a bitter reminder people still use IE. But I thought the SO would benefit from knowing that there was a CSS rule explicitly for what they wanted. I don't understand why everyone thinks there is a "secret" way to do CSS correctly that won't involve IE hacks, javascript, etc, when there are tons of sites dedicated to the many methods and approaches to dealing with cross-browser CSS and IE hacks, like quirksmode.
Anthony
@Pekka, we are in agreement then. I get **really** PO'd when I see people post "don't use tables" or whatever in a legit question about how to style tables. Tables are not evil, they just have a sordid past.
Anthony
@Anthony, fair enough. I referred to it as being "hacky" as it isn't completely cross browser compatible, but then inline-block isn't either. I think my original question might be a bit confusing. I don't want divs to explicitly act like tables. It would be much easier to just use tables in this case. Referring to my original question, I asked for advice on how to have the "center part" fit fluidly to the contained text as illustrated. Any ideas on how to get this done looking at the current markup? Thanks for the input
Constant M
I can't actually figure out what the OP is asking for here, but it sure doesn't leap out at me as being a data table, and therefore I think this is an excellent answer. Curiously, the one thing that is semantically wrong with the mark-up in the question is the use of <br>. I wonder why we get so hung up with <table> and not with <br>?
Alohci
@Alochi - Here here! down with break tags! I have definitly found myself backed into a corner on this one, forced to choose between splitting a line with `<span>` just to avoid a `<br />` only to swallow that sometimes even `<br />` has it's place (but not nearly as often as it's used).
Anthony
@Pekka - I totally agree. Until the CSS standard has a non-hacky way for setting explicit vertical and horizontal alignment (not just text) of block elements I will continue to use tables. It's such a waste of time to get div's to layout in a precise way which is a 5 second job with a table.
James
One of the things I find curious though, is the idea that using tables for layout is easy. I spent a good 3/4 hour this afternoon getting a table to position itself as I wanted it in IE6 (it was fine in Firefox), something that would have been trivial with a div. (The table is generated by a third party engine that we're stuck with.)
Alohci
@Alohci - The problem with that argument is that just about everything we do relating to IE6 and CSS is a hack...hardly a rational for a good coding practice since IE6 is soon to lick the dust.
James
@James. Sure - though I generally find that IE7 is little better. It typically has a whole set of *different* layout problems to be worked around. I long for the time when all IE users are at V8 or later. At which point Anthony's answer above will work perfectly cross-browser.
Alohci
+3  A: 

If the width is going to be fixed why not use a single background image for each of the three "rows":

<style type="text/css">
.container    {width:943px;}
.header       {background:url(header.png) no-repeat;}
.body         {background:url(body.png) repeat-y;}
.footer       {background:url(footer.png) repeat-none;}
</style>

<div class="container">
    <div class="header">&nbsp:</div>
    <div class="body">
        <br />
        Some text heeere.
        <br />
        Some more text heeere.
    </div>
    <div class="footer">&nbsp;</div>
</div>

The divs will naturally stack and expand to the full width of the container.

chprpipr
aaah thank you. This is the type of answer I was looking for. It was just a way of solving the problem. All the other guys were perfectly correct, but they were thinking waaaay too technical! Thanks!
Constant M
+1  A: 

You asked for it, so here goes. This is my hand crafted, cross-browser, standards-compliant method of doing image borders on flexible containers.

I've assumed an image border size of 16px here, you will need to adjust this to suit. Also, for clarity in the absense of images I have added borders. Thse should be removed, obviously.

Demo.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Borders</title>
<style>
.outer {
    position:relative;
    float: left;
    border: 1px solid blue
}
.inner {
    border: 1px solid green
}
.tl, .tm, .tr, .ml, .mr, .bl, .bm, .br {
    border: 1px solid red;
    margin: 0;
    padding: 0;
}
.tm, .bm, .tl, .tr, .bl, .br {
    height: 16px
}
.tl, .tr, .bl, .br {
    width: 16px
}
.tm, .bm {
    height: 16px;
    margin: 0 0px
}
.tm {
    background-repeat:repeat-x;
    margin: 0 16px
}
.bm {
    background-repeat:repeat-x;
    margin: 0 16px
}
.tl {
    position: absolute;
    top: 0;
    left: 0;
}
.tr {
    position: absolute;
    top: 0;
    right: 0;
}
.bl {
    position: absolute;
    left: 0;
}
.br {
    position: absolute;
    right: 0;
}
.ml {
    padding-left: 16px;
    background-repeat:repeat-y
}
.mr {
    padding-right: 16px;
    background-repeat:repeat-y;
    background-position: 100% 0
}
</style>
</head>
<body>
<div class="outer">
    <div class="tm">
        <div class="tl"></div>
        <div class="tr"></div>
    </div>
    <div class="ml">
        <div class="mr">
            <div class="inner">
                <h2>Lorem</h2>
                <p>Ipsum dolor</p>
            </div>
        </div>
    </div>
    <div class="bm" >
        <div class="bl"></div>
        <div class="br"></div>
    </div>
</div>
</body>
</html>
graphicdivine
Thanks! This is what I was looking for! Another way of solving the problem.
Constant M
A pleasure. Not a million miles away from your original code, really.
graphicdivine