[css3-images] object-fit interactions with min/max sizing

I just did some CVS archaeology for Tab on why the definitions for object-fit
interact with the min/max properties the way they do in the definitions agreed
to by the CSSWG. You can see that text in old drafts of CSS3 Paged Media:
   http://dev.w3.org/cvsweb/~checkout~/csswg/css3-page/Overview.html?rev=1.71;content-type=text%2Fhtml#img-fit

The text was added originally on 14 November 2006, based on proposed text
from mid-October 2006, following discussions across the F2F and the internal
mailing list. (This was before the CSSWG decision to work in public.)
The discussion at the F2F was triggered by something I posted at
   http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/
which I will reproduce here for archiving.

====== min-max-replaced-2 ======

[Problem Statement]

Constraints:
   specified min width/height
   specified max width/height
   specified width/height
   intrinsic aspect ratio

Can't always satisfy all of these at once, so which ones get dropped?

   * Consensus is that min+max constraints must always be honored,
     with min overriding max in case of conflict.

   * Consensus is that when both width and height are specified, the
     aspect ratio is ignored.

   * Consensus is that when both width and height are auto, the aspect
      ratio is honored insofar as possible.

   ? Question is how to balance specified width/height and aspect ratio
      when either width or height (but not both) is auto.

[Solution Space]

Three possible balancing acts:

   A) Use the aspect ratio to find the missing dimension, then ignore
      it when applying min/max constraints.

        -> Changes to one dimension due to applying constraints won't
           affect the other dimension

        -> For example, for a 1:1 image with
              width: 300px;
              max-width: 100px;
           the resulting dimensions will be
              width = 100px
              height = 300px

        -> I don't think we really want this interpretation.

   B) Honor aspect ratio insofar as possible, but don't violate any
      author declarations.

        -> A specified width or height is always honored unless it
           violates min/max constraints.

        -> Missing dimension is calculated from the final value of
           the given dimension, subject to min/max constraints.

        -> Underlying assumption: author's declarations best represent
           author's intention.

        -> For example, for a 1:1 image with
             width: 150px;
             min-height: 300px;
           the resulting dimensions will be
             width = 150px
             height = 300px

   C) Honor the aspect ratio even if it means violating author-specified
      width or height.

         -> Use the given dimension to calculate the missing dimension.

         -> Treat resulting dimensions as the intrinsic dimensions and
            apply constraints as if both dimensions were auto.

         -> Underlying assumption: aspect ratio best represents author's
            intention.

         -> Resulting image may be smaller /or bigger/ than specified
            dimensions.

         -> For example, for a 1:1 image with
              width: 150px;
              min-height: 300px;
            the resulting dimensions will be
              width = 300px;
              height = 300px;

[Examples]

   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/intrinsic.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/intrinsic.svg>

Example 1.

   For a 1:1 image with
     width: 200px;
     max-width: 100px;
                            width      wmax
        |---------------------+----------+---------> width

        |------------------------------------------> height
   the resulting dimensions will be
     A) width = 100px       B) width = 100px       C) width = 100px
        height = 200px         height = 100px         height = 100px

   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex1b.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex1b.svg>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex1c.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex1c.svg>

Example 2.

   For a 1:1 image with
     width: 150px;
     min-height: 200px;
                            width
        |---------------------+--------------------> width
                                       hmin
        |--------------------------------+---------> height
                              `150px     `200px
   the resulting dimensions will be
     A) width = 150px       B) width = 150px       C) width = 200px
        height = 200px         height = 200px         height = 200px

   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex2b.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex2b.svg>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex2c.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex2c.svg>

Example 3.

   For a 1:1 image with
     width: 200px;
     max-height: 100px;
                            width
        |---------------------+--------------------> width
                hmax
        |---------+--------------------------------> height
                  `100px      `200px
   the resulting dimensions will be
     A) width = 200px       B) width = 200px       C) width = 100px
        height = 100px         height = 100px         height = 100px

   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex3b.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex3b.svg>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex3c.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex3c.svg>

