边框图像如何与线性渐变一起使用?

Eli*_*tan 7 css border linear-gradients

我试图了解 border-image-slice 在渐变边框图像的情况下如何工作。在规范中,边框图像切片的值可以是一个数字,

表示光栅图像的边缘偏移(以像素为单位)和矢量图像的坐标。对于矢量图像,该数字与元素的大小相关,而不是与源图像的大小相关,因此在这些情况下通常更可取。

在CSS-tricks文章的示例中,边框图像设置如下:

border-image: repeating-linear-gradient(45deg, 
        #000, #000 1.5%, 
        transparent 1.5%, transparent 5%) 80;
Run Code Online (Sandbox Code Playgroud)

因此,根据规范,80 是相对于 div 的大小(宽度:26em;高度:23em;)。但我还是不明白这是什么意思。当我更改 div 的宽度或高度时,边框图像不会改变其外观。但是当我更改边框图像切片或边框宽度时,外观会发生显着变化。所以看起来数字 80 和边框宽度 5em 之间存在相关性。(数字 40 的边框看起来相同,边框宽度为 2.5em,16 的边框宽度为 1em,等等)。

我的问题是数字 80 是如何计算的,这意味着给定 div 和渐变的切片过程是什么?(如果有草图,我们将不胜感激)而且 80 似乎不是以 px、em 或 % 为单位,因为当我添加这些单位时,外观正在发生变化。

完整代码在这里:

border-image: repeating-linear-gradient(45deg, 
        #000, #000 1.5%, 
        transparent 1.5%, transparent 5%) 80;
Run Code Online (Sandbox Code Playgroud)
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%;	
}
Run Code Online (Sandbox Code Playgroud)

Tem*_*fif 9

长话短说

使用渐变时,图像的大小就是元素的大小。将border-image-width定义我们将放置切片的 9 个区域(如果未定义,border-width则使用)。将border-image-slice考虑初始图像来创建切片。无单位值被视为像素值,百分比值根据元素的大小进行解析。

为了获得完美的结果,我们应该让切片等于regions,为此,当不带单位使用时,我们需要border-image-slice等于border-image-width(或)。border-width使用百分比,计算出的值应该相同。

在您的情况下,80切片意味着80px并且您的边框5em5x16px = 80px


让我们举一个简单的例子。

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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)

在上面我尝试使用不同的技术(背景和边框)创建两个具有相同输出的 div。请注意,在第二个示例中,我如何使用关键字fill,并指定border-image-width与边框宽度不同的宽度,并使用等于该边框宽度的切片。

请注意,50这里的切片被视为像素,因为我们正在处理非矢量图像(渐变)。

数字表示图像中的像素(如果图像是光栅图像)或矢量坐标(如果图像是矢量图像)。参考

让我们删除fill关键字:

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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)

fill 关键字(如果存在)会导致保留边框图像的中间部分。(默认情况下它被丢弃,即被视为空。)ref

默认情况下,边框图像不绘制在中间,而仅绘制在边框中。我们可以从每个边的示例中清楚地看到50px,我们的自定义边框同样由 定义border-image-width

如果我们不指定border-image-width默认值,则1意味着:

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

因此,我们要么明确指定border-image-width,要么简单地用作border-width参考。在大多数情况下,仅border-width需要,因为在大多数情况下,我们只想覆盖边界区域而不是更多区域。

现在切片会将图像分成 9 个部分:

该属性指定从图像的上、右、下、左边缘向内的偏移,将其分为九个区域:四个角四个边缘和一个中间

在此输入图像描述 参考

以下步骤将更好地展示我们的示例是如何完成的:

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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)

左边的图像是原始图像,我们将其分为9部分,然后我们将每一部分放入右边图像的9个区域中。中间是空的,因为我们没有使用fill. 在此示例中,我们不会注意到任何内容,因为切片适合区域。

现在让我们将切片减少到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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)

这有点棘手,但同样的逻辑也适用。我们从左图的25px每一侧剪切得到 9 个部分,将其放入右图,其中边框宽度仍然相同 ( 50px)。您可以清楚地注意到角落中的部分是如何简单缩放的并且边缘是如何扭曲的。

在每个角落,我们都使用区域25px 25px内的图像50px 50px,例如在顶部边缘,我们使用区域60px 25px内的图像10px 50px

您还可以为每一侧定义不同的值,如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)

现在更清楚我们如何切片图像,然后通过缩放拉伸它们将它们放在不同的区域中。同样清楚的是,最好的值是让所有边上的切片等于border-width您的示例中的情况,因为因此5em5x16px = 80px切片80


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

由 border-image-slice 值给出的区域可能会重叠。但是,如果左右宽度之和等于或大于图像的宽度,则上下边缘和中间部分的图像为空,其效果与非空透明图像相同。为这些零件指定。类似地,对于顶部值和底部值。

如果您指定的左右切片大于图像宽度,那么从逻辑上讲,您将无法在顶部/底部/中间部分放置任何内容:

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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)

同样的逻辑也适用于顶部/底部。

这是一个只有角点的示例:

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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)


使用百分比值也会得到相同的结果。我们只需要找到参考,并且由于我们正在处理渐变,因此渐变的大小就是元素的大小。在我们的示例中,切片50等于,41.666%因为宽度/高度等于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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>

<div class="border"></div>
Run Code Online (Sandbox Code Playgroud)