views:

3327

answers:

7

I've got a parent div floated left, with two child divs that I need to float right.

The parent div should (if I understand the spec correctly) be as wide as needed to contain the child divs, and this is how it behaves in Firefox et al.

In IE, the parent div expands to 100% width. This seems to be an issue with floated elements that have children floated right. Test page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">

<head>
<title>Float test</title>
</head>

<body>
<div style="border-top:solid 10px #0c0;float:left;">
    <div style="border-top:solid 10px #00c;float:right;">Tester 1</div>
    <div style="border-top:solid 10px #c0c;float:right;">Tester 2</div>
</div>
</body>

</html>

Unfortunately I can't fix the width of the child divs, so I can't set a fixed width on the parent.

Is there a CSS-only workaround to make the parent div as wide as the child divs?

+1  A: 

I couldn't come up with a CSS-only solution that fits your requirements, but if you want to use a JavaScript solution, maybe the following code can help? I did not alter the style of the divs, I only added the IDs main, sub1, and sub2 to your divs.

var myWidth = document.getElementById('sub1').offsetWidth + document.getElementById('sub2').offsetWidth;
document.getElementById('main').style.width = myWidth;
Daan
Sure, that should work JavaScript-wise—although, if I was going down the JavaScript route, I’d probably check whether Dean Edwards’ IE7 script fixed this particular issue (it fixes a bunch of others).
Paul D. Waite
A: 

What about using a single-cell table instead of the outer div? It may need some more work to have everything aligned properly, but the table doesn't expand.

Oz
Unfortunately, the table seems to force the child divs to wrap, so they're above each other instead of side to side.
Paul D. Waite
OK, how about nested tables? The outer table has float:left and one cell. In that cell there is an inner table with float:right and two cells. In each of the two cells is the content of your two inner divs. It's more involved than just the divs, but it works (on my XP/IE7, at least).
Oz
Ah, achieve the horizontal layout of the child divs with a table. Definitely a possibility, although technically you're not meant to use tables for layout (I think you fail a Web Content Accessibility Guideline if you do). Also, this is actually for a site that has two layouts: one left-to-right, and one right-to-left. Ideally we don't want to amend the HTML for the layouts (beyond having a class indicating which layout is in use), and using tables would put an end to that.
Paul D. Waite
A: 

Something you could start with is this:

<DIV style="BORDER: #0c0 10px solid; FLOAT: left; MARGIN-LEFT: 100%;">
<DIV style="BORDER: #00c 10px solid;FLOAT: right;">
Tester 1
</DIV>
<DIV style="BORDER: #c0c 10px solid;FLOAT: right;">
Tester 2
</DIV>
</DIV>

The result of that seems to be at least in the ballpark of what you're looking for. Obviously, you'd want to tweak it for your needs, and probably add some css logic to only apply it to browser < IE 7.

If that's not exactly what you're looking for, try playing with some negative margins.

Josh E
Unfortunately that doesn’t seem to work on my test page: the child divs wrap, so they're above each other instead of side to side. Also, at least in IE 7, the 100% margin takes up all the available space, so the parent div is positioned outside of its parent.
Paul D. Waite
whats with the caps?
David Murdoch
Sometimes IE 6 doesn’t hear properly unless you shout.
Paul D. Waite
wow I didn't even remember answering this question until I saw this new comment! I don't remember why those were in all caps, but I think Paul's got the gist of it :)
Josh E
A: 

Firstly, why aren't you using inline styles?

I'd use this to target IE with a separate css file:

<!--[if lt IE 7]>
<link rel="stylesheet" href="ie6.css" type="text/css" />
<![endif]-->

I know this isn't a direct question, but IE is ALWAYS a pain to deal with! Most designers/developers that I know will make a totally new stylesheet for IE.

Kevin Brown
Yup, sorry: the code above is just example code to highlight the bug. I used inline styles to make it slightly easier to see what’s going on.
Paul D. Waite
+5  A: 

I came up with a solution using text-align: right and display: inline.

Try this:

<div style="border-top:solid 10px #0c0; float: left;">
    <div style="margin-top: 10px; text-align: right;">
        <div style="border-top:solid 10px #c0c; display: inline;">Tester 2</div>
        <div style="border-top:solid 10px #00c; display: inline;">Tester 1</div>
    </div>
