奇怪的渐变边框效果

时间:2015-06-29 11:54:37

标签: html css css3 linear-gradients

在以linear-gradient为背景的元素上应用透明边框时,会产生奇怪的效果。

enter image description here

请注意,元素的左侧和右侧没有正确的颜色(它们在某种程度上是切换的)并且奇怪地平面

HTML

<div class="colors">
</div>

CSS

.colors {
    width: 100px;
    border: 10px solid rgba(0,0,0,0.2);
    height: 50px;
    background: linear-gradient(to right, 
        #78C5D6,
        #459BA8,
        #79C267,
        #C5D647,
        #F5D63D,
        #F08B33,
        #E868A2,
        #BE61A5);
}

为什么会在元素的左侧和右侧显示一个奇怪的效果, 我能做些什么呢?

这是小提琴:http://jsfiddle.net/fzndodgx/3/

8 个答案:

答案 0 :(得分:50)

这是因为gradient的起点和终点位于padding-boxborder的边缘,在padding-box之外呈现。因此,边框看起来很有趣,因为在background之外的每一边重复padding-box以覆盖border-box

box-shadow:insetpadding-box内呈现(就像背景一样)并且在视觉上与border具有相同的效果,因此您可以尝试使用它代替border }:

box-shadow: inset 0 0 0 10px rgba(0,0,0,0.2);
padding: 10px;

由于box-shadow不占用任何空间,因此您需要相应地增加填充。

padding-boxborder-box的插图: enter image description here

演示http://jsfiddle.net/ilpo/fzndodgx/5/

答案 1 :(得分:43)

解决方案

解决此问题的最简单方法是将background-origin属性的值设置为border-box

&#13;
&#13;
.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-origin: border-box;
}
&#13;
<div class="colors"></div>
&#13;
&#13;
&#13;

有问题的行为的原因

以下是确定此案例背景渐变显示方式的相关background属性:

  • background-origin - 默认值为padding-box。这意味着背景实际上是相对于填充框定位的,因此从border之后开始。
  • background-repeat - 默认值为repeat。这意味着图像应该根据需要重复覆盖整个背景绘画区域。
  • background-clip - 默认值为border-box。这意味着图像也应该出现在盒子边框占据的区域下面。

现在结合所有这三个,我们可以看到边界必须尽可能多地重复,以便它甚至在边界下出现,并且它的起始位置在框的边界之后。这意味着必须以循环方式重复背景,以便填充左侧边界下方的区域。因此,左边框的颜色为渐变的右端,反之亦然。

通过将其更改为border-box,我们将使背景相对于边框框定位。此设置也会影响背景图片的大小,详细说明如下。

为什么box-sizing: border-box不起作用?

box-sizing设置为border-box不会带来任何更改,因为该属性仅影响框的大小。它对以下内容完全没有影响:

  • 梯度图像的大小(实际计算逻辑如下所述)
  • 渐变图像的起点(或位置)
  • 重复背景图片

如何计算梯度的大小?

根据W3C spec,以下是未提供明确尺寸时图像尺寸的计算方法(默认值为auto)。

  

如果图片既没有固有宽度也没有固有高度,则其尺寸确定为'包含'

注意它是如何谈论图像的大小而不是盒子的大小。实质上,无论框的大小如何,当图像本身没有固有高度(which CSS gradients don't have unlike images)时,将根据关键字contain的定义计算背景图像的大小。

contain定义如下:

  

缩放图像,同时保留其固有纵横比(如果有),使其最大尺寸,使其宽度和高度都能够适合背景定位区域

后台定位区域定义如下(在background-origin属性定义下):

  

对于呈现为单个框的元素,指定背景定位区域

因此,当图像没有固有高度时(在这种情况下也没有background-size),图像的大小将等于background-origin的值(其中在我们的例子中是padding-box)。

这就是为什么即使将box-sizing设为border-box也无效。

注意:引用文本中的重点都是我的

如果您明确将background-size设置为框的大小,您会注意到问题是如何在右侧解决,而不是在左侧解决。这是因为现在图像足够大,不能在右边框下重复,但它的起点仍然在左边框之后。

&#13;
&#13;
.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-size: 110px 60px;
}
.colors-2 {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  box-sizing: border-box;
  background-size: 100px 50px;
}
&#13;
<div class="colors">
</div>
<div class="colors-2">
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:13)

背景在边界下重复。背景仅在元素的“主体”中运行,在边界下方是扩展并重复开始。

请参阅边框上no-repeat的{​​{3}}示例。

<强>更新

玩背景position&amp; size可以通过扩展背景然后调整其位置来提供帮助。

检查this

或查看代码段:

.colors {
  padding: 10px;
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-size: 117%;
  background-position-x: 130px;
}
<div class="colors"></div>

答案 3 :(得分:4)

根据默认的CSS框模型行为,渐变在填充框内开始,因此有意义的是,开始和最终结束的颜色一直出现在渐变的任何一侧,即边界所在的位置。

此渐变(NSFW)也是如此:

A GOD AWFUL EYE SORE

它在左边的起始值(紫色)中无限延续,并且向右无限地继续,结束值(橙色)。它可以通过这个渐变无限向上继续,所以它确实如此。

我理解为什么会出现这种情况,解决方案是使用不同的盒子模型。

答案 4 :(得分:4)

background-origin属性的默认值为GetMembers(),表示背景的位置和相对于填充框的大小。

背景也扩展在边框下方,因为background-clip属性默认为padding-box;它只是在边界下重复。这就是为什么你看到左边框下方背景的右侧,反之亦然。

所以,只需改变原点:

&#13;
&#13;
border-box
&#13;
.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-origin: border-box;
}
&#13;
&#13;
&#13;

或者你也可以玩背景大小和位置:将20px添加到背景大小并将其定位在-10px-10px:

&#13;
&#13;
<div class="colors"></div>
&#13;
.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-position: -10px -10px;
  background-size: calc(100% + 20px) calc(100% + 20px);
}
&#13;
&#13;
&#13;

答案 5 :(得分:4)

其他答案已经说明了如何解决这个问题,但我想我应该指出,如果你增加border-width,很明显背景实际上正在重复。

.colors {
    width: 100px;
    border: 100px solid rgba(0,0,0,0.2);
    height: 50px;
    background: linear-gradient(to right, 
        #78C5D6,
        #459BA8,
        #79C267,
        #C5D647,
        #F5D63D,
        #F08B33,
        #E868A2,
        #BE61A5);
}

将产生

enter image description here

答案 6 :(得分:3)

如果您不想使用box-shadow,可以使用border-image并调整渐变的颜色:http://jsfiddle.net/9pcuj8bw/5/

&#13;
&#13;
.colors {
    width:100px;
    height: 50px;
    background: linear-gradient(to right, 
        #78C5D6,
        #459BA8,
        #79C267,
        #C5D647,
        #F5D63D,
        #F08B33,
        #E868A2,
        #BE61A5) no-repeat;
    border: 10px solid;
    border-image: linear-gradient(to right, 
        #0bc3b8,
        #068e8c,
        #f8c617,
        #ea5f24,
        #b2492c) 1;
}
&#13;
<div class="colors"></div>
&#13;
&#13;
&#13;

小心这不适用于IE10或更低版本:http://caniuse.com/#feat=border-image

答案 7 :(得分:0)

它的工作正常。您在块上使用了透明边框,因此可以看到bg-color。它的线性渐变使其左右两侧的纯色。如果使用实线边框,则可以看到正确的效果。 http://prntscr.com/7mo5jm