Issue 101 Resolution

This email is an attempt to resolve Issue 101
(http://wiki.csswg.org/spec/css2.1#issue-101), brought up by dbaron's
email last year
(http://lists.w3.org/Archives/Public/www-style/2009Jan/0445.html) and
exemplified by his testcases
(http://dbaron.org/css/test/2009/float-outside-tests/).

Summary of the issue
====================

The positions of floats are defined by a set of constraints defined in
CSS2.1, section 9.5.1
(http://www.w3.org/TR/CSS21/visuren.html#float-position).  These
constraints are defined to involve all the floats in the same BFC.  In
practice, however, all browsers ignore some floats in the BFC in
certain circumstances when satisfying rules 3 and 7, and IE7 similarly
ignores some floats in the BFC in certain circumstances when
satisfying rule 5.

Browsers appear to interoperate in their breaking of rules 3 and 7, so
my proposal below will alter the text to accomodate their quirks, as
it seems likely that web content has come to rely on these quirks (in
particular, they appear to involve behavior that would be exercised in
float-based layouts, which means changing them would create decent
breakage.


Testcases Demonstrating The Problem
===================================

For rule 3, it appears that browsers consistently only consider floats
that intersect the parent of the float in question.  Test cases
follow:

Basic behavior, correct in all browsers:

<!doctype html>
<div id=container>
  <div id=rightfloat></div>
  <div id=leftparent>
    <div id=leftfloat></div>
  </div>
</div>
<style>
#container {
  width: 600px;
  height: 600px;
  background: yellow;
}
#rightfloat {
  width: 200px;
  height: 100px;
  background: green;
  float: right;
}
#leftfloat {
  width: 450px;
  height: 100px;
  background: blue;
  float: left;
}
#leftparent {
  width: 410px;
  height: 300px;
  border: 3px dotted black;
}
</style>

Broken behavior, consistent across all browsers:

<!doctype html>
<div id=container>
  <div id=rightfloat></div>
  <div id=leftparent>
    <div id=leftfloat></div>
  </div>
</div>
<style>
#container {
  width: 600px;
  height: 400px;
  background: yellow;
}
#rightfloat {
  width: 200px;
  height: 100px;
  background: green;
  float: right;
}
#leftfloat {
  width: 450px;
  height: 100px;
  background: blue;
  float: left;
}
#leftparent {
  width: 390px;
  height: 250px;
  border: 3px dotted black;
}
</style>

The only difference between these two cases is that #leftfloat's
parent does or doesn't intersect #rightfloat.  When it doesn't, then
they don't consider #rightfloat for the purpose of satisfying rule 3
when positioning #leftfloat.

One final case, showing that it is the parent that matters here:

<!doctype html>
<div id=container>
  <div id=rightfloat></div>
  <div id=leftgrandparent>
    <div id=leftparent>
      <div id=leftfloat></div>
    </div>
  </div>
</div>
<style>
#container {
  width: 600px;
  height: 400px;
  background: yellow;
}
#rightfloat {
  width: 200px;
  height: 100px;
  background: green;
  float: right;
}
#leftfloat {
  width: 450px;
  height: 100px;
  background: blue;
  float: left;
}
#leftparent {
  width: 390px;
  height: 250px;
  border: 3px dotted black;
}
#leftgrandparent {
  width: 410px;
  height: 300px;
  border: 3px dashed gray;
}
</style>


Suggested Change
================

Current text:

# The right outer edge of a left-floating box may not
# be to the right of the left outer edge of any
# right-floating box that is to the right of it.
# Analogous rules hold for right-floating elements.

Suggested text:

| The right outer edge of a left-floating box may not
| be to the right of the left outer edge of any
| right-floating box that is to the right of it and
| that intersects the left-floating box's parent box.
| Analogous rules hold for right-floating elements.



Suggested fixes for Rule 7 to follow in a separate email.

~TJ

Received on Tuesday, 5 October 2010 23:56:22 UTC