Re: [css-backgrounds] border-image with an SVG resource that has no intrinsic size

Regarding the last point which is why the SVG image (with no intrinsic size) by itself can be rendered correctly while the image-border in WebKit renders all the pieces from the top-left corner, here is my explanation for why this approach was chosen. Let's  consider this simple test case:

svg-no-intrinsic-size.svg:

<svg xmlns="http://www.w3.org/2000/svg <http://www.w3.org/2000/svg>" version="1.1">
 <rect width="100" height="100" fill="lime"/>
 <rect x="10" y="10" width="80" height="80" fill="none" stroke="black" stroke-width="4px"/>
</svg>

test-case.html:
<!DOCTYPE HTML>
<head>
 <style>
   .box {
     height: 100px;
     width: 100px;
     margin: 10px;
     display: inline-block;
     background-color: red;
     border: 20px solid;
   }
   .border-image-no-intrinsic {
      border-image: url('svg-no-intrinsic-size.svg') 0 fill;
   }
   .border-image-no-intrinsic-slice {
      border-image: url('svg-no-intrinsic-size.svg') 20 fill;
   }
 </style>
</head>
<body>
 <div class="box border-image-no-intrinsic"></div>
 <div class="box border-image-no-intrinsic-slice"></div>
</body>

When loading this test case In Chrome, the first div: <div class="box border-image-no-intrinsic”> draws only the fill part of the border-image. But the drawing of the border-image is scaled down by some ratio which is hard to be understood. But from tracing the code here is why this scaling is happening.
This div size is (100x100) with border of 20, so the border box is (140x140)
According to the specs: the intrinsic size of the SVG border image should be (140x140)
Since the border-image has fill set on but its slice is 0, the whole SVG which is (140x140) has to be displayed in the content box of the div which is (100x100)
So the SVG drawing will be scaled down by 100/140.
In Chrome also, the second div: <div class="box border-image-no-intrinsic-slice”> draws all the nine parts of the border-image. But it does not fill the whole rectangle of the <div>; it only fills 100x100 out of the 140x140 pixels. Here is why this happening:
This div size is (100x100) with border of 20, so the border box is (140x140)
According to the specs: the intrinsic size of the SVG border image should be (140x140)
Since the border-image has its slice set to 20, the drawing size is also 140x140, which means no scaling is applied when drawing the image.
Since the SVG itself draws only 100x100 pixels and since no scaling or stretching will happen,  only 100x100 of the element area will be covered by the SVG image.
From these two cases, it was obvious to me that this problem is unsolvable. The nine-piece-slicing algorithm needs to know the bonding box of the drawing to draw the border-image correctly. There is no reliable way to know this bounding box (at least for now). So the only way to know it is to require an “intrinsic size” set by the user.

Now if the following SVG is used, the border-image will be drawn exactly as expected:

<svg xmlns="http://www.w3.org/2000/svg <http://www.w3.org/2000/svg>" version=“1.1” width=“100” height=“100">
 <rect width="100" height="100" fill="lime"/>
 <rect x="10" y="10" width="80" height="80" fill="none" stroke="black" stroke-width="4px"/>
</svg>

The specs says that the border box of the containing element should be used as a replacement of the image intrinsic size, if it is not provided. But this does not even give predictable results for simple cases.

I disagree that this was horrible change in WebKit. I understand it is not the ultimate solution and might not be the expected behavior. But my goal in choosing this approach was two things: (1) Solve this problem using the most straightforward solution so we get predictable and easy to explain results. (2) Make strong emphasis to the users that border-image has to have intrinsic size since we can’t guess its bounding drawing box.

Received on Thursday, 13 August 2015 13:57:17 UTC