IE/Win: relatively positioned parent and floated child – disappearance

The box's position is calculated according to the normal flow (this is called the position in normal flow). Then the box is offset relative to its normal position. When a box B is relatively positioned, the position of the following box is calculated as though B were not offset.

(CSS2.1 9.3.1).

Different kinds of disappearance

Some bugs cause elements to disappear in IE. One can distinguish between rendering issues which are instable, and those which keep the elements vanished:

This article focuses on the latter problem. When elements disappear irrevocably in IE, then most probably three players are involved: positioning, floating, and clearing. Even absolutely positioned elements may vanish under certain circumstances: floats and disappearing absolutely positioned divs. The following examples look at relatively positioned parents and their floated children.

Example: A floated child hides behind its non-layout parent

The relatively positioned parent contains the float, due to the clearing element. The floated child has “layout”, but the positioned parent has not. The parent is offset to the left. A mostly transparent background image allows for inspecting behind the layer of the parent. By hovering the link, the float expands so that it touches the clearing element.

r.p. parent

floated child

~ expand ~

Sed diam ante, commodo non, pharetra semper, laoreet in, nibh. Morbi pharetra turpis sed nisl. Cura bitur non enim. Etiam tempus quam. Sed auctor lorem et nunc. Sed ultri cies, pede sit amet eleifend rhoncus, lacus purus viverra sem, sed venenatis mi metus eu justo. Prae sent vesti bulum fringilla tellus. Sed egestas erat vitae ante. Cras fringilla risus non neque. Nunc mauris. Suspendisse tempus consec tetuer erat.


clearing hr

CSS and HTML of the example above.
  1. .rp_parent { 
  2. position: relative;  
  3. left: -5em;  
  4. margin: 2em 0 0 5em;  
  5. background: url(transparent.gif);  
  6. border: 2px solid #00f; 
  7. padding: 0.5em; 
  8.  
  9. .fl_child { 
  10. float: right;  
  11. width: 50%;  
  12. background: maroon;  
  13. padding: 0.5em 
  14.  
  15. hr.clear { 
  16. display: block;  
  17. clear: both;  
  18.  
  19. a.expand { 
  20. display: block; 
  21. text-align: center; 
  22. zoom: 1; /* max clickable area */ 
  23.  
  24. a.expand:hover { 
  25. padding-top: 20em; 
  26.  
  27. .lorem{ 
  28. text-align: justify; 
  1. <div class="rp_parent"> 
  2. <h3>r.p. parent</h3> 
  3.  
  4. <div class="fl_child"> 
  5. <h3>floated child</h3> 
  6. <a class="expand" href="#">~ expand ~</a> 
  7. </div> 
  8.  
  9. <p class="lorem">Sed diam ... erat.</p> 
  10.  
  11. <hr class="clear" /> 
  12. <p>clearing hr</p> 
  13. </div> 
IE6 screenshot: normal state
the float does not adjoin the clear
IE6 screenshot: hovered state
the float is expanded and adjoins the clear
IE7 Mar 20 screenshot: normal state
the float does not adjoin the clear
IE7 Mar 20 screenshot: hovered state (same in IE7b3)
the float is expanded and adjoins the clear

Description

In IE6, the parent is drawn after the floating child is, the float is painted over. The lines of the paragraph inside the parent wrap at the expected places. However, the floating child didn't get the offset.

Whether the r. p. parent respects its left margin or not, it depends on whether the parent is expanded by its floated child or not, i.e., if the solid clearer adjoins the float or not (IE6+IE7Mar20).

Example: A relatively positioned parent ceases rendering and disappears

Basically the same setting as above, but: there is no content between the float and the clearer — with the exception of the link. And the :active pseudo-class of the link removes itself via display:none (this is to simulate the problem when there is no content disconnecting the clear from the float).

floated child

~ don't click ~

clearing hr

CSS and HTML of the example above.
  1. .rp_parent { 
  2. position: relative;  
  3. left: -5em;  
  4. margin: 2em 0 0 5em;  
  5. background: url(transparent.gif);  
  6. border: 2px solid #00f; 
  7. padding: 0.5em; 
  8.  
  9. .fl_child { 
  10. float: right;  
  11. width: 50%;  
  12. background: maroon;  
  13. padding: 0.5em 
  14.  
  15. hr.clear { 
  16. display: block;  
  17. clear: both;  
  18.  
  19. a.donot:active { 
  20. display: none; 
  1. <div class="rp_parent"> 
  2. <div class="fl_child"> 
  3. <h3>floated child</h3> 
  4. </div> 
  5. <a class="donot" href="#">~ don't click ~</a> 
  6. <hr class="clear" /> 
  7. <p>clearing hr</p> 
  8. </div> 
IE6 screenshot: active state
the link is clicked
IE7 Mar 20 screenshot: active state
the link is clicked

Description

IE7beta3: The upper border is missing. When scrolling out of sight and back, sometimes a 1em line next to the float is not painted (missing blue border and dotted background). The relatively positioned parent and all its child elements disappear if the link is clicked.

IE6: same problem, but the float keeps visible (bug in the bug).

Unrelated, but irritating: IE keeps the active-state of the link, even when the user leaves the page and is coming back.

A workaround?

We could trigger “hasLayout” by adding, for example, a dimension or zoom: 1 to the parent. But this urges the parent to enclose the float automatically, even if there is no clearing element. This is the auto-containing bug in IE/Win: By design, “layout” establishes a new block formatting context.

If applying hasLayout is not an option in certain design situations, IE6 and IE7 may render more stable if the float does not join the clearer in the source code, i.e. by separating them with an additional element.

Conclusion

A relatively positioned container with a floating child needs “layout” to gain control over the float. Otherwise, the layering, the offset and the width formatting may give unexpected results.

Created, and last updated:
Mar 30, 2005
Jun 29, 2006
Author:
Ingo Chao
Contact:
spam.info@satzansatz.de