[css3-background] <border-image> property

Dear CSS Community Members and Editors,

Greetings!

This is my first post or submission, so please forgive if it is not in the
style you are used to, but I have revised this message several times to be a
decent proposal.  

I am a web developer currently working on an online photo gallery and store.
With existing CSS properties, I have been able to simulate a matted
photograph, including the angled matte cuts around the artwork and even the
glass covering it.  I look forward to using border images to improve the
application and accurately represent framing options for customers.  During
my design process, I considered what specifications for border images would
be both effective and user-friendly, because there is no currently defined
and implemented standard.  I have had a chance to look at the draft
specification for <border-image> and found it a good compact way to display
very complex borders, but I believe there is a much greater potential for
images in borders.

I would like to propose modification of the definition of <border-style> to
allow a <uri> followed by one of the optional image keywords: [stretch |
repeat | round].  (It is important to note that the image keywords must be a
mutually exclusive group of words from those which are valid <border-style>
values; the reason why is given below.) The image keywords will be
interpreted as part of the <uri> that precedes them and ignored if no <uri>
precedes them.

Thus, the value set <border-style> would be redefined as: 

<border-style> = <uri> [stretch | repeat | round]? | none | hidden | dotted
| dashed | solid | double | dot-dash | dot-dot-dash | wave | groove | ridge
| inset | outset

Border style values may be in a comma-separated list when used (also new to
the definition).  The browser should always try to use the first value in a
comma-separated list, and if the browser cannot load the specified <uri> or
does not recognize the keyword, it should move to the next value in the list
and apply the same test.  If the browser reaches the end of a
comma-separated list and still has not found a useable value, it should
behave as if a non-empty transparent image had loaded for individual
properties and use value replication rules described below if declared using
the shorthand property.  Note: This specification will also make legacy
support much easier for <border-style> values introduced in CSS4 and beyond.
If the <border-style> value being used is a <uri>, the first image keyword
following that value within the list applying to that border side will be
used for that image.  If there is no image keyword following the loaded
<uri> within the list applying to that border side, ‘stretch’ will be
assumed.  For example:

Border-top-style: url(“a.gif”) round, url(“b.gif”), url(“c.gif”) repeat,
url(“d.gif”), url(“e.gif”), solid;  In this declaration, the browser would
try to load “a.gif” and if successful would use image keyword ‘round’ in
rendering the border.  If not, it would try to load “b.gif” and then
“c.gif,” using ‘repeat’ as the keyword on a successful load.  If none of
these three loaded, the browser would then try to load d.gif and then e.gif,
using the keyword ‘stretch’ if successful.   If the browser could not load
any, it would use the explicitly chosen <border-style> of ‘solid.’  Other
border-style keywords could have been mixed in there, with the browser
advancing beyond these only if it did not recognize that keyword.  

Allowing the mix of border-style keywords and author-defined images is
another key advantage to this redefinition.  

 

Legacy Support: I do not know if you have already solved the question as to
what authors should do if they wish to use CSS3 <border-style> values and
support older (2006 current) browsers, but adding <uri>s and comma-separated
lists will NOT make things any harder.  One solution I came up with was to
use two border style declarations with older but still acceptable keywords
in the first, as the browser will ignore the second rule.  

 

The shorthand property border-style may also be used by authors just as
before.  Styles for each border side are separated by a space, as they are
currently, and comma-separated lists for each side will be allowed as
described above.  This must be done with care. For example,

“Border-style: url(“a.gif”), url(“b.gif”) repeat solid;” [note the non-comma
space separation between ‘repeat’ and ‘solid’] would put an image (if loaded
correctly) on the top and bottom and a solid border on the left and right
(see value replication rules below), but the declaration “border-style:
url(“a.gif”), url(“b.gif”) repeat, solid;” would make ‘solid’ a part of the
comma-separated list and all four borders would have the same border-style
according to the value replication rules listed below.  Only image keywords
could be preceded by a non-comma space without causing advancement to the
next border side.  

 

          Value replication in the shorthand property would take place as it