Example 4.

   For a 1:1 image with
     min-width: 150px;
     height: 200px;
     max-height: 100px;
                            wmin
        |---------------------+--------------------> width
                hmax                  height
        |---------+---------------------+----------> height
                  `100px      `150px    `200px
   the resulting dimensions will be
     A) width = 200px       B) width = 150px       C) width = 150px
        height = 100px         height = 100px         height = 100px

   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex4b.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex4b.svg>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex4c.png>
   <http://fantasai.inkedblade.net/style/specs/css2.1/min-max-replaced-2/ex4c.svg>

[Spec Text]

After rereading the text carefully, I believe
   A) would require changing "used" to "computed" in the formula in 10.3.2
      and 10.6.2
   C) is using the constraint table, with the given dimension and the
      missing value calculated from the given dimension as the values
      for intrinsic width and height
   B) is actually what the last published draft says

Are you sure this time?

      Yes. :)

      The order is enforced by min/max-height/width stating that the steps that
      apply the constraints are what define the used width.

      Let's step through Bert's example.
        http://www.w3.org/Style/Group/css2-src/visudet.html
        http://lists.w3.org/Archives/Member/w3c-css-wg/2006JulSep/0036.html

      | Assume a landscape-style, inline image twice as wide as high. I set
      | the following:
      |    width: 300px;
      |    height: auto;
      |    max-width: 100px;
      |    max-height: 100px;

      The second interpretation is wrong because section 10.6.2 says:
        http://www.w3.org/Style/Group/css2-src/visudet.html#inline-replaced-height
      # if 'height' has a computed value of 'auto', 'width' has some other
      # computed value, and the element does have an intrinsic ratio; then
      # the used value of 'height' is: (used width) / (intrinsic ratio)

      The used width is calculated in 10.4
        http://www.w3.org/Style/Group/css2-src/visudet.html#min-max-widths
      The used width is the value of width after max-width has been applied,
       i.e. 100px

      Therefore the tentative used height is width/2 = 100px/2 = 50px, and since
      that's within the max-height constraint, it is also the final used height.

So what should we clarify?

      Maybe clarify that the used width/height calculated in 10.3/10.6 is
      tentative and subject to the algorithms in 10.4/10.7.

[Photo Grid Case]

The main proposed use case for C was arranging photos in a grid by setting
either width or height to some large value, then constraining it with max-width
and max-height. There are several problems with this approach imho.
   1. It's a hack. The author doesn't /really/ want to target his super-large
      height value at all. That would break his layout.
   2. It assumes that all authors don't really care about the width or height
      that they specified. (We've given authors a channel to communicate, and
      now it's corrupted.)
   3. As we saw above, in the case where min constraints are used instead of max
      constraints,  the image actually gets bigger than its specified dimensions.

Yes, this use case is very important. But it would make more sense if we gave
the author a channel designed to say what they mean than if we tweaked our
width/height calculations to let them write a hack to get this behavior. The
'fit' property is close, and is already there to control aspect ratio
handling, so why not use that?

[Using 'fit']

First problem: 'fit' doesn't apply unless both width and height are 'auto'.
   # The 'fit' property gives a hint for how to scale a replaced element
   # if neither its 'width' nor its 'height' property is 'auto'.
We can fix that by changing it to
   | The 'fit' property gives a hint for how to scale a replaced element
   | with an intrinsic ratio when it's used width and height result in an
   | aspect ratio different from the intrinsic ratio.

Second problem: 'fit' doesn't resize the image box, it just changes how the
   image is painted within it.
We can fix that by adding a new value that resizes the box, or by defining
different behavior for when min/max constraints take effect. For example,

   | If both 'height' and 'width' are 'auto' and both 'max-width' and
   | 'max-height' are given, then the calculate the used value of the width
   | and height as if the intrinsic size of the image were infinitely large.

We can put this under the definition of 'fit: meet'.

~fantasai

[Post Script]

   The CSS WG has decided to expand the 'fit' property as described above,
   and to change the names of the 'fit' property and values as follows:
      fit       =>  image-scaling
        fill      =>  fill
        hidden    =>  none
        meet      =>  contain
        slice     =>  cover

Received on Thursday, 26 May 2011 01:09:11 UTC