[css3-background] box-shadow and border-image

Following up on today's discussion and Chris's observations in it
   http://lists.w3.org/Archives/Public/www-style/2009Jul/0102.html
I wanted to present my position on this issue very clearly.

A few premises:

   First: The purpose of 'box-shadow' is to create the effect of
          cutting the box out of the canvas and shifting it up
          above the canvas. It is not about drop-shadowing the
          foreground content. Drop-shadowing all or part of the
          foreground content is a cool feature, but it's a different
          feature. Not part of this discussion. See e.g. roc's work
          on SVG filters for HTML. [1]

   Second: box-shadow as a fallback for failed border-image loads
          is IMHO a very minor concern, and not enough to block
          significant use cases for box-shadow. Fallback design
          for when images are turned off is a general problem:
          I don't disagree that it warrants a solution, but a
          general solution such as a media query is a far better
          approach than trapping ourselves here.

   Third: This module is very close to done, and its features are
          highly desired in the CSS design community. Unless we
          are painting ourselves in a corner with a limitation or
          e.g. roc and hyatt are super-excited by a new ability
          and are like "I am so going to implement this now", new
          capabilities should be deferred to the next level of
          this module. Otherwise CSS3 Backgrounds and Borders
          isn't going to make it this year.


Use Case and Constraints:

There are many possible border-images that don't fit the use case
for 'box-shadow': specifically, border-images that don't create a
continuous division between the interior and exterior of the box,
so the concept of "cutting out the box" doesn't make any sense.

The border-image in Chris's document is one such image:
   http://www.w3.org/2009/07/B-and-B/no-drop.png

Such images are not candidates for 'box-shadow': there is nothing
reasonable you can do with them to get a pop-out effect for the
box itself even if you Photoshop the whole element after rendering.
You need a continuous boundary -- a "cut line" -- for this effect
to work. It can be fuzzy. It can have multiple parts. But it needs
to go all the way around the box without leaving gaps that connect
the interior and exterior of the border.


There are three classes of border-images that can be box-shadowed.

   A. Cases that can be easily handled by UA alpha-masking
   B. Cases that can be easily handled by adding the shadow to the image.
   C. Cases that can't be easily handled by either method.

Cases that fall under C are cases that
   - Have shadows for one border-image part intruding into another
     border-image part, and therefore can't be pre-composed and
     then sliced and tiled.
   - Have complicated enough shapes that the UA cannot intelligently
     compute a shadow for them, at least not without some sophisticated
     edge detection algorithms and perhaps not even then.

There's a lot of overlap between A and B; shaded buttons are a common
example. In this range the advantage of the 'box-shadow' method is
that the shadow is easily tweakable, and can be altered via JavaScript.

Cases that fall under A but not B are cases that
   - Have simple enough shapes that the UA can compute a good shadow
     for them,
   - But suffer from the same boundary-crossing problems as C
An example of this is the diamond-chain border-image in spec example:
   http://dev.w3.org/csswg/css3-background/borderresult.png
If the interior is solid, we can compute a bottom-right drop-shadow
for it easily, but we can't pre-compose the shadow because the
top right and bottom left corner shadows will offset into the edge
parts and get distorted the wrong way when the pieces are stretched
to fit.

Cases that fall under B but not A are cases that
   - Don't have the boundary-crossing problem in C, but
   - Have complicated enough shapes or desired shadow-effects that the
     UA cannot intelligently compute a shadow for them.
An example of this is Brad's Aladdin's Lamp example:
   http://www.bradclicks.com/cssplay/border-image/Alladins_Lamp.png
where the drop shadow only affects the lamp itself.


I estimate that over 80% of use cases will fall under the combination
of A and B. I don't have an estimate for the breakdown between A-only,
B-only, and A-or-B cases, but:

- By not having UA-generated shadows, there is no workable solution
   for images that fall under A but not B.
- By not having UA-generated shadows, we lose scriptability for
   box-shadows when combined with a border-image.

It seems reasonable to me therefore that we should allow box-shadow
to drop-shadow the border-image.


UA-computed Shadows:

 From the original discussion with roc and hyatt, the suggestion was:
  * For outer shadows, create the drop shadow from the combination of
    an assumed-opaque padding box and the alpha channels of the parts
    of the border image outside the padding box. Then only paint the
    drop-shadow outside the padding box.
  * For inner shadows, create the drop shadow from the combination of
    an assumed-opaque "everything outside the border box" and the
    alpha channels of the border image within the border box. Then
    only paint the drop-shadow inside the border box.

If the author wants to alter the boundaries of the masking behavior,
he can use the border-image-width and border-image-offset properties.
But that still limits us to a straight line boundary somewhere. A
wavy border will need to be opaque on one side for 'box-shadow' to
work on it.

It seems to me this definition will handle the most common, if not the
most interesting, cases. I'm happy to add it to the spec if roc and
hyatt are planning to implement it.

The main missing piece to this definition is the handling of 'spread'.
   * Using a spread radius is an intensive graphical calculation, and
     fails on sharp convex corners.
   * Increasing the size of the shadow works for convex shapes, but
     not concave or perforated ones.
   * I am not a graphics person, I was hoping Chris's proposal included
     a discussion of this.

[1] http://weblogs.mozillazine.org/roc/archives/2009/02/svg_filter_effe.html

~fantasai

Received on Thursday, 23 July 2009 22:41:52 UTC