</div>

Notice I had to switch the order of the "tester" boxes in the markup to show up in the same way as your example. I think there is an alternative that margin-top on the new container, but I don't have time looking into right now.

If you want cleaner styling for all other browsers try this:

<div style="border-top:solid 10px #0c0; float: left;">
    <div style="float: right;">
        <div style="border-top:solid 10px #c0c; float: left;">Tester 2</div>
        <div style="border-top:solid 10px #00c; float: left;">Tester 1</div>
    </div>
</div>

There are some different issues that can come up when you want to layout stuff around those boxes. However, I think those issues will be much easier to solve than this one.

Hope this was helpful for you.

kaba
You might want to use `inline-block` instead of `inline`.
Casey Hope
inline-block does not work in ie6
meo
@meo: no, it doesn't, but it can be emulated with a few caveats: http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/
David Morrissey
Good stuff. The ordering thing is unfortunate, but there’s no way around that. There’s a solution below that gets inline-block working in IE 7 and 6, which better imitates the floated original, but credit is due here as well.
Paul D. Waite
@David M. +1 for the link, thank you!
meo
`inline-block` is an odd exception: you can make it work in IE 6, but not in Firefox 2.
Paul D. Waite
A: 

Hi, A very hacky but a CSS only solution that works okay in IE, chrome and FF.

I took kaba's solution - but the problem was, it works okay in IE but all the other browsers show a 4px space between the 2 child divs. The space remains as 4px even if the content on both the divs expand. So to fix that I've used IE conditional statements. I doesn't look like the best code in the world but it gets the job done.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">

<head>
<title>Float test</title>
</head>

<body>
<div style="border-top:solid 10px #0c0; float: left;">

    <div style="border-top:solid 10px #00c; text-align: right;">
        <div style="border-top:solid 10px #c0c; display: inline;">Tester2</div>

        <div style="border-top:solid 10px #00c; display: inline;margin-left:-4px">

        <!--[if gte IE 5]>
        <div style="border-top:solid 10px #00c; display: inline;margin-left:4px">
        <![endif]-->

         Tester1

        <!--[if gte IE 5]>
        </div>
        <![endif]-->


        </div>

    </div>
</div>
</body>
</html>
DMin
I see where you’re going; I think I prefer the `inline-block` solution for IE though, as that deals with the spacing issue without the need for negative margins.
Paul D. Waite
+3  A: 

Here's a solution which makes inline-block work on IE6 as at http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/ to make the elements behave more like right-floated <div>s:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>

<title>Float with inline-block test</title>

<style type="text/css">
    .container {
        border-top: solid 10px green;
        float: left;
    }

    .tester1,
    .tester2 {
        float: right;
    }

    .tester1 {
        border-top: solid 10px blue;
    }

    .tester2 {
        border-top: solid 10px purple;
    }
</style>

<!--[if lte IE 7]>
<style type="text/css">
    .container {
        text-align: right;
    }

    .tester1,
    .tester2 {
        float: none;
        zoom: 1; display: inline;/* display: inline-block; for block-level elements in IE 7 and 6. See http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/ */
    }
</style>
<![endif]-->

</head>

<body>
<div class="container">
    <div class="tester1">Tester 1</div>
    <div class="tester2">Tester 2</div>
</div>
</body>
</html>
David Morrissey
Aha! Yes, very good idea: `inline-block` is a closer imitation of the floats. We’re still left with the ordering problem, but unless we’re missing something, there’s no non-JavaScript way around that. Winner!
Paul D. Waite
Oh — also I use conditional comments so that the code for fixing IE 7 and 6 only gets applied in IE 7 and 6. I’ve rewritten your example accordingly. This avoids issues with `inline-block` in Firefox 2, and means that all IEs after 7 get the proper `float`-based code.
Paul D. Waite
Fair enough - I tried to add `float: right` to the test DIVs and `inline-block` to the container but that didn't work in IE6 - it seems that right floating made the elements 100% width no matter what. Oh well, at least the effect is possible anyway :-P
David Morrissey