用于渐变边框图像的border-image-slice [英] border-image-slice for gradient border image
问题描述
我正在尝试了解在渐变边框图像的情况下border-image-slice的工作方式.规范中写道,border-image-slice的值可以是一个数字,
I am trying to understand how border-image-slice works in the case of gradient border image. In spec it is written that a value for border-image-slice could be a number which
表示光栅图像的边缘偏移量(像素)和矢量图像的坐标.对于矢量图像,数字是相对于元素的大小,而不是源图像的大小,因此在这种情况下,通常最好使用百分比.
Represents an edge offset in pixels for raster images and coordinates for vector images. For vector images, the number is relative to the element's size, not the size of the source image, so percentages are generally preferable in these cases.
在CSS技巧的示例中
In the examples from CSS-tricks article a border-image is set like this:
border-image: repeating-linear-gradient(45deg,
#000, #000 1.5%,
transparent 1.5%, transparent 5%) 80;
因此,根据规范80是相对于div的大小(宽度:26em;高度:23em;).但是我仍然不明白这是什么意思.当我更改div的宽度或高度时,边框图像不会改变其外观.但是,当我更改border-image-slice或border宽度时,外观会发生很大变化.因此,似乎数字80与5em的边框宽度之间存在相关性. (数字40的边框看起来相同,边框宽度为2.5em,1em的边框宽度为16,依此类推.)
So, according to the spec 80 is relative to the div's size (width: 26em; height: 23em;). But I still don't understand what does it mean. When I change div's width or height, the border image doesn't change its look. But when I change border-image-slice or border width, the look changes significantly. So it seems like there is a correlation between number 80 and the border width of 5em. (the border looks the same for number 40 and border width of 2.5em, 16 for 1em, etc.).
我的问题是,如何计算数字80,这意味着给定div和渐变的切片过程是什么? (草图将不胜感激) 看来80不在px,em或%中,因为当我添加这些单位时,外观会发生变化.
My question is how number 80 is calculated meaning what is the slicing process for a given div and the gradient? (A sketch would be greatly appreciated) And it seems like 80 is not in px, em or %, because when I add those units the look is changing.
完整代码在这里:
div {
box-sizing: border-box;
position: relative;
border: solid 5em #000;
border-image: repeating-linear-gradient(45deg,
#000, #000 1.5%,
transparent 1.5%, transparent 5%) 80;
padding: 2em;
width: 26em; height: 23em;
background: linear-gradient(to right bottom,
#e18728, #4472b9);
background-size: 50% 50%;
}
<div></div>
推荐答案
TL; DR
使用渐变时,图像的大小就是元素的大小. border-width-image
将定义我们将放置切片的9个区域(如果未定义,则使用border-width
). border-image-slice
将考虑使用初始图像来创建切片.将无单位值视为像素值,并针对元素的大小解析百分比值.
TL;DR
When using gradient, the size of the image is the size of the element. The border-width-image
will define the 9 regions where we will place the slices (if not defined, border-width
is used). The border-image-slice
will consider the initial image to create the slices. A unitless value is considerd as pixel value and a percentage value is resolved against the size of the element.
要获得完美的结果,我们应该等于区域的切片,为此,当不使用单位时,我们需要使border-slice-image
等于border-width-image
(或border-width
).使用百分比,计算值应该相同.
To have a perfect result we should have the slices equal to regions and for this we need to have the border-slice-image
equal to border-width-image
(or border-width
) when used without unit. Using percentage, the computed value should be the same.
在您的情况下,切片中的80
表示80px
,并且具有5em
的边界,即5x16px = 80px
In your case 80
in the slice means 80px
and you have a border of 5em
which is 5x16px = 80px
让我们举个简单的例子.
Let's take an easy example.
div {
width: 100px;
height: 100px;
display: inline-block;
border: 10px solid transparent;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 50 fill;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
在上面,我尝试使用不同的技术(背景和边框)创建具有相同输出的两个div.请注意,在第二个示例中,我如何使用关键字fill
并指定与边框宽度不同的border-width-image
并使用等于该边框宽度的切片.
In the above I tried to create two divs with the same output using different techniques (background and border). Notice how in the second example I use the keyword fill
and I specified a border-width-image
different from the border width and used a slice equal to that border width.
请注意,切片中的50
在这里被视为像素,因为我们处理的是非矢量图像(渐变).
Note that 50
in the slice is considered as pixel here since we deal with non vector image (a gradient).
数字表示图像中的像素(如果图像是光栅图像)或矢量坐标(如果图像是矢量图像). 参考
让我们删除fill属性:
Let's remove the fill property:
div {
width: 100px;
height: 100px;
display: inline-block;
border: 10px solid transparent;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 50;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
如果使用fill关键字,则将保留边框图像的中间部分. (默认情况下将其丢弃,即被视为空.) 默认情况下,边框图像不会绘制在中间,而只会绘制在边框中.从示例中我们可以清楚地看到,在每边都有
50px
并具有如border-image-width
By default, the border image is not painted in the middle but only in the border. We can clearly see form the example that we have
50px
on each side with our custom border like defined byborder-image-width
如果不指定
border-image-width
,则默认值为1
,这表示And if we don't specify
border-image-width
the default value is1
which means数字代表相应计算出的
border-width
的倍数.因此,我们明确指定了
border-image-width
或仅使用border-width
作为参考.在大多数情况下,只需要border-width
,因为在大多数情况下,我们只希望覆盖边界区域,而不是更多.So either we explicitely specify
border-image-width
or we simply useborder-width
as reference. In most of the case onlyborder-width
is needed since in most of the case we want to only cover the border area and not more.现在切片将图像分成9个部分
Now the slice will split the image in 9 parts
此属性指定距图像的顶部,右侧,底部和左侧边缘的向内偏移,将其分为九个区域:四个角,四个边缘和一个中
下面的步骤将更好地说明我们的示例是如何完成的:
Here is the steps that will better show how it's done for our example:
div { width: 100px; height: 100px; border: solid 10px transparent; display: inline-block; position: relative; } div:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(green,green) left 0 top 50px/100% 1px no-repeat, linear-gradient(green,green) left 0 bottom 50px/100% 1px no-repeat, linear-gradient(green,green) top 0 left 50px/1px 100% no-repeat, linear-gradient(green,green) top 0 right 50px/1px 100% no-repeat; } div.box { background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red; } div.border { border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 50; border-image-width: 50px; background: red; }
<div class="box"></div> <div class="border"></div>
左图是原始图像,我们将其分为9个部分,然后将每个图像放置在右图的9个区域中.中间一个是空的,因为我们没有使用填充.在此示例中,由于切片适合区域,因此我们什么也没注意到.
The left image is the original one that we divide in 9 parts then we put each one in the 9 regions of the right one. The middle one is empty because we didn't use fill. In this example we will notice nothing because the slices fit the regions.
现在让我们将切片缩小为
25
:Now let's reduce the slice to
25
:
div { width: 100px; height: 100px; border: solid 10px transparent; display: inline-block; position: relative; } div.box:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(blue,blue) left 0 top 25px/100% 1px no-repeat, linear-gradient(blue,blue) left 0 bottom 25px/100% 1px no-repeat, linear-gradient(blue,blue) top 0 left 25px/1px 100% no-repeat, linear-gradient(blue,blue) top 0 right 25px/1px 100% no-repeat; } div.border:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat, linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat, linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat, linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat; } div.box { background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red; } div.border { border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 25; border-image-width: 50px; background: red; }
<div class="box"></div> <div class="border"></div>
这有点棘手,但适用相同的逻辑.从左边的图像中,我们使用
25px
切割每侧,以得到我们的9部分,我们将在右边的部分放置边框宽度仍然相同的(50px
).您可以清楚地注意到角落中的零件是如何简单缩放和边缘变形的.It's a bit tricky but the same logic apply. From the left image we cut using
25px
form each side to get our 9 portion that we will put in the right one where the border-width is still the same (50px
). You can clearly notice how the part in the corners are simply scaled and the edges are distored.在每个拐角处,我们在
50px 50px
区域内使用25px 25px
图像,例如,在上边缘,我们在10px 50px
区域内使用60px 25px
图像.In each corner we are using a
25px 25px
image inside a50px 50px
area and in the top edge for example we are using a60px 25px
image inside a10px 50px
area.您还可以为每一面定义不同的值,如下所示:
You can also define different value for each side to have something like below:
div { width: 100px; height: 100px; border: solid 10px transparent; display: inline-block; position: relative; } div.box:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(blue, blue) left 0 top 20px/100% 1px no-repeat, linear-gradient(blue, blue) left 0 bottom 30px/100% 1px no-repeat, linear-gradient(blue, blue) top 0 left 20px/1px 100% no-repeat, linear-gradient(blue, blue) top 0 right 60px/1px 100% no-repeat; } div.border:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat, linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat, linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat, linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat; } div.box { background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red; } div.border { border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px); border-image-slice: 20 60 20 30; border-image-width: 50px; background: red; }
<div class="box"></div> <div class="border"></div>
现在,我们更加清楚如何对图像进行切片,然后通过缩放拉伸将它们放置在不同的区域中.同样很明显,最佳值是使所有侧面的切片都等于边框宽度,在您的示例中就是这种情况,因为
5em
是5x16px = 80px
从而是80
Now it's more clear how we slice the image then we put them in the different region by scaling stretching them. It's also clear that the best value is to have the slices in all the sides equal to the border-width which is the case in your example since
5em
is5x16px = 80px
thus a slice of80
从规范中我们还可以阅读:
From the specification we can also read:
border-image-slice值给定的区域可能重叠.但是,如果左右宽度的总和等于或大于图像的宽度,则顶部和底部边缘以及中间部分的图像将为空,其效果与非空透明图像相同.为这些零件指定.类似地,用于顶部和底部值.
The regions given by the border-image-slice values may overlap. However if the sum of the right and left widths is equal to or greater than the width of the image, the images for the top and bottom edge and the middle part are empty, which has the same effect as if a nonempty transparent image had been specified for those parts. Analogously for the top and bottom values.
如果您指定的左切片和右切片大于图像宽度,那么从逻辑上讲,您不会在顶部/底部/中间部分放置任何内容:
If you specify a left and right slice bigger than the image width then logically you will get nothing to put on the top/bottom/middle part:
div { width: 100px; height: 100px; border: solid 10px transparent; display: inline-block; position: relative; } div.box:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(blue, blue) left 0 top 20px/100% 1px no-repeat, linear-gradient(blue, blue) left 0 bottom 30px/100% 1px no-repeat, linear-gradient(blue, blue) top 0 left 60px/1px 100% no-repeat, linear-gradient(blue, blue) top 0 right 60px/1px 100% no-repeat; } div.border:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat, linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat, linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat, linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat; } div.box { background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red; } div.border { border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px); border-image-slice: 20 60 20 60; border-image-width: 50px; background: red; }
<div class="box"></div> <div class="border"></div>
相同的逻辑也适用于顶部/底部.
Same logic apply to top/bottom too.
这是一个例子,其中我们只有拐角处
Here is an example where we will only have the corners
div { width: 100px; height: 100px; border: solid 10px transparent; display: inline-block; position: relative; } div.box:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(blue, blue) left 0 top 20px/100% 1px no-repeat, linear-gradient(blue, blue) left 0 bottom 100px/100% 1px no-repeat, linear-gradient(blue, blue) top 0 left 60px/1px 100% no-repeat, linear-gradient(blue, blue) top 0 right 60px/1px 100% no-repeat; } div.border:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat, linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat, linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat, linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat; } div.box { background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red; } div.border { border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px); border-image-slice: 20 60 100 60; border-image-width: 50px; background: red; }
<div class="box"></div> <div class="border"></div>
使用百分比值也将得到相同的结果.我们只需要查找参考,并且由于我们正在处理渐变,因此渐变的大小就是元素的大小.在我们的示例中,切片
50
等于41.666%
,因为宽度/高度等于100px 2 * 10px = 120px
Using percentage value will also give the same result. We simply need to find the reference and since we are dealing with gradient, the size of the gradient is simply the size of the element. A slice of
50
in our example is equal to41.666%
since the width/height is equal to100px 2 * 10px = 120px
div { width: 100px; height: 100px; border: solid 10px transparent; display: inline-block; position: relative; } div:before { content: ""; position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background: linear-gradient(blue, blue) left 0 top 50px/100% 1px no-repeat, linear-gradient(blue, blue) left 0 bottom 50px/100% 1px no-repeat, linear-gradient(blue, blue) top 0 left 50px/1px 100% no-repeat, linear-gradient(blue, blue) top 0 right 50px/1px 100% no-repeat; } div.box { background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red; } div.border { border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 41.666%; border-image-width: 50px; background: red; }
<div class="box"></div> <div class="border"></div>
这篇关于用于渐变边框图像的border-image-slice的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!