has before, but a clear definition is important.  ‘No useable value’ could
occur if an author used less than four <border-style> lists (as the most
common case will be), or if the browser got through a comma-separated list
without being able to use a <uri> or recognize a keyword.

*     If there is no useable value for border-style-left, horizontally flip
the image used on the right if a uri, or use the same border-style keyword
if a keyword is used on the right.

*     If there is no useable value for border-style-bottom, vertically flip
the image used on the top if a uri, or use the same border-style keyword if
a keyword is used on the top.

*     If there is no useable value for border-style-right, rotate the image
used on the top by 90° (clockwise) if a uri, or use the same border-style
keyword if a keyword is used on the top.

*     If there is no useable value for border-style-top and there IS a
useable value for border-style-bottom, vertically flip the image used on the
bottom if a uri, or use the same border-style keyword if a [useable] keyword
is used on the bottom.

*     If there is no useable value for either border-style-top or
border-style-bottom, but there IS a useable value for border-style-right,
rotate that image by 90° counterclockwise for the top and clockwise for the
bottom if a <uri>, or use the same border-style keyword if a [useable]
keyword is used on the right.

*     If there is only a useable value for border-style-left, rotate the
image by 90° each side going around the image, or use that keyword for all
border sides if a keyword is used.  

*     If there are no useable values, the browser will behave as if a
non-empty transparent image had loaded (OR ignores the declaration- we
should specify which).

For example, the rule ‘border-style: url("darkoak.gif") stretch solid
url(“lightoak.gif”) repeat, ridge solid; would render an oak frame on top
(dark, stretched) and bottom (light, repeated), with solid left and right
sides.  If lightoak could not be loaded, a ridge border would be used
instead for the bottom.  If darkoak could not be loaded, and lightoak could,
lightoak would be vertically flipped and used on top (with ‘repeat’).  If
neither oak frame image could load, a ridge border would be used on both top
and bottom.  Comma-separated lists as described above would give authors the
chance to explicitly define a different behavior if that were desired.

 

Image Keywords will behave as currently described under the <border-image>
property.  

The image, if tiled (the keyword was not “stretch”) would have as its origin
for tiling the most counter-clockwise edge of the border section it would be
covering.  In the example below, the top border would begin tiling at the
red line, and the right border would begin tiling at the blue line.   This
tiling would happen in both directions, though the tiling in the
counterclockwise direction would be affected by the handling of the corners
(see below).  



          Handling at the corners:

          The current draft specification “does not define how borders of
different styles should be joined in the corner.”

Given the addition of images to <border-style>, I would recommend the new
“border-corner” property.

*     The border-corner property: 


Name: 

border-top-right , border-bottom-right, border-bottom-left, border-top-left 


Value: 

 <http://www.w3.org/TR/2005/WD-css3-background-20050216/#ltborder-stylegt>
<border-style> (which, as defined above, would include <uri> values) | angle


Initial: 

If both sides adjacent to the corner have the same <border-style> keyword,
that keyword is used.  Otherwise, the border-corner keyword ‘angle’ is the
default.


Applies to: 

all elements 


Inherited: 

no 


Percentages: 

N/A 


Media: 

visual 


Computed value: 

specified value 

 


Name: 

border-corner 


Value: 

[ <http://www.w3.org/TR/2005/WD-css3-background-20050216/#ltborder-stylegt>
<border-style> | angle]{1,4} 


Initial: 

(see individual properties) 


Applies to: 

all elements 


Inherited: 

no 


Percentages: 

N/A 


Media: 

visual 


Computed value: 

see individual properties


 

 

Border style keywords used at the corners would cause that corner to be
rendered as they would be if both adjacent border-styles used that keyword,
regardless of the truth of that latter statement.  User agents may (or may
not) also choose to define corners for styles, like a short right angle with
legs of equal length for the dashed border style, or a single round circle
for the dotted style.  Examples of border-corners for each of the keywords
can be found with the examples of the border-style keywords.  

 

