使用伪元素 ::before
和 ::after
可以实现非常神奇的事情。对于页面上的每个元素,您都可以获得两个额外的免费元素,您可以对它们进行与任何其他 HTML 元素相同的操作。它们可以解锁许多有趣的设计可能性,而不会对标记的语义产生负面影响。这里有一些神奇的事情。如果您愿意,这是一个汇总。
提供多个背景画布

因为您可以将伪元素绝对定位到其父元素,所以您可以将它们视为每个元素可以使用的两个额外图层。 Nicolas Gallagher 向我们展示 了很多应用场景,包括多个边框、模拟 CSS3 多重背景以及等高列。
扩展您可以使用单个元素创建的形状数量

上面所有形状 以及更多形状 都可以用单个元素创建,这使得它们实际上很实用。与那些使用 1,700 个 div 创建的“用纯 CSS 制作咖啡杯!”之类的东西不同,那些东西很酷但并不实用。
以下是一个六角星的示例
#star-six {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
position: relative;
}
#star-six:after {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid red;
position: absolute;
content: "";
top: 30px;
left: -50px;
}
在打印的网页中显示链接的 URL

@media print {
a[href]:after {
content: " (" attr(href) ") ";
}
}
清除浮动

与其插入额外的非语义标记来清除容器元素的浮动,我们可以使用伪元素来完成此操作。通常被称为 “clearfix”,并在语义上用类名“group”命名。
.group:before,
.group:after {
content: "";
display: table;
}
.group:after {
clear: both;
}
.group {
zoom: 1; /* For IE 6/7 (trigger hasLayout) */
}
模拟 float: center;

尽管我们可能很希望它,但 float 属性实际上没有 center 的值。但是 float 有 left 和 right,通过使用占位符伪元素,我们可以划分两列之间的区域并将图像放置在那里,我们可以 模拟这种效果。
使用代码语言标记代码块

在这个网站的当前设计中,代码块使用伪元素标记了它们所属的代码语言。
pre::after {
content: attr(rel);
position: absolute;
top: 22px;
right: 12px;
}
创建整个图标集

Nicolas Gallagher 再次将形状的概念提升到另一个层次,通过创建一个巨大的图标集,这些图标集不使用任何图像,而只是在最多两个元素上使用伪元素。
更有效地利用可用空间

CSS 给予了什么,CSS 也可以拿走什么。我的意思是,伪元素内容可以通过 媒体查询有条件地应用或删除。也许您在空间有限时应用一个图标,而在空间充足时使用更具描述性的词语替换它。
应用排版装饰

如果您的伪元素是文本,它们将继承与其父元素相同的排版样式。但在设置其内容时,您也可以对其进行样式设置。比如,使用不同的字体和颜色,让您的标题以装饰的形式脱颖而出。
h2 {
text-align: center;
}
h2:before, h2:after {
font-family: "Some cool font with glyphs", serif;
content: "\00d7"; /* Some fancy character */
color: #c83f3f;
}
h2:before {
margin-right: 10px;
}
h2:after {
margin-left: 10px;
}
创建全浏览器宽度栏

当您需要背景延伸到全宽,但内容不延伸到全宽的元素时,您经常会遇到非语义内部包装元素或重复且杂乱的间距声明。或者,您可以 模拟这种效果,通过用一个元素限制内容宽度,并使标题栏使用伪元素延伸到边缘。
创建主体边框

使用常规边框在左侧和右侧,以及在顶部和底部使用固定定位的伪元素栏,我们可以获得 “主体边框”效果,而无需任何专门的标记。
body::before, body::after {
content: "";
position: fixed;
background: #900;
left: 0;
right: 0;
height: 10px;
}
body::before {
top: 0;
}
body::after {
bottom: 0;
}
body {
border-left: 10px solid #900;
border-right: 10px solid #900;
}
制作一个闪闪发光的按钮

如果您制作一个具有透明到白色到透明渐变的伪元素块,将其定位在按钮外部(通过隐藏溢出隐藏它),并在悬停时对其进行过渡移动,您可以制作一个按钮,当您将鼠标悬停在它上面时,它似乎会捕捉到一些光线。仅 Firefox、Chrome 26+ 和 IE10+ 支持。
原始 作者 Anton Trollbäck; 伪元素化 作者 Nicolas Gallagher; 另一个版本 作者是我。
当特定链接悬停时淡出页面

