开发者

Separate content from style using CSS

I know this is supposed to be the fundamental reason why CSS exists but I contend that CSS fails miserably at it. It is your job to prove me wrong.

Take this example:

<html>
<head>
    <title>div test</title>
    <style>
        html {
            font: bold 20px Arial;
            color: white;
        }

        #container {
            border: 1px dotted black;
            width: 90%;
        }

        .blue {
            background-color: blue;
            opacity:0.5;
            float: left;
        }

        .red {
            background-color: red;      
            opacity:0.5;
        }
    </style>
</head>
<body>
    <div id="container">
        <div class="blue">Here is some text</div><div class="red">&nbsp</div>
    </div>
</body>
</html>

And make it so

  1. the red and blue div share the same line
  2. the red and blue div do not overlap
  3. the red and blue divs combined width is 100% of #container
  4. the blue div automatically occupies as much space as it needs to accommodate the text that is inside of it, no more or l开发者_如何学编程ess.
  5. the red div automatically grows/shrinks to occupy the remaining space in #container so that #3 and #4 are both satisfied

I've been trying to do this - what should be - incredibly simple thing for about 3 hours now with no success. The only way that I can do it is by intertwining style and content and adjusting the width of each div based on the amount of text that is in the blue div.


From the code you posted with your description it seems like your code should work. I verified it here:

http://jsfiddle.net/3nSwT/1/

(played with the colors just for clarification)

What's wrong with that scenario that you want fixed?

EDIT:

This code works as you expect. I think. :)

http://jsfiddle.net/3nSwT/3/


Here is a table based approach that I think does what you want.

<div id="container">
    <table><tr>
        <td class="red">Here is some text in the red div.</td>
        <td  class="blue">
        Some text in blue div. Some text in blue div. Some text in blue div. 
         Some text in blue div.     
        </td>
     </tr>
 </table>

 td.red { white-space: nowrap; width: 1%;   background: red;   }
 td.blue { background: blue; }

The only slight kludge is forcing the width of the red column to 1% so it always takes up just exactly the necessary space.

If you can drop IE6 support, and need everything to be "semantic", you can turn the construct into a series of display: table-* div elements:

    <div class="table"><div class="tr">
    <div class="td red">Here is some text in the red div.</div>
    <div class="td blue">
    Some text in blue div. Some text in blue div. Some text in blue div. 
    Some text in blue div.     
    </div>
  </div>

.table { display: table }
.tr { display: table-row }
.td { display: table-cell }

But I personally find the resulting div soup horrible, and the <table> tag a much cleaner and nicer solution, even though it's not the semantically correct choice.


This used to be hard, but is now fairly simple using the method Pekka alluded to. To be more specific:

Remove the float from .blue and add these lines:

#container {
    border: 1px dotted black;
    width: 90%;
    display: table;
}

.red, .blue {
    display: table-cell;
}

and this matches all your criteria, including the implicit criteria that when you resize the window to smaller than the #container width, it starts wrapping text to the size of the box, and that if you put longer text in one side versus the other, browsers will resize accordingly.

Works even in IE8. It's part of CSS2.1, and IE8 implemented that pretty thoroughly, but ignored CSS3. IE7 and IE6 need hacks. See http://www.gunlaug.no/contents/wd_additions_22.html for more info on this method and others, including hacks for IE6/7. This is the only part that I would consider tricky.

One other gotcha for IE8 - make sure you have a standards doctype in your HTML. If you don't, this WILL fail. My new favorite is the HTML5 doctype - <!doctype html>

Using this method rather than old-fashioned table opens up the ability to re-use the same HTML for a mobile site and have .red and .blue appear below each other if needed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