If a <uri> was used to reference an image, the image would be scaled to have
a width equal to border-width of the vertical side coming to that corner,
and a height equal to the border-width of the horizontal side coming to that
corner, as expected.

 

To determine the order of values for the shorthand (given in the order of
listing of the individual properties), I used what seems to be the CSS
standard of starting near the top center and working clockwise around the
box.

If the shorthand property were used, value replication would take place as
it does for border-style:

*     If there is no useable value for border-top-left, horizontally and
vertically flip (or just rotate by 180*) the image used on the bottom-right
if a uri, or use the same border-style keyword if a keyword was used.

*     If there is no useable value for border-bottom-left, horizontally and
vertically flip (or just rotate by 180*) the image used on the top-right if
a uri, or use the same border-style keyword if a keyword was used.

*     If there is no useable value for border-bottom-right, rotate the image
used on the top-right by 90* if a uri, or use the same border-style keyword
if a keyword was used.

*     If there is no useable value for border-top-right and there IS a
useable value for border-bottom-left, horizontally and vertically flip (or
just rotate by 180*) the image used on the bottom-left if a uri, or use the
same border-style keyword if a [useable] keyword is used on the bottom-left.

*     If there is no useable value for either border-top-right or
border-bottom-left, but there IS a useable value for border-bottom-right,
rotate that image by 90° counterclockwise for the top and clockwise for the
bottom if a <uri>, or use the same border-style keyword if a [useable]
keyword is used on the bottom-right.

*     If there is only a useable value for border-top-left, rotate the image
by 90° each side going around the image, or use that keyword for all border
corners if a keyword is used.  

*     If there are no useable values, the browser ignores the declaration
and uses default values.  

 

Default Values:  I considered three options for the specification:

When the author does not specify a border corner,

*       The same keyword value that was used for the <border-style> of the
side counterclockwise-adjacent to it should be assumed.  If this value was a
<uri>, the border-corner keyword ‘angle’ is the default.

OR, 

*       ‘Angle’ is always the default.

OR,

*       If both sides adjacent to the corner have the same <border-style>
keyword, that keyword is used.  Otherwise, the border-corner keyword ‘angle’
is the default. 

 

I chose the third definition, because it would allow default non-‘angle’
browser-defined handling of styles like ‘dashed’ or ‘dot-dash,’ and because
this definition matches the current behavior of most browsers. 

 

Definition of keyword ‘angle:’

(Note that introduction of the border-corner property would prevent future
use of the keyword ‘angle’ as a <border-style> value; it is an unlikely
keyword to ever have been chosen anyway.)

Behavior for the keyword “angle:”  An imaginary line is drawn from the inner
corner of the border to the outer corner of the border, as shown in green
for the lower-left corner above.  (For example, when two adjoining borders
are of equal width, this line would be at 45* to both the horizontal and
vertical.)  This line would divide the corner into two equal parts which are
each adjacent to exactly one side of the border.  Each half of the rectangle
would be then treated as if it were an extension of the adjacent border.
Put another way, the corner would be occupied by both border-styles but only
one would show for any given point in the corner, and an [invisible] angled
line would separate the two regions.  This is currently the way most
browsers handle corners for styles such as inset, outset, groove, and ridge.
This is also how many browsers currently handle heterogeneous corners for
most combinations of border styles. 

 

It is important to note that border corners are a part of the border.  

 

Here is an example, using the image file “gold.jpg.”  Note that the second
rule is the only one that is really new.

img.kinkade {

border-color: #FC6;

border-style: url(“frames/gold.jpg”) repeat, ridge; 

border-width: 50px;

background: #060;

padding: 100px;

} would also use the default border-corner value of ‘angle’ and approximate
the following:

(where gold.jpg = ).

 

(This sample assumes that the image file contains the red and white stripes
around the artwork.  If it didn’t, the same end result could be achieved
using nested blocks with a red-and-white striped inner border.)  

Please feel free to respond with any comments and consider integrating this
proposal into the next draft of CSS.

 

 

Grace and peace, 

Ben

ben@wbtproductions.com

 

Received on Thursday, 20 July 2006 14:26:21 UTC