奇怪的渐变边框效果


72

在以alinear-gradient为背景的元素上应用透明边框时,我得到了怪异的效果。

在此处输入图片说明

请注意,元素的左侧和右侧没有适当的颜色(它们以某种方式切换)并且怪异地平坦

的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/


这不仅是因为边框与内容框是分开的吗?即背景。
2015年

一种解决方案是使用:: after进行第二个div处理:jsfiddle.net/a1h2yh11
DenysSéguret15年

为什么要投票?考虑也发表评论。无论如何..
阿方索·马托斯

Answers:


52

这是因为的起点和终点gradient在的边缘,padding-box并且border在的外部渲染padding-box。因此,边框看起来很有趣,因为在background之外的每一侧都重复了,padding-box以覆盖border-box

box-shadow:inset呈现内padding-box(就像背景),并在视觉上给人以同样的效果border,所以你可以尝试使用代替border

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

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

padding-box和的插图border-box在此处输入图片说明

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


9
背景重复出现-因此它超出了填充框的范围,然后又重新开始-因此出现了明显的反转。
Geoff Atkins 2015年

6
我认为,在另一个答案发布很长时间之后,将另一个答案中已经涵盖的内容添加到您自己中并不是很好。至少您可以在编辑中提到其他答案。
哈利

3
否决了..因为有其他帖子的复制粘贴答案。不要试图将他人的工作视为功劳。
Mr_Green

4
嗯,称它为复制粘贴有点儿麻烦,这不像该用户新答案替换了原来的答案。无论如何,Harry的答案仍然可以解释他的解决方案,因此它仍然优于该解决方案。
BoltClock

2
抱歉,在进行编辑之前没有花时间阅读他的长答案,也没有意识到已经提出了解决方案。我可以删除我编辑过的位,如果有区别的话。
Okku,2015年

46

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

.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;
}
<div class="colors"></div>


出现上述问题的原因

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

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

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

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


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

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

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

梯度的大小如何计算?

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

如果图像既没有固有宽度也没有固有高度,则将其大小确定为“包含”

请注意它是如何谈论图像的大小而不是盒子的大小。从本质上讲,无论框的大小如何,contain当图像本身没有固有高度时(该CSS梯度不会像其他图像一样),背景图像的大小将根据关键字的定义计算)。

定义contain如下:

将图像缩放,同时保留其固有的宽高比(如果有),以最大尺寸进行缩放,以使其宽度和高度都可以适合背景定位区域

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

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

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

这就是为什么即使将box-sizingas设置border-box都无效的原因。

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


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


1
很好的解释,可能有不同的解决方法。
阿方索·马托斯

1
@afonsomatos:此答案涵盖的方法不是解决方法。实际上,这实际上是解决您的问题的合适方法:)
哈利

13

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

请参见带有边框的示例no-repeat

更新

播放背景positionsize可以通过扩大背景,然后调整其位置来提供帮助。

检查这个小提琴

或查看摘要:

.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>


@DenysSéguret,固定到小提琴的链接
JNF

4

渐变根据默认CSS盒子模型的行为在填充框中开始,因此有意义的是,开始和结束颜色一直出现到渐变两侧的无穷大处(边界将位于边界的两端)。

此梯度(NSFW)也是如此:

上帝的眼睛

它在左边的起始值(紫色)中无限地继续,并在右边的终止值(橙色)中无限地继续。它可以通过该梯度无限地继续向上延伸,所以确实如此。

这就是我对为什么出现这种情况的理解,一种解决方案是使用其他盒子模型。


12
...为什么将渐变标记为不安全?
Woodrow Barlow 2015年

4
因为它非常难看>。>
2015年

13
老板让我看到了这个梯度,现在我必须与人力资源部见面。非常感谢亚伦。
斯特林·阿彻2015年

1
@WoodrowBarlow Stackoverflow看起来足够商业化,很认真,可以随便浏览(除非您已激活基于标签的线程突出显示)。如果直接询问,您总是可以说:“我在这里找到问题X的解决方案”。大而彩色的图像破坏了这种印象。
Traubenfuchs

1
@SterlingArcher我确定Malory会大怒。
Purag

4

background-origin属性的默认值是padding-box,它表示背景相对于填充框的位置和大小。

由于属性默认设置为,背景也延伸到边框下方background-clipborder-box;。它只是在边界下方重复。这就是为什么您在左边框下方看到背景的右侧,反之亦然。

因此,只需更改原点:

.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;
}
<div class="colors"></div>

或者,您也可以使用背景大小和位置:将20px添加到背景大小并将其放置在-10px -10px:

.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);
}
<div class="colors"></div>


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);
}

将产生

在此处输入图片说明


@mflodin + 1确实变得更加明显
Afonso Matos

3

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

.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;
}
<div class="colors"></div>

请注意,这不适用于IE10或更低版本:http : //caniuse.com/#feat=border-image


您的意思是,“这不适用于IE10−”-它适用于所有其他浏览器(Firefox,Chrome等)。
科比2015年

1
这不是最佳解决方案,也无法达到预期的效果。
阿方索·马托斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.