在 BERG 云 上的按钮看起来很漂亮。这不是什么大不了的事,但它们创建它们的方式使用了两个单独的图像(而不是精灵图)和两个内部跨度。在本教程中,我们将使用一些现代技巧来重新创建它们。我们不会使用任何图像(更高效),更少的标记(更语义化),并且功能更平滑(没有 JavaScript 控制状态)。
以下是我们要尝试重新创建的原始按钮

以及我们的最终结果 在 CodePen 上
简单的标记
链接就是链接。
<a href="#" class="button blue">
Find Out<br>More
</a>
在我们的例子中,除了 “button” 之外,我们还有 “blue” 类。这种简单的事情值得讨论。首先,在 “现实世界” 中,我只需使用 “button” 类就可以完全正常运行。它将是网站上最常见的按钮样式。然后为了处理变化,过去我添加了额外的类,就像上面显示的那样。第二个类将处理覆盖。我可能会像这样写它们
.button.blue {
/* overrides */
}
但我开始认为这不太好。该按钮的特殊性是原始按钮的两倍,并且使用了没有独立值的类。最近我看到了几个使用单个类名进行变体的代码库,例如 “button-blue” 是唯一的类名,并且让它完成所有工作。在常规 CSS 中完全可行,但在 Sass 中使用 @extend 会更容易。例如
.button {
/* Styles for basic button */
}
.button-blue {
@extend .button;
/* overrides */
}
超级干净的创作,不臃肿的输出,以及与任何其他按钮具有相同 特殊性 的单个类名。我同意这一点。
神圣的 box-shadow!
这里发生的主要事情是在内联块链接上层叠了 box-shadow。如果创建了一个在两个方向上偏移 1px、模糊为零的阴影,则可以本质上在方框的两个边缘创建 1px 边框。如果再次使用相同的偏移方向但偏移 2px,则会开始形成一条斜线并为方框赋予一些伪深度。如果这样做六次,您将获得一个看起来相当厚实的按钮。
现在,如果您将它加倍并交替颜色(左侧偏移获得一种色调,底部偏移获得另一种色调),则可以模拟一些灯光。
.button {
box-shadow:
/* Left Side */ /* Right Side */
-1px 0px 1px #6fadcb, 0px 1px 1px #54809d,
-2px 1px 1px #6fadcb, -1px 2px 1px #54809d,
-3px 2px 1px #6fadcb, -2px 3px 1px #54809d;
/* etc */
}
使用相同的技术,但反转方向并从边缘停止的地方开始,您可以使用非常柔和的透明黑色来创建真实外观的阴影。在上面添加一个带柔和透明白色的内阴影,它会加强光线照射到按钮的错觉。
.button {
box-shadow:
/* Sides */
-1px 0px 1px #6fadcb, 0px 1px 1px #54809d,
-2px 1px 1px #6fadcb, -1px 2px 1px #54809d,
-3px 2px 1px #6fadcb, -2px 3px 1px #54809d,
/* etc */
/* Shadow */
-6px 7px 0 rgba(0, 0, 0, 0.05),
-5px 8px 0 rgba(0, 0, 0, 0.05),
-3px 9px 0 rgba(0, 0, 0, 0.04),
/* etc */
/* Light & Top Edge */
inset 0 4px 5px -2px rgba(255, 255, 255, 0.5),
inset 0 1px 0 0 rgba(0, 0, 0, 0.3);
}
我相信大家都可以想象 Sass 以巧妙的方式帮助完成这项工作。计算色调、循环、颜色变量、更紧凑的语法等等。
更多 CSS!
按钮的正面是一个非常微妙的渐变(再次有助于照明)。没问题。最好将渐变应用于按钮的基本类,然后覆盖它以进行变化。
.button {
/* ...shadows ... */
background: linear-gradient(#a2d3e9, #7abedf);
}
按钮内的文本带有一点阴影。用 text-shadow 很容易。只要确保阴影与背景相符。我们制作了两个按钮变体,本质上我们需要覆盖黄色变体上的所有颜色,因为它是在深色背景上的浅色,而不是在浅色背景上的深色。
.button {
/* ...shadows ... */
/* ...background ... */
text-shadow: -2px 2px 0 rgba(0, 0, 0, 0.2);
}
当然,这些按钮上还有很多其他 CSS 属性,就像您所期望的那样。例如,关闭下划线、文本颜色、设置间距以及其他显而易见的事情。
交互
在原始按钮中,当您点击或点击按钮时,JavaScript 会应用 “active” 类,这会触发 “按下” 动画。这有点笨拙,因为按钮可能会卡在这种状态。尝试点击按钮,然后将鼠标移开并松开。按钮保持按下状态。如果它们执行了诸如在鼠标移开时删除 active 类之类的操作,则可以解决这个问题,但是,我们不必担心这个问题,因为我们可以在 :active 上触发按下状态,在 :active 中,我们会自动获得所有交互详细信息。
我们的交互将是相同的按下动画,其中
- 删除所有 box-shadow,使按钮看起来平坦
- 按钮被移动到看起来像表面的位置
非常简单。
.button {
/* ... styling stuff ... */
/* interaction */
transition: all 0.1s linear;
transform: translateZ(0);
}
.button:active {
box-shadow: none;
transform: translate3d(-6px, 6px, 0);
}
过渡完成了大部分工作。应用后,box-shadow 会慢慢消失,而不是立即消失。在此过程中,我们将移动按钮。我们可以对按钮进行相对定位,并使用 top/left 值将其推动。这样做的问题在于
- 它混淆了定位和交互问题。如果按钮被绝对定位,它很快就会变得很奇怪。没有 top: where-its-at-plus-10;
- 它的性能不如使用
translate移动好。
要注意的第二件事是使用 3D 变换。我们正在使用 3D 变换属性,但实际上没有进行任何 3D 变换。我们这样做是因为
- 它会启动 GPU 并获得更平滑的性能。
- 它会使按钮的 *默认状态* 中的文本变得模糊(变细),因此当过渡开始时不会感到意外。
WebKit 有一个很糟糕的(我认为是 bug)问题,即被转换/过渡的文本看起来很细而且很糟糕。我之前尝试过 不令人满意地 解决这个问题。我的朋友 Koop 曾经很好地总结了这个问题,他说 “你只需要决定哪种更糟糕”。选项 A) 让文本一直模糊,这样就不会出现尴尬的屏幕闪烁和文本重量的变化。选项 B) 忽略它。默认情况下文本看起来很好,但当按钮处于过渡状态或被转换时,会出现闪烁和变细。
在这些按钮上,它相当引人注目。


