如果说我最喜欢我所做的事情中的一件事,那就是解决设计师抛给我的挑战。几乎总有一种方法可以用代码重现设计,我喜欢找出如何使用 CSS 尽可能接近原始设计。
最近,我们在 Sparkbox 的创意总监 Drew 让我为一个电子商务网站构建一个设计。该网站有一个元素,有点像星爆形状,其中包含产品价格。由于它包含动态价格,因此该元素必须相应地增长和调整,因此我着手使用 CSS 构建它。
分解设计
所以我们开始了。我们有一个相当尖锐的圆圈,里面是产品价格。(还要注意 Drew 在这里使用的微妙的内边框。我们稍后会讨论它。)我采用了这个设计并制作了这个
我知道它并不完全相同——它有几个较少的“点”——从技术上讲,我可以用更多的标记来实现,但我认为少用一些标记和减少一些点是值得的。让我们一起了解这里发生了什么。
可视化这里发生的事情
将此星爆视为一系列旋转的方块。我理解这里发生的事情的方式是使用一些便利贴。看看
所以我这里有三个元素,每个元素旋转 30 度。(在最终设计中,我实际上将有六个元素,您会看到……)
标记
<div class="price-container">
<div class="price">
<span class="label">Buy</span>
<span class="number">$15.00</span>
<span class="label">Now</span>
</div>
</div>
我有 <div class="price-container">
,它包含价格星爆。我将将其用作星爆的背景。<div class="price">
是内部文本(价格信息)的容器。这就是标记的全部内容。从这里开始,我将使用伪类来创建多个点。此外,我之前提到过 CSS 版本的星爆中有一些较少的点。此标记中没有任何不必要的元素。
设置样式
现在进入有趣的部分。让我概述一下我将要做什么,然后我会向您展示实现它的所需样式。我将设置 .price-container
、.price
以及每个元素的 :before
和 :after
伪元素的样式。本质上,我有六个元素可以使用。我创建了这个背景图像以应用于每个元素,并且我将每个元素旋转 15 度
如果您回顾上面便利贴的图片,请注意我如何用铅笔绘制内边框。拆卸便利贴模型给了我一个看起来像这样的部件。
所以这里列出了每个元素的样式(注释应该可以帮助您理解这里发生了什么。我还在下面提供了一些注释。)
.price-container,
.price-container:before,
.price-container:after,
.price-container .price,
.price-container .price:before,
.price-container .price:after {
height: 8.5em;
width: 8.5em;
background: #760B1F url(price-bg.png) top left no-repeat;
background-size: 8.5em;
}
.price-container:before,
.price-container:after,
.price-container .price:before,
.price-container .price:after {
content: "";
position: absolute;
}
.price-container {
margin: 100px auto; /* Centering for demo */
position: relative; /* Context */
top: 2.5em;
left: 2.5em;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.price-container:before {
top: 0;
left: 0;
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
}
.price-container:after {
top: 0;
left: 0;
-webkit-transform: rotate(-15deg);
-moz-transform: rotate(-15deg);
-ms-transform: rotate(-15deg);
-o-transform: rotate(-15deg);
transform: rotate(-15deg);
}
.price-container .price {
padding: .5em 0em;
height: 7.5em; /* height minus padding */
position: absolute;
bottom: 0;
right: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
z-index: 1; /* important so the text shows up */
}
.price-container .price:before {
top: 0;
left: 0;
-webkit-transform: rotate(60deg);
-moz-transform: rotate(60deg);
-ms-transform: rotate(60deg);
-o-transform: rotate(60deg);
transform: rotate(60deg);
}
.price-container .price:after {
top: 0;
left: 0;
-webkit-transform: rotate(75deg);
-moz-transform: rotate(75deg);
-ms-transform: rotate(75deg);
-o-transform: rotate(75deg);
transform: rotate(75deg);
}
关于样式,我将指出几点
- 注意旋转角度的顺序:此顺序很重要,因为最内层元素内将有文本。因此,最后一个元素(文本所在的元素,在本例中为
.price
)必须是直的。请注意,.price-container
旋转 -45 度,而.price
旋转 45 度——回到 0。 - 高度和宽度:由于我们在这里处理背景图像,因此必须设置高度和宽度。我已将其设置为 em,以便在文本大小增加时进行适当调整。
.price-container .price
有顶部和底部的填充。这就是为什么高度与所有其他元素略有不同的原因。- 所有内容都绝对定位在第一个容器内。
.price-container
有left: 2.5em
和top: 2.5em
,只是为了稍微移动整个元素。当所有内容都旋转时,角会稍微超出页面和容器。 - z-index:为
.price-container .price
定义了z-index
。这样,此 div 内的价格信息就可见。
现在剩下的就是设置文本样式了。
.price-container .price span {
position: relative;
z-index: 100;
display: block;
text-align: center;
color: #FE3D5C;
font: 1.8em/1.4em Sans-Serif;
text-transform: uppercase;
}
.price-container .price span.number {
font-weight: bold;
font-size: 2.5em;
line-height: .9em;
color: #fff;
}
无图像实现
现在,我这里有一些额外的内容,因为设计要求使用这个非常微妙的内边框。如果您不喜欢或不需要内边框,只需删除有关背景图像和背景大小的部分,设计将保持不变。
浏览器支持
这在 IE 9+、Firefox 4.0+、Safari 4.1+ 和 Chrome 3.0+ 中按原样工作。IE 8 及更低版本不支持 background-size,Chrome 1.0、Firefox 3.6 和 Safari 3.0 需要一些供应商前缀。IE8 支持伪元素,但不支持 transform
。
回退将是彩色正方形。很可能不是一个大问题。
就是这样
这是一个价格星形元素。足够灵活,可以在您增加字体大小时进行扩展。使用一些 CSS 制作。
能够用 CSS 制作所有这些东西真的很酷。
但是,由于您需要主图片(正方形)才能开始。直接使用他给您的星爆图像作为背景难道不更容易吗?
如果您想让它可以编辑内部文本,只需克隆原始文本,然后在内部放置文本。
对我来说,这似乎更容易:P。
无论如何,这是一项了不起的编码工作,干得好。
是的,但是那样的话,CSS 或技巧就没有什么意义了,不是吗?:p
转到演示页面,尝试更改文本的大小。看到绘图相应地更改了吗?这就说明问题了!
非常有创意,执行得很好。我经常为徽章制作类似于此的图像,但我们越能从图像切换到完全的 CSS 解决方案越好。边框也很好看。感谢您的撰写!
是的,这太棒了 :)
css3 功能的不错示例,但我必须同意 Zach 的观点,此练习完全没有意义,因为您必须使用图像才能开始。
为什么不使用星形作为背景图像,并在 div 中覆盖您的文本,从而节省大量时间,因为您不必编写额外的 100 行 css,并且结果可以在所有网络浏览器中使用,而不是 4 个?
这太棒了。我迫不及待想尝试一下。从页面加载速度的角度来看,使用 CSS 而不是图像非常棒。
Gary,
他仍然在使用图像……如果他只是使用整个星星的图像而不是仅仅使用它的边框轮廓,页面加载速度不会改变。其他评论者说得对——这个练习对大脑很有好处,但对功能性帮助不大。
很棒的教程。令人印象深刻的是,仅使用 CSS 就能完成的事情。
但是(总有一个“但是”,不是吗?)我认为这个例子不太实用,因为无论如何你都必须创建一个图像,为什么不创建星星作为背景并大大减少 CSS 呢?
不错的教程,有点同意 Zach 的观点,既然你无论如何都在使用图像,使用整个图像并使用 `background-size: 100% 100%` 使其始终水平和垂直拉伸是否更容易?
不要忘记,所有这些都可以完全无图像地完成。在这种特殊情况下,设计需要一个内边框,因此图像解决方案效果最佳。删除背景图像并使用背景颜色将获得相同的结果——在这种情况下,比使用星形图像更灵活。
仅使用 CSS,这真是令人惊叹的东西,几年前这会让任何 CSS 专家都感到震惊,这仅仅表明 CSS 发展了多少,也许将来我们会看到复杂的图案集成到 CSS 中,或者也许所有 Flash 般的效果,或者也许谁知道呢……
看看最近起草的CSS 着色器!
我的大脑被炸开了
令人惊叹的棒极了
嗯,使用 `border-radius` 和 `border-image` 怎么样?不太确定,这是否在这种混合中有效,但我认为应该可以。
与其他人一样,一个完全无图像的解决方案会非常棒。
哦,你忘记在浏览器支持中提到 Opera 了;)
非常好。
干得好!现在,让我们把这个抛在脑后…… :)
让我们先忘记一下图像。并不是说图像不好。图像会比 CSS3 存活更久,我对此毫不怀疑。
我在这里没有看到任何你不能用 SVG 做得更好并在过程中获得更多浏览器覆盖率的东西。
虽然可以用 CSS 完成,但我个人认为,*再次*;),CSS 并不是这里最合适的工具。
作为一个 CSS 练习,作为一个 CSS 挑战,毫无疑问,它有其优点。然而,最终产品未能提供人们期望的整体图形质量。
而这正是这里最重要的部分!不会有很多人欣赏编码技巧,但所有人都将评判最终的图形质量。
因此,如果不是图像,那么 SVG 肯定更适合这种类型的事情。
我想我所说的与我之前的评论有关:困难的部分是决定何时一些 CSS 技巧可以超越成为聪明的概念并证明自己在实际项目中值得使用。
“可视化这里发生的事情”至关重要!很好的类比。
Chris,
虽然这是 CSS3 新概念(transform => rotate)的非常天才的使用,但我检查了最终结果以及你的代码。如果你增加价格的位数,它不会按比例缩放。例如,如果你将 39 更改为 3999,那么一个数字就会从圆圈中掉出来。
如果是这种情况,为什么不使用简单的背景图像呢?
好主意!!!
一个被盗的想法冒充成你自己的,干得好。
http://matthewjamestaylor.com/blog/css3-starbursts
Matthew,
这怎么会是被盗的?本教程使用了与你在共享的文章链接中显示的完全不同的过程。
标题相似,但仅此而已。
我太懒了,不想做,但我相信我们可以找到其他关于创建基于 CSS 的星爆的文章,这些文章比 Matthew 的文章更早。仅仅因为你不是第一个记录一种方法并不意味着你偷了任何东西。
这是一个想法。更新你的文章,添加指向 Chris 的帖子的链接,并将指向你帖子的链接放在此帖子的评论中。想想这对社区有什么好处。如果你只是为了自己写文章,那么请保护你的博客,这样就不会有人“窃取”内容。
嗯,让我为 Matt 说几句。我在几个项目中使用过(并修改过,有时还滥用过)他的布局和导航菜单,并曾向他咨询过关于它们的使用,他给出了友好而有用的回复。他制作了大量非常好的材料,这些材料都是免费下载的,只附带了一个通用的“如果你愿意,请捐赠”请求。
因此,对他进行责备,要求他保护他的博客的隐私,以防止任何人“窃取”他的材料,这纯粹是胡说八道。他和 Chris 都提供了大量的材料供大家获取,我认为这都是出于对设计/开发的真诚热爱以及慷慨和“回馈社区”的精神。
对于星爆,Chris 的方法与 Matt 的方法完全不同。但是,这些概念足够相似,可以说 Chris 应该在帖子中承认 Matt 的工作——如果他知道的话,他可能根本不知道——。Matt 可能可以使用比“偷窃”更不尖锐的词语,因为 Chris 没有偷 Matt 的作品。
这应该可以解决问题了。退下,伙计们。
这是真正的 Matthew James Taylor……
我只是想指出上面关于“偷窃”的评论不是我发的。它是由一些冒充我的人添加的。很遗憾,人们可以冒充别人,让人看起来很糟糕。
Chris,有没有办法更改他的评论,使其看起来不像是我发的?顺便说一句,我实际上非常喜欢你的工作和奉献精神,我太懒了,无法像你一样多产!;)
没问题。干杯。
哈哈,先在几张矩形纸上画出来真是个好主意!
这真是太棒了!我不敢相信像Ryan Buttrey这样的人存在。
说真的,你们不断想出创新的 CSS 东西。没有人能称 CSS 为一种简单或基础的语言来学习。CSS 应该像 PHP、ASP.NET、C++ 或汇编语言一样被掌握。
太疯狂了,尽管我只是用一张图片,因为我懒惰:)
很有创意,喜欢它 :)
我喜欢发现随机的酷炫的东西,尤其是与 CSS 相关的,所以这很符合我的要求。
感谢分享你的想法,现在我要在其中加入一些时髦的悬停旋转和颜色变化。
Simon
K2Joom.com
太棒了。我想知道是否有办法将 CSS 渐变加入其中。
如果你添加一些无意义的标记,你应该能够为现代浏览器完成即使是内部边框版本的无图像版本。假设两个带有类名 innerborder-1 和 innerborder-2 的 div 容器,它们与它们的伪元素一起是六个绝对定位的块,具有透明背景和浅棕色边框。然后让其中一个跨度成为一个带有棕色背景的圆形块,以覆盖内部星星内的边框。
你总是可以争论是否保存一个 http 请求值得拥有额外的标记以及对 css2 回退的需求,但我不确定它是否不会!
有趣的帖子,我特别喜欢用便利贴进行可视化的概念!
太酷了。
我不确定我是否会用到它,因为星爆有点俗套,但我纯粹从“编码乐趣”的角度来看,很喜欢阅读这样的文章。克里斯,干得好——一篇非常有启发性的文章。
我只能说这真是太棒了……
大家好,我注意到很多人都在称赞和批评克里斯这篇文章。我只是想说克里斯没有写这篇文章。它是Ryan Buttrey的客座文章。
为什么???
纯粹的好奇心,为了证明它可以做到,为了实验,为了纯粹的乐趣,为了提供挑战,为了突破编码的界限,等等等等。但这只是我的猜测。
你疯了哈哈(当然,是好的方面)——你一定玩得很开心,制作这些东西。即使有些东西用CSS(以及这些技巧)还无法实现,但看看你是如何完成它的仍然很有趣。在我的一些帖子中,当人们错过这一点时,我觉得很有趣。无论如何,这真的很酷。干得好!
很棒的优惠,
我可以在我的Joomla网站上使用它吗?
这似乎是CSS的另一种误用。我认为我们必须记住,CSS不应该用于生成内容;而是用于对其进行样式设置。否则,这是一个非常牵强的“巧妙”CSS编码示例。我宁愿看到更多CSS2和CSS3的良好和适当用法……也许与SVG结合使用,以保持事物令人兴奋,而无需发明和强化不良编码。还有关于XSLT和CSS等内容需要讨论。
我想看到更多真实/有用的代码,就像CSS-Tricks的旧时光一样。否则,我对这个网站的支持正在急剧下降。