关于Google圆角高光高宽自适应按钮及其拓展

一、前言
对于一门技术而言,要想达到真正的高度,需要形成自己关于这门技术的世界观。我在研究css上花费的功夫相对多些,但还不至于形成css世界观的程度,css是如此精深的一门学问,不仅仅是一门技术,更融入了美学,哲学的东西。当然,对于css,我是有自己的一套约束准则的,请允许我称之为“鑫三无准则”,即无浮动,无宽度,无图片。这是为了css的模块化以及可扩展性需要尽量遵守的准则。然而,现有国内各类大大小小的网站,做到这一点的有多少呢,很少,而且各个网站差距很大。即使国内前列的互联网公司网站的css代码也是有明显的档次之分。
如果要学css,不建议看淘宝网,其css估计维护改动颇多,已是千疮百孔,hack巨多。人人网、新浪博客可以说算是css不错的网站,一个一个分析其css用意,会学到很多东西的。而谷歌可以说是css最精深的网站了,其网站css技术含量真是很高,新浪,人人,腾讯之类与其不在一个档次。更准确的说是与谷歌网站相比,新浪之类的网站没有一个很贯彻的css理念,也可以称为css的世界观。谷歌网站将css的可维护性,css的前瞻性发挥到极致,如何极致法?好,这里我就拿Google(谷歌)上的看似普通的按钮阐述谷歌网站css的技术强在哪里,为何说其css的前瞻性发挥到了极致。本文后半部分根据总结的一些相关启示,重新付诸一些优化方面的实践,将本文主题意义推到可实践性的高度。

二、目录
1. 关于Google圆角高光高宽自适应按钮
①如何用高效的css代码实现
②此按钮的优点在何处
③给我们的启示
2. 关于虾米网全选等圆角阴影宽度自适应按钮
①原按钮分析
②如何用纯粹的css实现
③css实现的按钮的优点

三、内容
1. 关于Google圆角高光高宽自适应按钮

首先,来看一下这个所谓的其貌不扬的按钮是个什么样子:

谷歌gmail邮箱中出现的圆角高宽自适应按钮

谷歌gmail邮箱中出现的圆角高宽自适应按钮

网上有句话很流行,叫做“我很丑,但是我很温柔!”这句话的境界与这个其貌不扬的按钮可谓一致,乍看这个按钮,很普通,第一反应是制作很简单嘛——打开photoshop,拉个2像素圆角的圆角矩形,渐变填充即可。但是,用firebug一看此按钮的“内心深处”,额!惊住了,全是css代码构成的,没有一丁点的图片,从圆角,到高光渐变全是css实现。更难能可贵的是这个按钮不仅宽度自适应,高度也自适应,而且可以与文字,图片混排。但是我不建议您用firebug去看其按钮实现,原因在于这个按钮已经融入在整个页面的体系中,其HTML以及css代码是相当复杂的,或许其中还牵涉到JavaScript——按钮是全div标签实现,其鼠标经过样式必定借助于JavaScript实现(考虑到IE6),而且实际上的层级无需firebug看到的那么复杂。
这里将提供经过自己反复试验,可以说是相当精简高效的css代码(方法多种,这里仅提供认为最好的方法)实现上图所示的按钮效果,并针对css样式提供一系列具体的分析,所涉及到的一些分析都是网上很少有的。

①如何用高效的css代码实现
关于此按钮的实现,您可以狠狠地单击这里:demo实例页面,里面有按钮效果展示,以及css代码的展示。
首先,看一下在各个浏览器下的最终效果:
仿Google圆角高宽自适应按钮在各个浏览器下的表现
这里是实现此效果的css代码:

