有趣的问题
css3 气泡问题:对于“三角形”的边框颜色,如何自动将其设置为其父 div 的背景颜色?
— Jin Yang (@jzy) 2012年2月1日
Jin 所说的“css3 气泡”是指在容器上使用伪元素来添加一个小指针箭头(三角形)。 并不是真正的 CSS3,但这有点吹毛求疵了。
假设在外部 CSS 文件中设置粉红色是不切实际的。 也许它是一个用户设置,或者也许它是以某种方式动态设置的。
<div class="speech-bubble" style="background: pink;">
I like bananas, because they have no bones.
</div>
使用内联样式设置容器很好,但不幸的是,伪元素没有内联样式。 因此,我们最终可能会得到如下所示的内容
太糟糕了。
不过,有一个解决方案! 当我们为容器设置内联样式时,我们也可以为border-color
设置内联样式。 即使容器实际上没有边框,我们也可以依靠继承将该颜色传递给伪元素,伪元素被视为子元素。
<div class="speech-bubble" style="border-color: pink; background: pink;">
I like bananas, because they have no bones.
</div>
然后,在我们针对伪元素的代码中,我们将明确地让它继承颜色
.speech-bubble:after {
content: "";
position: absolute;
top: 100%;
left: 20px;
border-top: 20px solid black;
border-top-color: inherit;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
请注意,我将inherit
应用于border-top-color
而不是速记属性border-top
。 出于某种原因(欢迎您赐教),inherit
在速记中不起作用。 另请注意,当您使用inherit
覆盖颜色时,它不会“继承”刚刚在其上方设置的颜色(黑色),而是继承自其父元素。 因此,如果您需要默认值,则需要在父元素上设置border-color
。
通过用 span 元素替换伪元素,可以使其与 IE7 和 IE8 浏览器兼容。
实际上只有 IE 7,IE 8 有伪元素。 但是的,正确。 而且您不必太担心这种继承问题,因为您可以直接在 span 上设置边框颜色。 但这样就会有非语义化的标记。
好吧,语义化很好,但在我的项目中,我必须使用此技术来显示工具提示,并且我意识到我无法通过 JavaScript 操作伪元素的样式(我试图调整那个小三角形的位置)。 所以我想这完全取决于您使用它的方式。
我认为可以通过 JavaScript 方法测试浏览器是否支持伪元素,如果它不支持,则附加一个<span>元素。 然后,在设置样式时只需执行以下操作
.bubble::after,
.bubble span {
border-top-color: inherit; /* 我实际上没有测试过,但在理论上它应该可以工作 */
}
请原谅我的错别字…
有谁知道使用 javascript 查找所有具有 :before 或 :after 内容的元素的方法吗? 我四处查找了一段时间,但没有找到。 这将使执行以下操作成为可能
然后使用您的 javascript 在元素内部添加一个 span……就是这样,ie7 支持。
我目前手动执行此操作,只需知道我在哪些元素上使用 :before 和 :after,但这并不是最佳实践…
嘿,Chris! 我认为这解释了为什么您无法从速记属性继承:http://www.w3.org/TR/2002/WD-CSS21-20020802/changes.html#q3
确实如此。 很有道理。
您可以使用此 JavaScript 库 http://ie7-js.googlecode.com/ 在 IE 6、7 等许多其他现代浏览器功能中启用对伪元素的支持,此处列出 http://ie7-js.googlecode.com/svn/test/index.html
我对措辞印象深刻——“我喜欢香蕉,因为它们没有骨头。” 谢谢你的笑声!
在正常使用中也很方便。 谢谢!
如果您不关心旧浏览器的支持,只需继承背景颜色并将框旋转 45°。
对于旧版浏览器,您可能还可以使用纯色边框将背景遮罩成三角形形状。 这需要有一个已知的背景颜色,气泡将浮在其上。
我们不能使用一个旋转 45° 并继承背景颜色的伪元素框(通过定位使其看起来像一个三角形,即框的一半将与气泡重叠以使框看起来像一个突出的三角形)吗?
如果这能起作用就好了
有谁知道让它起作用的方法吗?
我认为如果纯粹通过 CSS 完成,这是不可能的。 如果我可以使用 javascript,我仍然无法选择
div.bubble:before
。 除非您使用 javascript 插入另一个额外的元素。 我认为您不需要data-background
属性。 只需获取 background-color 值即可我错了吗?
将来可以通过纯 CSS 完成,但现在不行。
http://dev.w3.org/csswg/css-variables/
或者,如果您使用 SCSS 或类似的扩展,您现在就可以做到。
很棒的技巧,谢谢 Chris。
顺便说一句,喜欢 ShopTalk!
.speech-bubble – 它不应该有一行“position: relative;”吗?
非常有用的技巧。
谢谢!
嗨,Chris。 第二个 css 规则有一个简化版本
感谢分享这个新想法。
也许可以用‘currentColor’? :P)
“我喜欢香蕉,因为它们没有骨头。” 来自本人……罗宾·希奇科克先生!
抱歉,只是测试一下您很棒的表单
精彩的文章,谢谢,学到了一些很棒的技巧。
谢谢 Chris,这正是我要找的 :)
我不太明白代码的哪个部分负责三角形的东西……是“transparent”关键字吗?
请 Chris 告诉我们这个拖尾是如何创建的
我看不出您在代码中创建了哪里!!
FF 中的奇怪错误
试试这个
style=”background: white; border-color: white;”
(或任何浅色)
而不是这个
style=”background: red; border-color: red;”
三角形会出现细细的深色轮廓。 有人有解决办法吗?
所以现在我必须使用这个“content: ‘\a0’;”
… 这是 FF 错误的答案
<code>border-style:solid;</code>
所以整个CSS应该如下
<code>
<pre>
.speech-bubble:after {
content: “”;
position: absolute;
top: 100%;
left: 20px;
border-top: 20px outset black;
border-top-color: inherit;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
</pre>
</code>
CSS 的一种非常有创意的用法。说实话,我花了一点时间才弄清楚不同边框的原理。
我遇到的问题是试图让它在一个水平元素列表中工作。如果我在列表项上使用 :after,然后像上面一样使用 left:20px;,它会将箭头定位在整个列表的左侧边缘 20px 处,而不是该列表项。
@Keith Mancuso: 确保你的 li.active 元素上设置了 position:relative。
如果我想让背景是线性渐变怎么办?