用于渐变边框图像的border-image-slice [英] border-image-slice for gradient border image

查看:85
本文介绍了用于渐变边框图像的border-image-slice的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解在渐变边框图像的情况下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 by border-image-width

如果不指定border-image-width,则默认值为1,这表示

And if we don't specify border-image-width the default value is 1 which means

数字代表相应计算出的border-width的倍数.

因此,我们明确指定了border-image-width或仅使用border-width作为参考.在大多数情况下,只需要border-width,因为在大多数情况下,我们只希望覆盖边界区域,而不是更多.

So either we explicitely specify border-image-width or we simply use border-width as reference. In most of the case only border-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 a 50px 50px area and in the top edge for example we are using a 60px 25px image inside a 10px 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>

现在,我们更加清楚如何对图像进行切片,然后通过缩放拉伸将它们放置在不同的区域中.同样很明显,最佳值是使所有侧面的切片都等于边框宽度,在您的示例中就是这种情况,因为5em5x16px = 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 is 5x16px = 80px thus a slice of 80

从规范中我们还可以阅读:

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 to 41.666% since the width/height is equal to 100px 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