开发者

Absolutely positioned parent and float:right child stretches

开发者 https://www.devze.com 2022-12-08 15:55 出处:网络
In IE6, IE7 and FF2 the .outer div below is stretching out to the right edge of the document. Here is a complete test case:

In IE6, IE7 and FF2 the .outer div below is stretching out to the right edge of the document. Here is a complete test case:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <style>
  .outer { position:absolute; border:1px solid red; }
  .outer .floater { float:right; }
  </style>
</head>
<body>
  <div class="outer">
      <div class="floater">Lorem ipsum</div>
  </div>
</body>

As I understand position:absolute, the outer div should be removed from the flow of the document and (without a width specified) should take up the minimal amount of space needed to display its contents. However float:right on any child breaks this.

Expected output (IE8, FF3+, Chrome 2+, Safari 4, Opera 9+):

Absolutely positioned parent and float:right child stretches

Actual output (IE6, IE7, FF2):

Absolutely positioned parent and float:right child stretches

How do I get the outer div to not stretch? This is only happening in IE6, IE7 and Firefox 2.

Requirements:

  • .outer cannot have a width set (it must be left as "auto")
  • .outer must remain absolutely positioned
  • .floater must remain floated to the right

Update:

I've reproduced the behavior as a "real world" example using jQuery dialog. The characteristics are开发者_运维百科 the same:

  1. There is an absolutely positioned div (i.e. the dialog container, jQuery-UI creates this)
  2. The div from 1) has width="auto"
  3. There is an element inside this dialog that is floated to the right.

See it here. Again, IE6, IE7 and FF2 are the only problematic browsers.

This replicates the conditions inside my application. I tried boiling down the problem to what you see above this Update, but I'm getting the sense that people could use a real-world example where my requirements make sense. I hope I've done this.


Apologies for the negative answer, but I don't think there's a way around this. The CSS implementation for those older browsers is simply incorrect when it comes to the case you've outlined, and I don't believe there's any way to hack around this via other CSS properties within the constraints you've given us. As a limited fix you could in theory set a max-width on the outer div to limit the degree to which it stretches... but unfortunately max-width isn't supported in all of the 'old' browsers mentioned anyway.

I know it's not what you're wanting to hear, but I think you're going to have to bite the bullet and either change the markup or relax your style requirements (e.g. give up on the float).


You need this to stop it overflowing the edge of the page:

body {margin:0;padding:0}

However it will still take up the whole width of the page, it just won't overflow


float should have a width in this case, and from another point of view you should have top:0;left:0; for the positioned element they should not kept like this. note: this is logic only for the design if you wont the code please ask :)


.outer { overflow:hidden; clear:right; position:absolute; border:1px solid red; } .outer .floater { float:right; } Lorem ipsum It's really simple, you only must set the overflow and clear properties to every object that has floated childs.

If the parent is also floated, you only need to set your object to float.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <style>
  .outer { overflow:hidden; clear:right; position:absolute; border:1px solid red; }
  .outer .floater { float:right; }
  .outer .floater .child { float:right; }
  </style>
</head>
<body>
  <div class="outer">
      <div class="floater">Lorem ipsum 
                <span class="child">HI!</span>
      </div>
  </div>
</body>

If got any questions, just ask!

Regards & GL. ;)


If you change float:right to clear:right, you will get the requested output in your example, but it will not work as expected if you actually have content outside the floater div.


The css2 spec has some information about how a user agent “should” compute width, but reality is not the spec: http://www.w3.org/TR/CSS2/visudet.html#Computing_widths_and_margins.

I definitely recommend going with a strict DOCTYPE instead of a transitional one, http://www.w3.org/QA/2002/04/valid-dtd-list.html#DTD.

Without specifying a margin for your .outer div, the user agent will determine the width using width: auto, which looks like it varies depending on the user agent.

Why do you not want to specify a width for the parent div?

If you can, specify a width for the parent div, even if it's width: 100%. You may want to also place * { margin: 0; padding: 0; } in the stylesheet to avoid user agent differences in those attributes, especially if you specify width as 100% for .outer.

This may be trivial, but you should be able to shorten the statement .outer .floater to just .floater.

If you need the “shrink-to-fit” effect around the inner floater and need to maintain float-right, then add direction: rtl; to the .floater class; otherwise you should be able to use float-left;


Yeah for absolute positioned elements, width is undefined (as is top and left). Some browsers do elastic table-style width in this case, and some do 100% width, but it's up to the browser. Best to be explicit in this case.

Tables are really the only good way to get elastic width in a cross-browser fashion. A single celled table is just as good as a DIV as long as your remember the cellspacing=0.

<table cellspacing=0 cellpadding=0 style="position:absolute;top:0;right:0">
    <tr><td>Lorem ipsum</td></tr>
</table>


Your .outer div is empty, therefore we get different results. As soon as you add content to it, atleast in my test it seems to work exactly the same (my test was Chrome 3.0 as the 'working as intended', and IE7 as the broken one).


<div class="outer">
  <div class="floater">Lorem ipsum</div>
Lorem ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit 
</div>

Since you mentioned the .outer div has content, try removing the float div from it and it still gets very similar output.

Edit

To reproduce your code without stretching (understand here that you'll have different problems to deal after you have this working equally, like margins/padding/vertical stretch) you can introduce a relative 'wrapper'.


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

  body { margin: 0; }
  #outer { position: absolute; border:1px solid red; }
  #wrapper { position: relative; }
  #floater { position: absolute; right:0; border: 1px blue solid;  }

  </style>
</head>
<body>

  <div id="outer">

    <div id="wrapper"> 
        <div id="floater">Lorem ipsumX</div> 
    </div>

    Lorem ipsum dolor sit amet consequetur elitipsum dolor sit amet consequetur elit
  </div>
</body>


Since I see in your working example you're using jquery you could calculate the width of the container first, before floating the floater like so:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
  <style>
  .outer { position:absolute; border:1px solid red;}
  </style>
</head>
<body>
  <div class="outer">
    <div class="floater">Lorem ipsum</div>
  </div>

  <script type="text/javascript">
    $(".outer")
      .css("width", $(".outer").width());
    $(".floater")
      .css("float", "right");
  </script>

</body>

Putting a width on the outer div makes it behave in all the other browsers


I don't have IE6, IE7, or FF2 to test on, so I'm going to take a stab in the dark on this one. If my memory serves me, you're going to want to float:left on .outer. This will minimize the width of .outer while maintaining your inner div's proportions.

0

精彩评论

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