如果您没有对元素设置相对定位,绝对定位的伪元素将相对于下一个具有相对定位的父元素进行定位。如果没有其他元素,它将相对于根元素进行定位。您可以使用它制作一个全浏览器窗口元素,将其堆叠在主元素下方,并在悬停时显示它,从而在链接上实现 “页面淡出”效果。
将标题设置为三维丝带样式

每个人都喜欢丝带!查看此代码片段,了解此丝带的 HTML 和 CSS 代码。它使用负 z-index
,在某些情况下,需要额外的包装元素才能防止元素在具有不透明背景的父元素下丢失。
设置有序列表中的数字样式

你有没有尝试过设置有序列表中的数字样式?你最终会做一些蠢事,比如将内容包装在 span 中,设置列表项的样式,然后使用 span 移除该样式。或者以疯狂的方式使用背景图片。或者移除列表样式并添加自己的数字。所有这些方法都很糟糕。最好利用 伪元素作为计数器。
使数据表格响应式

大型数据表格在小屏幕上浏览起来很糟糕。要么放大后需要垂直和水平滚动,要么缩小后太小,无法阅读。我们可以将 CSS 媒体查询与伪元素结合起来,使数据表格响应式,并在小屏幕上将其重新格式化为更易于阅读的视图。
创建样式化的工具提示

使用 HTML5 数据属性,然后将其拉入并将其设置为伪元素,我们可以通过 CSS 创建完全自定义的工具提示。
在导航项之间添加分隔符

如果你想区分一个导航项与另一个导航项,你的选择是有限的:你可以添加边框(很无聊)或者在每个项之间添加额外的标记(很糟糕)。伪元素允许你使用任何内容作为项之间的间隔符
.menu li:before {
content: "// ";
position: relative;
left: -1px;
}
无需 HTML 创建整个网站

利用浏览器自动插入的 <html>
、<head>
和 <body>
标签,Mathias Bynens 展示了如何仅使用 CSS 和伪元素内容创建网站。
构建仅使用 CSS 的字体

