这个效果点击慕课网的这个地址就可以查看。
1. 字体图标的方式
相比较背景图片的方式,使用字体图标,会明显增加html结构的复杂度:
<div class="toolbar-container"> <a href="javascript:;" class="tbitem tbitem-weixin"> <div class="tbitem-wrapper"> <span class="tbitem-icon iconfont icon-weixin"></span> <span class="tbitem-text">公众<br>账号</span> </div> <span class="tbitem-code"></span> </a> ... </div>
使用背景图片时,tbitem下面如果不需要显示像app下载和公众账号的二维码,可以不包含任何子元素,但是这里必须使用tbitem-wrapper这个包裹元素,目的是:
a. 对它设置溢出隐藏,以便图标和文本对应的span元素在调整top值时,溢出的元素不可见;
b. 保证不影响tbitem元素的溢出属性,因为二维码对应的span元素,必须在溢出可见的环境里才能显示。
css实现不复杂:
@import (inline)"icon-front.css";//用的是淘宝的iconfront,挺好用的,推荐使用! @tbitem-width: 52px;//重复用到的值 @tbitem-height: @tbitem-width;//重复用到的值 @tbitem-text-lineheight: 18px;//方便调试,字体图标要想效果,需要花费更多调试次数 @tbitem-text-size: 14px;//方便调试 @tbitem-icon-size: 28px;//方便调试 @common-images-dir: "../images";//文件夹 @tbitem-code-width: 172px;//重复用到的值 * { box-sizing:border-box;//border-box在计算盒子模型时,比较简便 -moz-box-sizing:border-box; -webkit-box-sizing:border-box; } .toolbar-container { position: fixed; width: @tbitem-width; height: @tbitem-height * 4 + 3; bottom: 20px; right: 20px; .tbitem { display: block; position: relative; width: @tbitem-width; height: @tbitem-height; text-decoration: none; color: #fff; text-align: center; & + .tbitem { margin-top: 1px; } .tbitem-wrapper{ overflow: hidden; } .tbitem-icon, .tbitem-text, .tbitem-wrapper { height: 100%; display: block; position: absolute; width: 100%; left:0; } .tbitem-icon, .tbitem-text { transition: all 200ms linear; } .tbitem-icon { top: 0; background-color: #ccc; line-height: @tbitem-height; font-size: @tbitem-icon-size; } .tbitem-text { top: 100%; font-size: @tbitem-text-size; line-height: @tbitem-text-lineheight; background-color: #989898; padding: (@tbitem-height - @tbitem-text-lineheight * 2) / 2 0; } &:hover { .tbitem-icon { top: -100%; } .tbitem-text { top: 0; } } .tbitem-code { position: absolute; background: url(‘@{common-images-dir}/elevator.png‘) no-repeat 0 0; right: @tbitem-width - 5 ; bottom: -10px; width: @tbitem-code-width; opacity: 0; filter: alpha(opacity=0); transform: scale(0.01); transform-origin: 100% 95%; transition: opacity 0.25s, transform .3s; } &:hover { .tbitem-code { opacity: 1; filter: alpha(opacity=100); transform: scale(1); } } &.tbitem-weixin { .tbitem-code { height: 212px; } } &.tbitem-app { .tbitem-code { height: 194px; background-position: 0 -222px; } } } }
结合html和css得出的总结是:
a. less中尽量不要出现重复代码
b. 使用简短的类前缀,如tbitem,可以简化代码,减少命名冲突,同时保证清晰的逻辑结构和重用,也不要为了命名更加清晰,将类名命的很长,其实css要尽量简短,可以减小文件大小,减少每次请求的数据量,类似这样的命名:tbitem-weixin tbitem-wrapper tbitem-text tbitem-icon tbitem-code既能达到清晰结构的目的,又能保证较短的代码结构。以前我喜欢用tbitem-wrapper-text tbitem-wrapper-icon,就是从命名上还体现出层级关系,其实真的没必要,搞太复杂了,css有层级,但是她可以跨越层级生效,css的质量要求就是简洁,高效,易懂。
c. 二维码对应的span之所以加css类,原因是span元素在tbitem下不唯一,当然也可用子元素选择器解决这个问题
2. before after伪类的方式
这种方式在字体图标的方式上进行改进,html结构比字体图标精简:
<div class="toolbar-container"> <a href="javascript:;" class="tbitem tbitem-weixin tbitem-code"> <div class="tbitem-wrapper"></div> </a> ... </div>
tbitem的text和icon可以用tbitem-wrapper的before after伪元素来实现。二维码可以用tbitem的after伪元素来实现。
css代码如下:
@import (less)"icon-front.css"; @tbitem-width: 52px; @tbitem-height: @tbitem-width; @tbitem-text-lineheight: 18px; @tbitem-text-size: 14px; @tbitem-icon-size: 28px; @common-images-dir: "../images"; @tbitem-code-width: 172px; * { box-sizing:border-box; -moz-box-sizing:border-box; -webkit-box-sizing:border-box; } .toolbar-container { position: fixed; width: @tbitem-width; height: @tbitem-height * 4 + 3; bottom: 20px; right: 20px; .tbitem { display: block; position: relative; width: @tbitem-width; height: @tbitem-height; text-decoration: none; color: #fff; text-align: center; & + .tbitem { margin-top: 1px; } &:after, .tbitem-wrapper, .tbitem-wrapper:before, .tbitem-wrapper:after { display: block; } .tbitem-wrapper, .tbitem-wrapper:before, .tbitem-wrapper:after { overflow: hidden; height: 100%; width: 100%; position: absolute; left:0; } .tbitem-wrapper:before, .tbitem-wrapper:after { &:extend(.iconfont); text-decoration: none; color: #fff; text-align: center; transition: all 200ms linear; } .tbitem-wrapper:before { top: 0; background-color: #ccc; line-height: @tbitem-height; font-size: @tbitem-icon-size; } .tbitem-wrapper:after { top: 100%; font-size: @tbitem-text-size; line-height: @tbitem-text-lineheight; background-color: #989898; padding: (@tbitem-height - @tbitem-text-lineheight * 2) / 2 0; white-space: pre; } &:hover { .tbitem-wrapper:before { top: -100%; } .tbitem-wrapper:after { top: 0; } } &.tbitem-weixin .tbitem-wrapper:before { content: "\e620"; } &.tbitem-weixin .tbitem-wrapper:after { content: "公众\A账号"; } &.tbitem-feedback .tbitem-wrapper:before { content: "\e601"; } &.tbitem-feedback .tbitem-wrapper:after { content: "意见\A反馈"; } &.tbitem-app .tbitem-wrapper:before { content: "\e611"; } &.tbitem-app .tbitem-wrapper:after { content: "APP\A下载"; } &.tbitem-top .tbitem-wrapper:before { content: "\e69e"; } &.tbitem-top .tbitem-wrapper:after { content: "返回\A顶部"; } &.tbitem-code:after { content: ""; position: absolute; background: url(‘@{common-images-dir}/elevator.png‘) no-repeat 0 0; right: @tbitem-width - 5 ; bottom: -10px; width: @tbitem-code-width; opacity: 0; filter: alpha(opacity=0); transform: scale(0.01); transform-origin: 100% 95%; transition: opacity 0.25s, transform .3s; } &.tbitem-code:hover:after { opacity: 1; filter: alpha(opacity=100); transform: scale(1); } &.tbitem-weixin:after { height: 212px; } &.tbitem-app:after{ height: 194px; background-position: 0 -222px; } } }
从这种方式中的思考总结是:
1. 伪元素的好处是简化了html的结构,缺点是增加了css的复杂度,原本属于html的内容都增加到了css中,比如文本,不利于html的语义化
2. 换行还需要特殊处理,结合\A字符串在content属性中,同时还要配置white-space为pre才有效
3. 伪元素还必须配置content属性才能在html中显示,否则无效
4. 这种方式调试起来也不是很方便,逻辑结构不够清晰
5. 结合字体图标使用的时候,还需要找到字体图标中对应的实现方式,不过在less中通过extend可以解决这个问题
综合这三种方式,显然第二种方式是优于另外两种方式,今后在能找到相应字体图标资源时,尽量使用这样的方式。