在这种罕见的情况下,我更喜欢变细的版本,因此两全其美。
箭头
在我第一次尝试创建这些按钮时,我用两个跨度创建了箭头。它运行良好,但与原始版本相比,语义改进并不大。Neil Kinnish 复制了我的 Pen 并使用伪元素创建了箭头,这意味着我们又回到了只使用快乐的锚链接。我后来用他的代码更新了我的 Pen。你会认为我的脑海里会直接想到伪元素,因为我以前专门做过关于它们的演讲,而且我 长期以来一直吹嘘 它们的出色之处。我知道在 WebKit 中你仍然不能转换伪元素,但我认为你也不能转换它们。要么我一直错了,要么这是一个比较新的功能。
诀窍是使用两个免费元素来创建一个小的黑色矩形,并将其绝对定位在按钮的右侧(由于 padding,那里总会有空间)。一个小黑矩形旋转 45 度(通过 transform),另一个旋转 -45 度。当它们嵌套在跨度中时,设置 filter: drop-shadow() 最有意义(只应用于顶部跨度),但现在使用伪元素,box-shadow 在两者上都工作得一样好。
.button:after, .button:before
position: absolute;
content: "";
right: 15px;
top: 14px;
width: 6px;
height: 18px;
background: white;
transform: rotate(-45deg);
display: block;
z-index: 2;
}
.button:before {
height: 14px;
top: 26px;
right: 16px;
z-index: 3; /* on top */
transform: rotate(-137deg); /* hey, it works */
filter: drop-shadow(0 -2px 0 rgba(0, 0, 0, 0.15));
}
.button:After {
filter: drop-shadow(-2px 0 0 rgba((0, 0, 0, 0.2));
}
同样,您需要调整所有颜色以适应不同的按钮变体。但定位将相同。
完成
以下是最终结果 在 CodePen 上
另外:OMG 微型打印机太可爱了 #想要。
正如预期的那样,点击效果在移动设备上不会发生,但按钮仍然完全可用 - 看起来是一个不错的技术。
非常酷,我喜欢这些按钮的样式!我可能需要在我的下一个项目中尝试一下。
这些很棒。一种摆脱 Apple 风格的新鲜风格。
是的,你是对的。哈
写得更少,做更多,无需 jQuery >> 好的代码
我的天啊!单击时的动画让我起鸡皮疙瘩 :) 我太印象深刻了,立刻把它放在我的网站上。真的很酷。谢谢
嗨 Chris – 很好的介绍。
我很好奇你**具体**不喜欢
.button.blue的权重比.button高出两倍的原因。你预见到这样做的缺点是什么?我的意思是,你想让.button.blue作为.button的变种,所以它更具体是件好事,不是吗?另外,我**真的很**想要一台小打印机。
很酷的效果,但我认为这是 UI 装饰,而不是 UI 设计。使用这些按钮在 UI 中移动会感觉缓慢而沉重。
在 IE9 中现在看起来有点奇怪/降级效果不好。也许 IE10 会更喜欢它?=)
*PS 我不是在故意找茬,我感谢这个演示展示了我们使用 CSS3 的方向,只是目前还没有看到实际的应用。不过,正在接近中!
给黄色的按钮添加了边框。
http://codepen.io/joe/pen/LAcaz
我用一个伪元素(使用旋转的正方形和两个边框)实现了几乎相同的箭头。演示在这里:http://jsfiddle.net/vVeqr/
顺便问一下 Chris,这个 -137deg 是什么?看起来像是魔法数字!:P
当我看到它时,我的想法也和你一样,尽管我可能会用一个更小的正方形和外部阴影(语义较差)。
我唯一看到的问题是,对箭头进行任何额外的演示更改可能不会那么容易。例如,我无法看到一种简单的方法来为箭头创建内阴影,就像 Chris 的示例中那样。
等等,他的示例没有内阴影。我的眼睛在欺骗我,哎呀!
你实际上可以添加内阴影,方法是偏移一个比箭头更暗的阴影,使其位于箭头后面,从而形成阴影。
很好地使用了
box-shadow。看到它们具有的边框,我添加了这行代码
border: 1px solid rgba(black, 0.3);到
button类中,它为主要边缘添加了一些不错的定义。http://codepen.io/Druid-of-Luhn/pen/fiDlE
不错的技巧,将不透明度降低了一点点。
尝试添加一个不错的微妙的 3px 边框半径
border-radius: 3px;
;)
好吧,不过可能性是无限的
我可以在那里坐一整天,不停地点击这些按钮!
这些按钮的触感和外观都非常棒,非常感谢代码!
您好,
效果很棒,
Opera 和 Chrome 之间的效果不同。Chrome 正常,但在 Opera 12.10 中,点击时,按钮没有被按下,而是阴影移动到了表面上。
当然,我会在下一个项目中使用它 :)
还有其他人看到字母在移动时模糊不清吗?还是只有我?这在 BERG 的按钮上似乎没有发生。
有没有办法让字母的移动更加平滑?
非常酷.. 并且在 Google Chrome 中完美运行
太棒了,我刚刚在这个网站上使用了它,但没有那么精致。
盒子阴影绝对起到了很大的作用。
有没有可能只发布这些按钮的普通 CSS?我快要放弃将 SCSS 转换为 CSS 了。这要了我的命!我只是想将一些样式放到网站上!(O_o)
嘿 triune,使用 Codepen 做这件事非常简单,如果你点击面板顶部的 CSS,这里
https://www.evernote.com/shard/s258/sh/ad9ff3b7-8632-45b8-850a-ddce53af7877/3f06554fe8ecf4e00e75f764a611a33c
你会得到这个
https://www.evernote.com/shard/s258/sh/074103d4-e6e1-4ad4-8c64-51a78e51ef30/1e4039f46c48236fcb142a998e4e7f21
我的天啊,太简单了!我几乎觉得自己很蠢,没有发现它!非常感谢!另外,为那些超级顺滑的按钮点赞!
非常棒的文章,绝对帮助我理清了一些思路
很棒的文章!我认为我会在正在进行的一个项目中尝试 BERG 风格的概念。看到 SCSS 在实际中的应用也很有用。我需要学习它。
Chris,非常感谢你。你总是让我惊叹不已。提醒一下:在交互部分的代码示例中
应该是
已修复,谢谢!
您在 IE 8 或 9 中看到它们了吗?
我不得不承认… 每隔几个月我都会回到这个页面,只是为了再点击那些按钮几次。太顺滑了… ;)