使用单个 HTML 元素(加上伪元素)来表示每个字符,Yusuke Sugomori 通过 CSS 构建了完整的字体,名为 CSS Sans。交互式演示让你可以浏览 Yusuke 用于构建每个字符的所有巧妙技巧(例如,旋转、圆角和倾斜)。
该字体仅限于大写拉丁字母,并且非常漂亮。CSS Sans 项目很好地展示了在约束条件下构建的创造力。
这里有很多好东西,期待着使用更多伪元素进行操作。
很棒的教程。谢谢!!
非常棒的帖子!我正在努力学习 CSS,虽然这篇文章的内容对我来说有点难,但我已经了解足够的信息来了解你所做事情的实用性。感谢你的提示!
哇!太棒了。谢谢。
Chrome 12(稳定版),标题遮挡了下面的图片。除此之外,这是一篇很棒的信息:)
.one-thing h3 {
margin: 0 0 -38px 0;
}
这似乎是罪魁祸首。我使用的是 Chrome 12,看到了同样的情况。
本来打算这样做。显然,结果没有我想象的那样酷。
我必须承认,我也注意到了这一点,在决定是故意的之前,我在 Chrome 中查看了它。:)
只是想插一句,我认为这是一个很聪明的主意。我没有想到这可能是无意的。
绝对精彩。我一直不喜欢使用非语义标记进行清除浮动,模拟 float: center 的方法非常巧妙。
哇,这里的东西太棒了。
不错 - 尽管令人望而生畏 - 的列表。我让有限的技能变得生疏了。哎。
对于它值得注意的事情
Who’s 是 Who is 的缩写。
你在这里想要用到的词是 whose(“元素 whose 背景拉伸到全宽,但 whose 内容没有”)。
干杯!
太棒了!浏览器支持怎么样?除了像 Gleaming 按钮 Firefox 支持这样专门提到的,这些可以用于生产环境吗?
这篇文章非常令人兴奋,我回家后会尝试所有这些!
最初的 gleaming 按钮演示在 Chrome 12 中似乎没问题,不过后面的演示不行(鉴于现在只提到了 FF4+,这并不奇怪)。
那是一个非常巧妙的效果。:D
你妈妈.. 很辣。哈哈
很棒的帖子!
决定尝试你链接的纯 CSS 工具提示,但在旧浏览器(即 IE)中发现了一些问题。
决定进行故障排除,并找到了 这个。
你觉得怎么样?这是我第一次真正深入地解决 CSS 浏览器支持问题,所以如果我犯了一些明显的错误,我不会感到惊讶!
很棒的帖子:)
太可惜了,firebug 不支持编辑这种东西。
其中一些在 IE 上不起作用。
啊,难怪我在 firebug 中看不到我的更改,真是太糟糕了。
这些东西真好吃!
去你*的 IE!
真的很喜欢这种版式修饰的想法,我从来没有想到过要采用这种方法。
很棒的列表,包含一些我从未听过的有用技巧。谢谢!
真的,这篇文章很火。很喜欢。继续努力!
Chrish 拼写错误,
所有上述形状以及更多形状都可以
在链接(以及更多)中使用任何用于和。
无论如何,不错的集合
Opera 11 也支持伪元素上的过渡(效果不错,顺便说一句),不仅仅是 FF4-5
没有,它没有?
证明:http://jsfiddle.net/chriscoyier/cxSQR/
嘿,克里斯,
我今年在 MinneBar 上听了你关于伪元素主题的演讲。很棒的东西,继续努力。
关于
rel="CSS"
的一个小细节:CSS
不是有效的链接关系。最好使用自定义的data-*
属性。是的……我当时是把它想成“这段代码与______ 的语言相关”。也许全世界都会屈服于我的意志,允许它。
你也可以将选择器定位到元素的“影子 DOM”(现在可以在 Chrome 中检查)来进行操作。例如,你可以使用
::-webkit-slider-thumb
定位输入类型为“range”的滑块。我有点走得太远了,通过滥用它来实现 iPhone 解锁滑块:)——参见我的帖子(抱歉,自我推广,但这与主题相关!)http://davidbcalhoun.com/2011/implementing-iphone-slider-unlock-with-input-type-range我们什么时候才能获得无限的伪元素,它在将内容和标记分离的教条中意义重大。也许有一天~
我只能说哇,克里斯,简直是哇。我不知道 CSS 如此强大,让我印象深刻。我还喜欢你这样呈现信息的方式,这使得它更容易理解和接受,而且很高兴能有一些老式的幽默作为点缀。
非常棒的东西,用它们真的很有创意。
伪工具提示需要额外的浇头;visibility: visible/hidden。
http://peteryee.my/playground/tooltip/
受到你在这里的创意的启发,我在伪元素中制作了一个概念验证的翻页动画。
http://ontouchstart.wordpress.com/2011/06/14/sallie-gardner-at-a-gallop/
很棒的帖子。我喜欢能够在打印页面中显示 url 的功能。
哪些浏览器支持这些功能?
我为你制作了一个小网站,你可以用它创建简单的,只有 CSS(使用::before 和::after)的 3D 丝带,soiheardyouliekribbon。
嘿,真棒的人!很喜欢!
那个拼错的“liek”是故意的,对吧?
哦……希望你把我的进度条(http://lab.galengidman.com/progress-bars)也包含在你的文章中……不过文章很棒,克里斯。
非常棒的帖子,非常有用。谢谢克里斯
很多不错的想法,但也有一些不应用于真实网站的例子。内容必须在 HTML 文档中编写。CSS 仅用于样式。其他一切都是…… - 操场上的东西。
无论如何:不错的集合!
你能给我展示一个上面违反该规则的例子吗?
不,我的错!
不,抱歉。——我仍然半睡半醒…:-}
不,我的错。我早就开始找删除按钮了。
有些例子是游走在边缘的,比如响应式数据表。但是有一些方法可以改进它……我应该更新那篇文章。用 CSS 添加真实内容确实是一个问题,因为它不利于可访问性、语义和 SEO,所以任何可以避免它的方法都是一个好主意。
感谢你收集这些内容并将它们放在同一个页面上!
@Chris:这里有些东西不正常?!我试图回复你——当然你是对的。一切都好(如果你不计算,作为一个用户,而不是一个开发者)不喜欢响应式设计。
实际上非常好的文章
我认为在这篇文章中添加伪雪碧部分可能是个好主意:)
https://css-tricks.org.cn/13224-pseudo-spriting/
使用 :after 进行计数非常棒。很喜欢这篇文章,谢谢!
很棒的列表。我正在考虑使用 :after 来在标题文本下方创建一条线,这条线的宽度将小于文本。
从没想过要玩这种把戏,太酷了!
很棒的文章!它真的帮了我很多。谢谢!!!
克里斯,:after 和 ::after 之间有区别吗