Open SebastianZ opened 1 year ago
It was my personal experience that border-image-slice
was the hardest property to get use to when I first started working with border-image
. Have observed many others struggling with it as well. Even when I show people the MDN border-image
generator they just tinker with it constantly clearly not understanding what is going on. Also cannot count the number of times people have "corrected" me when I tell them that the pixel value cannot have a px
unit. They tell me: "That's just not how CSS works".
Under "Allow to target specific regions" you mention "all eight regions." This seems to ignore the possibility of including a fill
image. Is that intentional?
Maybe a grid-template
like syntax could be used when specifying all images?
border-image-source:
"url(top-left-corner.svg) url(just_a_solid_line.svg) url(top-right-corner.svg)"
". . ."
"url(bottom-left-corner.svg) linear-gradinet(to top, #000 0 3px, transparent 0) url(bottom-right-corner.svg)";
How would alignment of images work if for example the top corner images and top edge image where not the same height? Outer, center/middle, or inner aligned?
I can see a lot of just_a_solid_line.svg
/solid gradient being used to mimic solid bordered edges as part of the source. Could it be made possible to use something like border solid 3px
as an image?? Or as a keyword in place of an image??
Also cannot count the number of times people have "corrected" me when I tell them that the pixel value cannot have a
px
unit.
Agree that that's another pain point but let's keep that discussion in #6739.
- Under "Allow to target specific regions" you mention "all eight regions." This seems to ignore the possibility of including a
fill
image. Is that intentional?
Yes, because I see the fill
image as another source of confusion. Border images are meant to be placed within the border area.
For consistency reasons, a ninth image could be added, though I am strongly against that. For filling the background area we have the background-*
properties.
The same accounts for border-image-width
, which should not have existed, in my opinion. Or it shouldn't be possible for it to extend the actual border area, at least.
So my approach was to restrict it to the eight border regions.
- Maybe a
grid-template
like syntax could be used when specifying all images?border-image-source: "url(top-left-corner.svg) url(just_a_solid_line.svg) url(top-right-corner.svg)" ". . ." "url(bottom-left-corner.svg) linear-gradinet(to top, #000 0 3px, transparent 0) url(bottom-right-corner.svg)";
You mean grid-template-areas
. The issue with that is that the string syntax conflicts with the <image>
data type. You'd rather need to keep the <string>
s for the dots separated from the <image>
s. I.e. the example might look like this:
border-image-source:
url(top-left-corner.svg) url(just_a_solid_line.svg) url(top-right-corner.svg)
". . ."
url(bottom-left-corner.svg) linear-gradient(to top, #000 0 3px, transparent 0) url(bottom-right-corner.svg);
But yeah, that could be another approach.
Another approach could be to target the different regions by name. Taking your example, that might then look like this:
border-image-source:
url('top-left-corner.svg') top left
url('just_a_solid_line.svg') top center
url('top-right-corner.svg') top right
url('bottom-left-corner.svg') bottom left
linear-gradient(to top, #000 0 3px, transparent 0) bottom center
url('bottom-right-corner.svg') bottom right;
Or maybe something that aligns with the grid syntax proposed for anchor positioning, allowing to fill multiple border regions with one image. Though I guess we might then run into similar issues again as we have them now with slicing.
- How would alignment of images work if for example the top corner images and top edge image where not the same height? Outer, center/middle, or inner aligned?
They are layed out using border-image-width
, i.e. they are shrunk or stretched so that they are equal in size. As I said, all other border-image-*
properties besides border-image-slice
would still have an effect on the images.
We might still extend the features to allow aligning the images within their regions, but I explicitly only wanted to target the slicing issue for now and don't introduce new features besides that.
- I can see a lot of
just_a_solid_line.svg
/solid gradient being used to mimic solid bordered edges as part of the source. Could it be made possible to use something likeborder solid 3px
as an image?? Or as a keyword in place of an image??
Authors could achieve that by placing a linear-gradient(transparent calc(50% - 1px), black calc(50% - 1px), black calc(50% + 2px), transparent calc(50% + 2px))
. Pretty hacky, I know, but again, something better would be for a future extension. (And authors do have to fake that right now as well by creating an image tile like that.)
We might allow the stripes()
function we just introduced for border-color
for that, though. Which would reduce this to the much nicer stripes(transparent, black 2px, transparent)
.
Sebastian
Potential live site use cases for this change to border-image-source
. It is of note that there are many more examples of border-image like styles on this page than I've called out below but I don't see border-image
being used at all: https://baldursgate3.game/
border-image-source: url('corner.svg') url('top-bottom-edge.svg') url('left-right-edge.svg');
border-image-source: url('corner.svg') url('top-bottom-edge.svg') none;
I finally remembered where I had seen border-image
properties like the ones proposed in this issue before and it was in the Emmet cheat sheet: https://docs.emmet.io/cheat-sheet/
Where these properties part of a previous proposal for border-image
?
What would have been the function of continue
keyword?
I don't think these were part of any spec. At least I couldn't find it in the history of CSS Backgrounds 3 publications.
Though I found something along those lines proposed by Stuart Ballard[proposed] and elaborated by @fantasai and as comments on a request for corner images.
Introducing individual properties for each corner and side would be another way to achieve this. Though then we'd need to specify how they interact with the existing border-image-*
properties.
Sebastian
How would missing border-image-sources be handled? Would one missing or slow to load image request result in the entire border-image
not being painted? Or would the images that are available load in without the ones that aren't?
How would missing border-image-sources be handled? Would one missing or slow to load image request result in the entire
border-image
not being painted? Or would the images that are available load in without the ones that aren't?
The same logic as for background-image
applies, i.e. a missing image only affects the region(s) that image is used. The images that are loaded will still be displayed.
Sebastian
I think border-image
is fundamentally broken and instead of trying to fix it we should deprecate it and replace it with something else. Use cases for using images as borders are very, very common, and currently border-image
not only doesn't cover enough of them, it has terrible DX for those it does cover.
I just posted https://github.com/w3c/csswg-drafts/issues/9714 to get the conversation started.
I think
border-image
is fundamentally broken and instead of trying to fix it we should deprecate it and replace it with something else.
As I noted in the first comment and in the other issue, I believe the only big issue with border images is the slicing logic. Therefore, I believe it's better to extend and fix border-image
rather than replacing it. Regarding the slicing problem, I just filed #9734.
Sebastian
The slicing logic for border images is a relatively complicated concept that can confuse authors.
To make it easier to define border images, it should be possible to define multiple images instead of a single one that gets sliced.
The idea is to define up to eight individual images via the
border-image-source
property. Doing so, theborder-image-slice
property doesn't have any effect. The other border image properties would still work the same. When eight images are specified, each image targets one region of the border image area, starting at the top left corner and going clockwise through the regions. As indicated in the previous sentences, you may also specify less images. This allows to cover common use cases and may save network bandwidth when external images are used.For filling the different regions I can imagine two different approaches.
Copy and auto-flip and/or auto-rotate the images
If less than eight images are defined, the images are used for the other regions as well.
E.g. if only two images are specified, the first one will be used for the four corner regions. It will be flipped horizontally for the corners on the horizontal opposite side and vertically for the vertical opposite side. The second image is then used for the four edges, rotated by 90° for each adjacent side.
Example:
If three images are specified, the first one is used for the corners again, the second one for the top and bottom edges, and the third one for the left and the right edge, with the ones for the bottom and right edges rotated by 180°.
Example:
Other combinations might be possible.
There may be use cases in which an auto-flipping and -rotating algorithm might not be wanted. For those we might introduce a new property that controls how to place the images.
Allow to target specific regions
Authors have to define the images for all eight regions but may skip them. That allows to place the images in specific regions within the border image area.
If authors want to add border images only in the bottom regions, they'd skip the top, left and right regions.
Example:
If only the four corners should be decorated, authors would have to skip the edges.
Example:
Flipping and rotation like in the first proposed solution would still be possible via image manipulation functionalities. This would reduce the need for different images in some cases.
Sebastian