您知道可以使用纯 CSS 制作三角形吗?这非常简单。 您只需创建一个宽度和高度为零的块级元素,在其一侧设置彩色边框,并在相邻的两侧设置透明边框。它们可以用于各种用途,例如从气泡中伸出的箭头、导航指针等等。通常,这些只是视觉修饰,不值得使用专门的标记。幸运的是,伪元素通常非常适合这种情况。也就是说,使用::before
、::after
或两者来创建这些块级元素并放置三角形。这种方法的一个巧妙用途是:面包屑导航。

HTML 标记
让我们尽可能保持简洁,并使用一个简单的无序列表,并添加一个“breadcrumb”类。
<ul class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Vehicles</a></li>
<li><a href="#">Vans</a></li>
<li><a href="#">Camper Vans</a></li>
<li><a href="#">1989 VW Westfalia Vanagon</a></li>
</ul>
CSS
首先,我们将确保我们的列表看起来不像一个典型的列表。我们将删除默认的列表样式,将项目浮动到左侧,并为每个链接设置非常基本的样式。请注意列表本身隐藏的溢出,这将有两个用途。第一,它确保菜单具有高度。仅包含浮动元素的容器会折叠,这通常不是理想的。第二,当我们制作三角形时,我们将使它们很大。
.breadcrumb {
list-style: none;
overflow: hidden;
font: 18px Sans-Serif;
}
.breadcrumb li {
float: left;
}
.breadcrumb li a {
color: white;
text-decoration: none;
padding: 10px 0 10px 65px;
background: brown; /* fallback color */
background: hsla(34,85%,35%,1);
position: relative;
display: block;
float: left;
}
要创建三角形,我们将使用::after
选择器来创建一个伪元素。它将是块级元素,高度和宽度为零,并绝对定位到左侧的 100%,这意味着它将从其父元素的右边缘开始。我们将它从顶部定位 50%,并使用边距将其向上拉 -50px,这将确保它绝对居中。这是一个经典技巧。还需要注意其他一些事项。我们将使用的边框在顶部为 50px,底部为 50px,左侧(制作向右的箭头)仅为 30px。这意味着一个更扁平的箭头。如果我们超过 50px,它将更尖锐。等于 50px 将使其成为完美的 90 度。由于顶部和底部的边框各为 50px,因此箭头的总高度为 100px。100px 远高于我们的菜单在 18px 字体大小和 10px 上下填充的情况下可能具有的高度。这是一件好事。这意味着我们有足够的空间来调整字体大小,而不用担心三角形会显示其限制。
.breadcrumb li a::after {
content: " ";
display: block;
width: 0;
height: 0;
border-top: 50px solid transparent; /* Go big on the size, and let overflow hide */
border-bottom: 50px solid transparent;
border-left: 30px solid hsla(34,85%,35%,1);
position: absolute;
top: 50%;
margin-top: -50px;
left: 100%;
z-index: 2;
}
注意到那个细小的 1px 白色分隔线了吗?这是另一个小技巧。我们不能直接在三角形上添加边框,因为它本身就是由边框构成的!相反,我们将创建另一个三角形,并将其放置在我们原始三角形的后面,并将其颜色设置为白色。这个三角形使用::before
选择器,但在其他方面完全相同。请注意,这里的关键是 z-index。您可以交换哪个三角形使用::after
和哪个三角形使用::before
,这实际上并不重要。
.breadcrumb li a::before {
content: " ";
display: block;
width: 0;
height: 0;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 30px solid white;
position: absolute;
top: 50%;
margin-top: -50px;
margin-left: 1px;
left: 100%;
z-index: 1;
}
现在开始着色。由于我们在这里稍微使用了一些高级技巧,因此我认为有两个 CSS 部分非常适合这个想法:nth-child 和 HSLa。
- nth-child 的优点:我们可以为面包屑的不同级别着色,而无需任何额外的标记。
- HSLa 的优点:我们可以基于单个色调和不同的阴影轻松地为面包屑的不同级别着色。
除了着色之外,我们还将使第一个链接具有较少的左侧填充(单个三角形不需要那么多填充,因为它没有与它紧贴在一起),并且我们将使最后一个链接没有任何着色,并且也不会响应点击或显示指针光标。我们也可以在不使用任何额外标记的情况下通过:first-child
和:last-child
实现这些效果。
.breadcrumb li:first-child a {
padding-left: 10px;
}
.breadcrumb li:nth-child(2) a { background: hsla(34,85%,45%,1); }
.breadcrumb li:nth-child(2) a:after { border-left-color: hsla(34,85%,45%,1); }
.breadcrumb li:nth-child(3) a { background: hsla(34,85%,55%,1); }
.breadcrumb li:nth-child(3) a:after { border-left-color: hsla(34,85%,55%,1); }
.breadcrumb li:nth-child(4) a { background: hsla(34,85%,65%,1); }
.breadcrumb li:nth-child(4) a:after { border-left-color: hsla(34,85%,65%,1); }
.breadcrumb li:nth-child(5) a { background: hsla(34,85%,75%,1); }
.breadcrumb li:nth-child(5) a:after { border-left-color: hsla(34,85%,75%,1); }
.breadcrumb li:last-child a {
background: transparent !important;
color: black;
pointer-events: none;
cursor: default;
}
.breadcrumb li:last-child a::after {
border: 0;
}
最后是悬停状态。这里唯一的技巧是,我们需要为三角形和链接都着色。没什么大不了的。
.breadcrumb li a:hover {
background: hsla(34, 85%, 25%, 1);
}
.breadcrumb li a:hover:after {
border-left-color: hsla(34, 85%, 25%, 1) !important;
}
更深入的浏览器兼容性
叫我懒惰鬼也行,但我没有费心处理非常深入的浏览器兼容性问题。我更兴奋于这个想法本身,而不是考虑生产环境。如果您想使用这个想法,但又担心旧版浏览器,以下是一些需要考虑的事项。
- 不要使用
hsla()
进行着色,请使用十六进制颜色代码。 - 不要使用
:nth-child
进行着色,请为每个列表项指定一个类名。 - 对于不支持
::after
/::before
的浏览器,请使用基于图像的系统。这是我最喜欢的基于图像的面包屑教程。 - 使用 Modernizr 检测功能(如 HSLa)。
- 使用 IE 专用样式表。
尽情享受
这是我们介绍的示例,以及一些变体。
查看 CSS-Tricks 的 CodePen 作品 CSS 三角形面包屑(@css-tricks)在 CodePen 上。
太棒了。使用稍微现代一点的 CSS 可以实现如此令人印象深刻的效果。但我仍然不明白边框是如何形成三角形的!
好的,我现在明白了 :) http://jsfiddle.net/JvUW4/
感谢您提供的链接 :)
是的,这解释清楚了。
多彩的!http://jsfiddle.net/FPUzF/
非常棒。感谢您提供的链接 :)
这不应该包装在标签内吗?我认为这样做比直接放在 ul 中更明智。
很棒的导航,Chris!但在 IE 中无法正常工作。我以为它是跨浏览器兼容的。
无论如何,这是一篇很棒的文章!谢谢!
请阅读上面文章中的“更深入的浏览器兼容性”部分,了解如何开始自行解决此问题的一些提示。
哇!我尝试在 IE6 中查看演示,但我首先尝试在其中加载这篇文章,而这已经是我能做到的极限了!CSS-tricks 是否故意在 IE6 中表现如此糟糕?我的意思是,它似乎是在该浏览器中主动、_故意_ 无法正常工作……
我无意在这个网站上支持 IE 6,抱歉。我不想让这里变成一个关于 IE 6 的讨论话题,因此后续回复将被隐藏。(别介意,我感谢您的反馈!)
如果您将链接拖动开(至少在 Firefox 中),您就可以看到 CSS 实际上是如何工作的。
否则,这或多或少是我在我目前正在处理的网站中实现的方式,直到我需要使用渐变背景,而……
最近我在面包屑中开始使用大于符号来表示三角形,它们更容易处理!
更改面包屑的好方法.. 谢谢 Chris。
不错的技巧。我在文章中没有看到的部分是用于关闭最后一个面包屑后的三角形的样式。从代码来看,它很不错。
.breadcrumb li:last-child a:after { border: 0; }
如果整体背景不是白色,我想可以使用类似的 before 选择器。
哇!我是您博客的忠实读者,通常不发表评论,但这个确实引起了我的注意!很棒的想法和漂亮的实现。
为什么同时设置 display block 和 float left,只需要 float left 就可以了吧,因为元素的行为类似于 display inline block?
非常酷的技术。只需再花十分钟左右的时间,就可以轻松地使它在 IE 8 中更加实用。我对这种技术印象深刻,但它确实有点粗糙。
如果你有这十分钟,我就会用你的名字更新文章。
不用使用 nth-child,可以为每个
<li>
应用类名,例如level-1
。由于您已经在 CSS 中多次调用 nth-child 来实现颜色渐变,因此不妨这样做。使用这种方法,以及从最低级别开始,以 1 为起点,到最高级别(在本例中为 5)结束的 z-index,并使用 rgb 而不是 hsla,就可以实现 IE8 的支持。
Snipplr 上的测试用例
在 Chrome(6.0.472.63)OSX SL 中看起来很糟糕……只是说说而已。
在我看来,Chrome 8 中看起来不错。 http://cl.ly/34Ee
这里似乎没有任何 Chrome 6 无法完全处理的东西。如果您找到解决方案,请告知我们,以便我们更新本文。我觉得应该有一些巧妙的谚语,比如“如果你有时间闲逛,你就有时间清理”,类似于“如果你有时间评论问题,你就有时间编写解决方案”。
我指的是三角形的边缘——您可以在屏幕截图中看到它们是多么锯齿状…… :)
http://cl.ly/808614bd38384d2d8f66
……但这似乎确实与三角形边框的锐利程度有关……在 90 度角处,Chrome 会完美地渲染它们。
啊,是的,绝对是“较矮胖”的三角形渲染效果更差。不确定是怎么回事。90 度三角形通常更清晰。白色三角形确实突出了糟糕的渲染效果,因此,如果您只是删除 :before 三角形,看起来也会更清晰。
Chrome 在抗锯齿某些效果方面很糟糕,因此它会在任何不容易融入直线像素的东西上留下锯齿(45 度线没问题,因为它只是放置对角线像素,但 45 度以外的任何角度都会出现锯齿)。话虽如此,在 Chrome 7 Windows 7 上,演示非常流畅 :)
克里斯,这是一篇很棒的文章!我真的很喜欢这个面包屑的设计……
我迫不及待地想看到每个浏览器都全面支持 CSS3。
IE7 中对我不起作用。
Al
我也是。IE7 中不起作用。
我在一年前创建了几乎相同的东西(尽管不是用于面包屑)。
http://cl.ly/1f8177a6147a07371650
适用于
PC IE6/7/8、Firefox 3+、Safari 4+、Chrome 4+、Opera 10.5+
Mac Firefox 3+、Safari 4+(在 Chrome 中未经测试,我的 MacBook 上只有 Tiger)。
标记是一个无序列表,使用精灵图,并且必须使用 JavaScript 才能使其仅在 IE6 中工作。我认为,在 IE6 中不使用 JS 时,这些框只会以方形的右侧呈现(已经有一段时间了)。
该网站仍在开发中(内部开发失败,然后外包,导致日期推迟了几次!),但计划在年底之前上线。我们将看看它在上线时是否仍然有效,我对这一点信心不足,因为供应商表示他们甚至还没有进行任何跨浏览器测试(哎呀)。
如果我记得,我会回来这里,并在上线后发布链接。
图片看起来更好更流畅。
很棒的东西,直到它在该死的 IE 中也能工作。感谢分享 :)
太棒了……我不知道我们可以用 CSS 制作三角形……我会在我的下一个项目中应用这个技巧 :)
克里斯,好主意。
此外,以下是我书签中的一些 CSS 三角形链接。
http://www.pvmgarage.com/2010/01/how-to-create-depth-and-nice-3d-ribbons-only-using-css3/
http://hedgerwow.appspot.com/demo/arrows
http://www.dinnermint.org/blog/css/creating-triangles-in-css(我认为这是我第一次阅读有关该技术的信息)。
当它是透明时,没有理由使用 hsla,使用 hsl。
hsl(8%, 100%, 50%)
或者,在白色背景上没有理由更改 HLSA 的亮度属性,使其更透明。
hsl(8%, 100%, 50%, 1)
hsl(8%, 100%, 50%, .8)
hsl(8%, 100%, 50%, .6)
我真的很喜欢这个 :) 太棒了!
非常有创意地使用 CSS!
配色方案让我想起了《绝命毒师》中的房车。
仅使用 CSS3 的概念验证,带渐变背景和边框。
http://jsfiddle.net/qXCed/5/
(不过仅限 Webkit 和 FF4)。
在 IE9 测试版中看起来有点奇怪……
同样的想法也用在了 http://zemz-ua.com/en/about 的语言切换器中。只是为了好玩。
喜欢!非常喜欢!非常感谢分享。顺便说一句,@Jeremy,你的也很棒。
可能它在 IE 中不起作用……有人知道吗?
很棒的教程。面包屑以前从未如此美丽过。
多么创新的解决方案。感谢您抽出时间将其整理在一起。
哈哈——我不打算支持 IE6,我对此感到很有趣。除了这篇忍者文章,克里斯,谢谢。
抱歉,但这篇文章一开始就错了。css 技巧本身很有趣,但 HTML 语义不正确。将面包屑编码为无序列表会让人觉得这些项目处于相同的层次结构级别,就像一行中的项目集一样。面包屑中的项目并非如此,它们表示一条路径,每个链接都是上一个链接的“子级”。
因此,作为包装器的 p 标签,包含简单的 a 标签已经会更好。编码面包屑有多种选择,但许多选择都过于复杂或语义不正确。我想指出这一点。
不想在这里发起语义战争,我认为标记没有任何问题。语义的问题在于它是主观的。
我对面包屑的看法是它们是有序列表,因为它们以定义的逻辑顺序出现。这并不能证明我是对的,而你和克里斯是错的。
克里斯,很棒的文章。我喜欢 CSS 正在变得可能的新事物,我只是希望我与之合作的其他开发人员也持有这种观点。
我认为 Geert 关于无序列表不是最完美的语义事物的说法很有道理。我也认为段落标签不是正确的答案。这是我的想法,但这似乎有点过头了。
我认为有序列表在语义上是可以的(因为面包屑的顺序很重要),而且很简单。
使用
<ol>
和一堆嵌套的<ul>
之间的区别在于您如何看待面包屑的工作方式。对于
<ol>
的情况从“顶级”开始
继续到“第二级”
继续到“第三级”
在“当前项目”处结束
对于嵌套的
<ul>
的情况从“顶级”的链接列表开始
从下一个选择列表中选择“第二级”
从下一个选择列表中选择“第三级”
从下一个选择列表中选择“当前项目”
我想这取决于您是想将其视为直接路径/因果关系(
<ol>
)还是一系列仅显示所选项目的选项(<ul>
)。@Thomas:我同意,语义在某种程度上是主观的,但有些事情就是错误的,而这就是其中之一。另一方面,在面包屑的特定情况下,也没有明确的正确解决方案。使用无序列表并不糟糕,但也不正确。而且我不认为这是主观的。当然,任何人在最终使用什么都是他们自己的选择。
@Chris:您发布的示例在语义方面可能稍微好一些,但显然正如您指出的那样,它非常复杂。如前所述,我认为面包屑没有明确的语义正确解决方案,这就是为什么我决定保持简单(包含 a 标签的 p 标签)。如果每个解决方案都有其缺点,那么在这种情况下,我将选择最简单的方案。但仁者见仁,智者见智。
无论如何,这是一个有趣的讨论,我认为在 HTML5 的开发过程中本可以更好地解决这个问题。
Geert,我对这个问题的看法是,面包屑是导航辅助工具,而不是站点层次结构的描述。从 HTML 文档的角度来看,面包屑轨迹是一系列链接,可用于向上导航站点树。对我来说,这是文档主题的补充,因此我不会对此进行过多的详细说明。
但是,如果文档的主题是描述站点层次结构,那么我会说列表根本不够用。
但另一方面,面包屑也会显示您在层次结构中的位置,因此它很容易双向工作!
希望这说得通。
我同意 Thomas Heaney 的观点,这里有序列表非常合理。
我喜欢 james 使用大于或小于符号。
酷...喜欢它!
优秀的文章,喜欢面包屑的设计,可能会尝试将其用作导航指针。LT
这是一种很棒的技术,因为它真的很酷,您也可以将其用作工具提示上的指针。可惜它与旧版浏览器不兼容。
这就是我一直在寻找的:D 非常感谢 :)
这是一个很棒的教程。非常有帮助。谢谢!
简直太棒了,我可以在旧版浏览器上进行变通,只有在有真正动机这样做的情况下,否则它只会优雅地降级,没有任何巧妙的技巧,我受够了 IE。
太棒了!我真的很喜欢它,非常感谢!
您有什么建议如何仅使用 div 的面包屑实现 css 箭头?谢谢。
不错的主意,但实际上不兼容浏览器。尽管我打算使用它 :)
一如既往的精彩作品:) 谢谢
不用图片制作三角形非常棒。但我仍然不明白他是怎么做到的。我必须仔细研究一下。
谢谢
vara
几个月前当我需要编写这种面包屑时,哪里有这个教程???:P 太棒的技术了,Chris。
不错。非常有帮助
您好,先生,我有一个小疑问。在单击菜单项后,我们可以使用哪个属性使鼠标悬停颜色固定,然后在单击下一个项目时更改为固定颜色?这怎么可能实现?
请告诉我可以使用哪个属性,先生…