.g_a{display:inline-block; border-width:1px 0; border-color:#bbbbbb; border-style:solid; vertical-align:middle;}
.g_b{float:left; background:#e3e3e3; border-width:0 1px; border-color:#bbbbbb; border-style:solid; margin:0 -1px; position:relative;}
.g_c{display:block; line-height:0.6em; background:#f9f9f9; border-bottom:2px solid #eeeeee;}
.g_d{display:block; padding:0.1em 0.6em; margin-top:-0.6em; cursor:pointer;}

HTML代码如下:

<a href="#nogo" class="g_a">
     <span class="g_b">
         <span class="g_c">&nbsp;</span>
         <span class="g_d">圆角按钮</span>
     </span>
</a>

css及HTML代码分析:
►原来Google的按钮是使用div实现的,如果要想要让div标签在各个浏览器下实现图文混排,以我现在经验来看,势必用到hack,或多一行css。所以这里我使用inline属性的标签a,span实现效果。inline属性的标签在inline-block属性下能实现类似于inline-block的效果,与支持inline-block的浏览器一起,就可以无需hack实现按钮与图文混排的效果(inline或inline-block属性的元素能与文字同行排列)。
►最外层标签(a标签)css中的vertical-align:middle属性是可选样式,这里添加主要是为了和文字在一起时居中显示,更舒适的布局。
►第二层标签(span标签)样式中的position:relative属性是为了解决IE6下margin负值部分不可见的bug,浮动是为了使IE6、IE7下向左的margin负1像素起作用。
►第三层标签含有两个并列的span标签,它们display属性设置为block是为了自动换行排列且宽度100%显示,当然,您千万不能设置width:100%,否则IE6下会有麻烦的。其中第一个span标签的line-height是为了设置高度,千万不能直接使用height撑开高度,原因在于在IE下,height会使标签有haslayout属性,宽度会撑开,满屏显示的。

②此按钮的优点在何处

★可以与文字混排,对vertical-align属性敏感,见下图:

按钮与文字可以任意混合排列

按钮与文字可以任意混合排列


★宽度自适应于内部文字的个数,高度自适应于内部文字的大小
高度宽度自适应于内部文字大小或个数

高度宽度自适应于内部文字大小或个数


需要提示的是:要想实现高度自适应,内部标签请使用em做单位,文字大小的改变请改变最外层标签的大小,否则只是文字变,而高度不变。em单位大有学问,不是本文重点,不多说,您可以尝试着研究研究。

★支持用css实现鼠标经过样式改变
这是因为最外层标签是a标签,IE6随不支持div标签的hover样式,但是支持a标签的hover样式,所以这里可以直接通过css实现鼠标经过按钮,按钮样式改变的效果。例如,原谷歌gmail邮箱中的按钮的鼠标经过样式是边框颜色的加深,在我提供的demo实例页面中第一部分的第5小项按钮就是实现的这个效果,您可以自己试一试。

★页面性能提成,开发维护成本降低
很显然的,使用几行css代码代替图片实现同样的效果,页面加载的大小更加小了,字符显然比图片要小很多;服务器链接请求次数少了,少一次图片的请求;而且高度也自适应,这是图片难以实现的;如果需要改动,只要改改代码就可以了,不需要再很麻烦的图片处理,保存等,维护成本大大降低。

③给我们的启示
我觉得Google的这个看似普通的按钮的最大启示不在于技术,而是一种意识,一种思想,一种关于css的思想。我们在写很传统的程序的时候,例如C++,很强调代码的可移植性,可扩展性,健壮可读性等,就是说一段代码,要能够预见以后它可能会做的修改,在编写的时候就最大程度的注意这些可能的修改,使得后期的维护更加方便,这种思维在程序开发中似乎很普遍,很是必须的了。然而,css有别于传统的代码,我虽然看到了国内css技术的进步,开始注重扩展性,维护性了,但是程序代码中那种意识似乎还没有贯彻到css中,太多的浅尝辄止。

然而,Google似乎做了一个领跑者,或者说是引导了一个方向,其网页中就深深的有着软件编程的思想。应该很多人都没有注意到,Google的这些产品的页面,不仅宽度自适应,高度也自适应,页面文字大小可调节(比例调节-浏览器,和文字尺寸调节两种),而且无论文字变得多大,其整个页面布局都是良好的,包括一些细节的东西,例如本论所着重讲述的按钮,都是显示良好的。再看看新浪,腾讯这些门户,或是人人,淘宝,页面都不会这样。我这里没有哪个好哪个不好的意思,这其实是两种理念而已,两个方向而已。一类以像素为单位,强调精确布局,强调小细节上的重用性;一类是一em为单位,强调完全的重用性。前者实现的页面精致,布局精良,看似稳固;后者布局则谈不上精致,流动性的。拿终结者人物作比喻的话,前者就是施瓦辛格演得那个固态金属机器人,零件安装;后者就是那个液体金属机器人,可液态变形。

假设现在所有用户的显示器大部分都是1440像素~1600像素的,那么,像腾讯,新浪,阿里巴巴这些网站都是要重新改版的,因为960~1000像素宽的网页在这些浏览器下就显得很狭窄了,要知道,这改版的成本可不小啊,不是改一两个页面的问题啊!然而Google会有这样的问题吗?不会的,其早就预见到这一点了,所以它的页面都是流动性布局宽度自适应的,显示器多宽,其页面自动拉伸到该宽度。在这一点上,显然Google更甚一筹。然而,让腾讯这样的网站改成类似Google产品的网站显然是不可行的,这其中有理念的差异等很多很多原因。但是,不可否认的是,谷歌页面中所体现的这种思想,这种意识是值得学习值得深思的。

个人而言,我是深受谷歌网页前端布局思想的影响,在不断的实践中,形成了自己的“鑫三无准则”,其实就是不断思考如何将css的可扩展性发挥到极致而形成的。其中的“无图片”就是与本文主题密切相关的。由于自己已经形成意识,所以每当浏览到不错的页面的时候,总会下意识地想,这个效果可不可以直接用css实现,这个习惯让我进步不小。这里我就举与本文主题相关的一个例子,昨天误入虾米网,界面等做得不错,我就分析哪些可以进一步优化的,其中就包括看似只能用图片实现的按钮如何用高效的css代码完成。请看本文下半部分——用css实现虾米网音乐播放下载的圆角投影按钮。

2. 关于虾米网全选等圆角阴影宽度自适应按钮

①原按钮分析
首先,请看虾米网个人主页这几个音乐选择及播放的按钮
虾米网全反选按钮截图
这几个按钮做的还不错,看上去很舒服,想必基本上所有第一眼看到这个按钮的人都会有诸如“这个按钮图片不错”这样的想法,确实,在虾米网这个网站上这个是用图片+css实现的。这是该背景图片地址:http://img.xiami.com/res/img/default/goplaybg.gif单击后在新页面打开,可以看到这个css工程师还是有一定技术的,css Sprite用得很熟练,也考虑到的重用性问题,实现了一定宽度范围内的宽度自适应。看HTML代码和css部分,使用双层标签+浮动实现的宽度自适应,恕我直言,这位css工程师要学的还有很多。触犯了“鑫三无准则”中的浮动和图片两条,尤其浮动,浮动会大大增加代码成本,应该避免的,这里不扩展叙述。
其实这里无需浮动,无需图片,就可以实现一模一样的效果,而且代码高效简洁。

②如何用纯粹的css实现
图片是最好的证明,下图是自己用css写出来的按钮效果,各个浏览器下表现都是一致的(除IE8未测),所以这里就只展示IE6浏览器下的效果。如果您已经打开了demo实例页面,在页面的下半部分就可以看到这个按钮的效果以及优点介绍了。
用css实现的虾米网圆角按钮效果图

灰色按钮css代码:

.x_a{display:inline-block; border-top:1px solid #d6d6d6; border-bottom:1px solid #e5e5e5; font-size:12px;}
.x_b{float:left; border-left:1px solid #d6d6d6; border-right:1px solid #c2c2c2; border-bottom:1px solid #c2c2c2; margin:0 -1px; position:relative;}
.x_c{display:inline-block; padding:0.3em 0.6em 0; background:#f4f4f4; border-left:2px solid #ffffff; border-top:1px solid #ffffff; border-bottom:0.2em solid #f0f0f0; line-height:1.1em; cursor:pointer;}

HTML代码如下:

<a href="#nogo" class="x_a">
     <span class="x_b">
         <span class="x_c">高光投影按钮</span>
     </span>
</a>

一些代码方面的注意点与谷歌按钮类似,这里要比谷歌的那个按钮要简单些,难点在于颜色的选取,颜色取准了,效果也就很逼真了。

③css实现的按钮的优点
相比较虾米网网站原版的按钮,优点那是多多的啦,总体而言,也就是谷歌按钮中所提到的些有点,包括:
※与图片文字任意混排
※高度与宽度的自适应里面的文字
※使用css即可实现鼠标经过样式的改变
※没有使用图片
从下面的截图可以看出一二,其中最后4选项的灰色按钮为鼠标经过时的样式,与网站上图片实现的效果一致。

css实现的虾米网按钮的一些优点

css实现的虾米网按钮的一些优点

您可以狠狠地点击这里:demo实例页面

四、结语
整这篇文章又花了超过10个小时的时间,似乎唠哩唠叨说了不少。最后还是要总结性的强调,写这篇文章的目的不仅仅是为了说明如何用css实现一些貌似图片才能实现的按钮效果,更重要的是传达一种意识,一种类似于编程的预见性意识,一种如何将css的可扩展性发挥到极致的意识。只要拥有了这种意识,您就会花很多功夫去钻研css方面的东西,您的技术,您的css层次将会得到飞速的提升。css博大精深,你我都只在底层攀爬,所学甚多,只有戒骄戒躁,潜心钻研,才能成为真正在css上有心得的人。

(本篇完)

原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址: http://www.zhangxinxu.com/wordpress/?p=292

分享到:

标签: , , , , , , , , , , , , , , , , , , ,

赞助商推荐(我也要赞助)



发表评论(目前24 条评论)

  1. mo说道:

    第二层的span 加了float 属性了,为啥外部的inline-block 元素会被撑开,请鑫哥指教一下?

  2. zousjun说道:

    你的三无原则,这些按钮不是一直在用浮动吗?

  3. Hector说道:

    授人以鱼,更授人以鱼,谢谢前辈。

  4. carl说道:

    试验之后发现,按钮中文字的上部总是比下部多一点,文字不垂直居中呢????

  5. philoyou说道:

    为了一个按钮,要套三层的标签,这样好么?

  6. hebrews说道:

    谢谢博主,我是一个接触前端不久的,感觉在你这里学到了很多东西

  7. hiddaorear说道:

    在关于Google圆角高光高宽自适应按钮 这个span是否可以去掉,然后
    .g_d{display:block; padding:0.1em 0.6em; margin-top:0; cursor:pointer;},这样也可以。不知道是什么原因要在这个地方加这个span。菜鸟一个,求解。

  8. aliszya说道:

    第二层标签(span标签)样式中的position:relative属性是为了解决IE6下margin负值部分不可见的bug,浮动是为了使IE6、IE7下向左的margin负1像素起作用。
    经我所测,float:left这个属性貌似是多余的…有position:relative margin负值已经起作用了,无需flaot…不知是我头发短,见识少的缘故,还是我没发现.

  9. 邝芃说道:

    太崇拜了,技术太牛了,身为同行的我,奉你为大神

  10. 路路说道:

    这样的代码也有不足:

    首先是复杂;

    其次代码对图片替代的流量节省也是有限的:因为背景图只有一个,并且也只需载入一次,如果需要在很多地方复用按钮,比如有100个按钮(有点夸张),则需要100份代码,而不是一份。这样流量是否节约就有存疑了,并且如果要改代码的话……

    另外,这个按钮其实是在用“相似的颜色”绘制渐变(背景色和边框色),但这样的方式很局限。其次那个圆角也仅适用于低半径(最好就是2像素)

    已经不考虑支持 IE6 了……

    个人感觉还是寄希望于 CSS 3,渐变属性的支持!

    补充:很欣赏这个个人空间,从您这里学到不少! 感谢的话不想多说,但还是要说……呵呵,谢谢!

  11. bohemouse说道:

    受益匪浅

  12. Charje说道:

    css写得很好,但有时候,我们做前端写出的代码,是否要考虑下后台开发人员使用上的方便呢?

  13. 潘韬说道:

    如果中英文混排,怎么能保证中文与英文垂直居中对齐?

  14. hackxiaozhu说道:

    我又看了一边 我的QQ是 244066467 要是张哥有时间的话 请加一下小弟 小弟请教问题 希望张哥同意

  15. hackxiaozhu说道:

    我想问下 如果用这个做出的圆角在其他的浏览器里面大小不一啊,这个是什么原因呢? 要不请张哥加我QQ吧 讨论下,谢谢了

  16. hackxiaozhu说道:

    我看了你写的这个了 有点问题想问下你,不知道你有时间吗?

  17. 答案说道:

    每天要多来看看.这是迄今为止我看过最好的博客.没有之一.

  18. 答案说道:

    这个就像是你有一把牛刀,但是很多时候你只是在杀鸡,所以用不上牛刀,但是有牛刀体现了你 层次.所以要好好学习啊.

  19. 丹丹说道:

    文章很好哦~~学到不少东东!赞~~!

    感觉并不适合所有的项目哦。类似活动类的项目,周期性本身较短(多则一个月,少则三四天),它的页面大多都风格不同(重用性很低),且要求页面制作时间短,按钮很多都是圆角,且还渐变。。这种就不太适应了。

  20. Zz说道:

    看似微小却暗含力量!

  21. o仔说道:

    文章很好,可是并不适用所有人。。页面重构 在代码方面,可是产品经理或者设计师的设计图一出,都得围绕这些去做,设计师如果喜欢这种按钮就好多了。。我个人也是赞成这种看似简单的设计。

  22. 下一站说道:

    很喜欢。
    有一问题,当用TAB键或JS,focus的时候,虚线框会高出按纽。
    如果里面换成A标签,又不够一定,上下不够平衡。
    不知有没办法解决。

  23. putaoshu说道:

    很赞,思想很高端,学习了! (ps:我原来学css时研究的是QQ,taobao,作者技高一筹,以后也向goolge学习)

  24. max说道:

    很棒的文章!很棒的世界观和准则!
    “鑫三无准则”,即无浮动,无宽度,无图片!
    我来找茬吧!严谨和细致也是一种思想
    demo页面/common.css/
    body{font-family:’宋体’,Verdana, Geneva, sans-serif;}
    ul,li,form,h1,h2,h3,h4,h5,h6,p{list-style-type:none;}