纯CSS 回形针情人节标签

标签:
css3transform投影高光情人节回形针box-shadowgradient渐变背景 |
分类: CSS3 |
这算是一个迟来的礼物,idea是情人节那天萌发的,登录QQ的时候,发现它的软件banner是一对恋人牵手依偎,执子之手,与子偕老的标题。然后还有一个标签悬挂着,看了之后想了下,觉得可以用css画出来,于是乎新作品就诞生了,写了webkit的兼容,发现了一个很奇怪且神奇的问题,以前都没注意,下面会说,这里买个关子哈...
先看看成品图先:
你可以通过这个链接下载我的页面:《纯CSS 回形针情人节标签》
为方便下载,提供本人网盘帐号密码,请不要弄乱里面的页面,以方便其它人下载,谢谢。
密码:123456
下面开始分析里面的亮点难点,由于moz跟webkit类似,下面代码均以moz为主:
一、回形针
1)HTML结构
这个应该算是里面最大的亮点,比较是花了最长时间写的,具体的html结构是这样的:
<div class="clip">
</div>
结构用firebug看下就清楚的,这里就不解释了。
2)底色
可能你看了上面的回形针之后,会觉得我是把背景挖空,然后border-radius做的,其实不是的,我是用背景background。 因为用border获取不到一个完美的半环,而且我觉得border的话,弧度的处理会起锯齿,不过刚试了一下,是没有锯齿的,我多虑了,但是构造不出半环这个致命缺陷导致了我还是选取background来做。具体的代码如下:
background:-moz-radial-gradient( 21px
bottom,circle,rgba(100,100,100,0) 14px,red 15px,red
19px,rgba(100,100,100,0)
20px);
如果你对css渐变有疑问的话,可以参考我这篇文章《CSS3线性渐变》,里面对有比较详细的描述。
上面的代码是一个径向渐变,以底部左偏移21px为中心,画一个圆形,这样就有一半超过底部给隐藏,从而获取到需要的上半圆。我预定是想画一个5px宽的环,一般是这样写的:
rgba(100,100,100,0) 15px,red 15px,red 20px,rgba(100,100,100,0) 20px
这样就很清晰的获得了一个5px宽的环,但是问题就是它太清晰了,清晰到起了锯齿,如下:
所以我用了下面这样的写法:
rgba(100,100,100,0) 14px,red 15px,red 19px,rgba(100,100,100,0) 20px
这样在透明与环之间有1px的过渡,从而消除了锯齿,效果如下:
以上是半环的写法,还有竖状的没完成,这个自然而然的会用到线性渐变,具体的代码如下:
background:-moz-linear-gradient(left,rgba(255,255,255,0) 0px,red 1px,red 5px,rgba(255,255,255,0) 6px,rgba(255,255,255,0) 34px,red 35px,red 39px,rgba(255,255,255,0) 40px);
从左向右拉一个‘红-透明-红’的线性渐变,同样做一个1px的渐变过渡,与半环相应,让它看起来更平滑。
3)高光
不过这仅仅是做了一个底色而已,看起来很“扁”,还得做个高光,让它立体些。所以我用伪类before来写高光,具体代码如下:
background:-moz-radial-gradient(
bottom,circle,rgba(255,255,255,0) 16px,rgba(255,255,255,0.5)
17px,rgba(255,255,255,0) 19px);
background:-moz-linear-gradient(left,rgba(255,255,255,0)
2px,rgba(255,255,255,0.6) 3px,rgba(255,255,255,0)
4px,rgba(255,255,255,0) 36px,rgba(255,255,255,0.6)
37px,rgba(255,255,255,0) 38px);
上面的是半环的高光,下面的是直条的高光,因为如果用1px来做高光的话很细很生硬,所以还是用一个过渡的写法,让它尽量显得柔和自然。可以看成底色的一个宽度缩小版,完成后效果如下:
4)阴影
既然有了高光,那就写多个阴影,但是问题就出来了,正常的高光、底色、阴影应该是这样的一种叠加状态:
高光最上,阴影最下,底色居中,然而我上面把底色写在了div上,高光写在before上,这样看起来没什么问题,但是阴影呢,写在after?伪类层是以基本层为父容器相对定位的,这样定位起来阴影就在底色上面了,这样很矛盾,但是把底色定在after上的话,把页面实际存在的元素作为一个虚拟的阴影,然后把伪类写成实际存在的底色构成,结构很怪很畸形,这样如果后期我要调整阴影的方向,大小,就很被动了。从机动性来分析还是对应的加多几个div来做阴影会好很多,但是从页面构成来分析,这样的写法会简约很多,为了结构清晰,我还是把底色该在after上,毕竟它不存在“后期调整”的范畴了哈...
具体阴影的写法如下:
background:-moz-radial-gradient(
bottom,circle,rgba(255,255,255,0) 12px,rgba(0,0,0,0.5)
15px,rgba(0,0,0,0.5) 19px,rgba(255,255,255,0) 22px);
background:-moz-linear-gradient(left,rgba(255,255,255,0)
-2px,rgba(0,0,0,0.5) 1px,rgba(0,0,0,0.5) 5px,rgba(255,255,255,0)
8px,rgba(255,255,255,0) 32px,rgba(0,0,0,0.5) 35px,rgba(0,0,0,0.5)
39px,rgba(255,255,255,0) 42px);
跟高光的写法差不多,不过把rgba(255,255,255,0.6)换成了rgba(0,0,0,0.5),渐变过渡拉开3px,让阴影铺得更开。加上阴影后效果如下:
看起来立体了很多,不过看起来怪怪的,阴影还是怪,我们习惯“光影左上,阴影右下”的模式,所以把阴影再调整一下,让它往右下移一点,效果如下:
立体感又增强了,到此回形针制作告一段落,然而,真的只是这样吗? 如果是上面贴出来的代码的确是这样的,但是假如把回形针放在深色背景上,问题就出来了,如下:
阴影在灰色底色上感觉不出什么问题,但是在深红色底色上,感觉白蒙蒙的一圈,很碍眼。问题出在过渡这里
rgba(255,255,255,0)跟rgba(0,0,0,0)都是表达一个透明色,但是本质上是不同的,前者是白色透明,后者是黑色透明,在单用的时候效果一样,但是在配合其它颜色、渐变度的时候,效果是截然不同的,也许我这样说你可能感觉有点抽象,我用Photoshop举个例子你就应该会明白了,如下:
这个是白色不透明到白色透明的渐变(很纯净的渐变)
这个是白色不透明到黑色透明的渐变(中间就有一段灰色半透明的渐变)
这个是黑色不透明到黑色透明的渐变(同样很纯净)
这个是黑色不透明到白色透明的渐变(视觉上这里渐变比上面的要短一些,因为中间有段灰色半透明的渐变)
现在你应该知道那圈白蒙蒙的东西是怎么出来的吧,知道了它出来的原理,要整掉它就容易了,如下:
background:-moz-radial-gradient( bottom,circle,rgba(255,255,255,0) 12px,rgba(0,0,0,0.5) 15px,rgba(0,0,0,0.5) 19px,rgba(255,255,255,0) 22px);
只要把阴影里面的rgba(255,255,255,0)换成rgba(0,0,0,0),让它的渐变颜色变得纯净即可。同样修改linear里面的,这样就不贴代码了,修改后效果如下:
如果你有下载我的代码的话,你会发现我底色是这样写的:
background:-moz-radial-gradient( 21px bottom,circle,rgba(100,100,100,0) 14px,red 15px,red 19px,rgba(100,100,100,0) 20px);
为什么用rgba(100,100,100,0)而不是用rgba(0,0,0,0)或者rgba(255,255,255,0),因为如果用纯白的话,底色到透明的渐变中间会有白色锯齿出现,而用纯黑的话,彩色底色的周边会很深感觉像是描边,所以用一个透明灰色,起到分割主体与阴影的作用,同时又过渡自然,有时候一些不经意的细节,也许就可以让作品上一个档次,细节体现专业,因为留意多一些细节,所以更专业。
5)彩色
单用一个红色未免太过单调,那么就多做几个颜色,回到最初,也许你会觉得高光、底色为什么不合并写一个渐变就可以了,这样多出来一个before可以写多一些东西细节,比如:螺旋纹(因为目前没有很好的兼容蒙板语句,所以这个效果没有实现),但是如果把底色跟高光写到同一个渐变里面的话,换颜色的时候,不变的高光要重复写多一次,这样重用性太差,所以我选择分开写,在定义新颜色的时候,我只要重写底色就可以了,具体代码如下:
<div class="clip orangeClip"></div>
利用类权重覆盖样式,继承框架,覆盖背景,实现彩色回形针的制作,而其它背景颜色定义很简单,把你想要的颜色设定好,复制一份原稿,ctrl+f打开对话框,进行相应“替换”的替换即可。
至此,回形针的制作便告一段落。
二、标签
标签页的制作技术含量就没回形针那么高, 不过还是有亮点的,具体代码如下:
<div class="paper">
</div>
具体效果如下:
以红色标签为例,我在右下角画了一个黑色圆圈,表示这是一个值得留意的细节, 具体代码如下:
-moz-box-shadow:0px 0px 5px rgba(0,0,0,0.5),inset 0px 0px 1px
rgba(255,255,255,0.8);
background:-moz-linear-gradient(left
top,#f4e68d,#c28032);
在外容器paper拉了一个左上到右下,由深到浅的金色渐变,然后用box-shadow写双层阴影,一个大的标签投影,另外一个用inset 1px内发光,模仿边缘高光效果。而内容器paperInner的代码如下:
-moz-box-shadow: inset 0px 0px 3px rgba(0,0,0,0.6),0px 0px 1px
rgba(255,255,255,0.8);
同样用box-shadow写双层阴影,不过这里是实现一个1px外发光,然后用inset实现内投影,这样一个金色内凹边框视觉效果就出来了。
至于paperInner的background是这样写的:
background:-moz-repeating-linear-gradient(left,#e11224,#e11224
1px,#991b1e 1px,#991b1e 3px)
moz有一个很有意思的repeat效果,可以用来实现重复平铺,平时用的很少,但是效果很棒,上面代码的意思就是0px-1px是#e11224,1px-3px是#991b1,然后就按照这样的长度比例repeat,实现一个抽丝效果。文字的话用text-shadow写,这里就不分析了。
三、绳子
绳子是一个叫rope的div,设定好宽高,然后设置圆角、边框如下:
-moz-border-radius:500px/110px; border:3px solid rgba(255,255,255,1);
让它变成一个3px白色边框的椭圆,跟回形针一样,如果把底色放在div上,投影就没法做了,所以我把它放在伪类上,div本体用来写阴影,这样的阴影与本体可以拉开,产生距离感,视觉上绳子就像悬挂着一样,比box-shadow写出来的阴影立体感要强很多。
因为回形针是要挂在绳子上面,所以必然有一块要给遮挡住,如果中规中矩的做的话,要把绳子“穿过”回形针,这样结构就复杂了,所以我只是写了4个div,把背景设定成白色,通过定位遮挡住回形针一角,这样看起来就像是挂在绳子上面了。
四、怪事
我在写效果的时候都只是在FF里面写,但是到了写webkit兼容的时候,发现了一些问题,比如,写径向渐变的时候,moz的过渡可以支持像素定位,而webkit只能用百分比,或者小数(其实也是百分比),我在moz里面一大堆精确的定位拼接,到webkit改得很吃力,我是开个windows自带计算器来转的,加上我在“调整阴影”的时候做了一些像素偏移,尺寸变更,改起来很伤脑细胞。不过还好webkit支持的小数很精细,所以做出来的效果基本跟moz一致,我顺手写多了一个shake的小动画。
上面是不支持像素级定位让我头疼,接着就是奇怪的事了,我看《CSS3 实战》,里面只是说到moz有repeat重复铺展的语句,没有说webkit有,我原以为要重新写一份webkit的抽丝效果出来,不料我玩似的把抽丝的moz改webkit后保存运行,效果居然出来了,我当时震惊了,然后我用一个普通的moz线性渐变,把moz改成webkit测试下,居然也可以显示,比如:
<div class="testDiv"></div>
.testDiv{ height:200px; width:200px;
background:-moz-linear-gradient(top,red,green);}
这样一段代码,很明显是moz的线性渐变写法,在FF显示效果如下:
然后我把背景色改成这样:
background:-webkit-linear-gradient(top,red,green);
在chrome里面居然能显示(safari也可以),效果如下:
然后我试着把回形针的那些背景直接把moz替换成webkit,回形针在chrome里面照样显示,在惊叹webkit强大的同时我郁闷了,坑爹啊,我用计算机算到我脑细胞都快死光了,居然这样就可以兼容webkit了。但是这样FF是读不到的:
background:-moz-gradient(linear,0 0,100%
100%,from(red),to(green));
如果你有什么看法或者好的建议,欢迎在我文章留言,感谢你的关注哈...Just for love...