效果:
主要的功能有:
1. 网格设计
2. 充话费独占2行2列
3. 充话费鼠标移入有字体缩小的动画
4. 充话费等第一行的四个应用鼠标移入时,图标会向上弹一下
5. 充话费等第一行的四个应用鼠标移入时,会有更多的应用内容以框的显示显示在该应用下面,如:

本文的价值:
1. 在html结构,css逻辑方面,有一些自己的想法可供参考和交流
2. 熟悉css的transition和animation的简单应用
3. 学习如何通过浮动和负的的margin值,实现这种网格效果
4. 学习如何利用less,编写更加清晰和易于修改的css
5. 见识下淘宝的iconfront的威力
html结构:该找个演示代码的工具了。。。贴代码不好
<div class="toolbox"> <ul> <li class="tb-item tb-rs-2 tb-cs-2"> <a class="tb-item-wrapper tb-item-big tb-item-hbox tb-item-huafei" href="javascript:;" title="话费充值"> <div class="tb-item-iwrapper"> <i class="tb-item-icon iconfont icon-icon"></i> <p class="tb-item-text">充值</p> </div> <div class="tb-item-box"> </div> </a> </li> <li class="tb-item"> <a class="tb-item-wrapper tb-item-hbox tb-item-youxi" href="javascript:;" title="游戏充值"> <div class="tb-item-iwrapper"> <i class="tb-item-icon iconfont icon-youxi"></i> <p class="tb-item-text">游戏</p> </div> <div class="tb-item-box"> </div> </a> </li> <li class="tb-item"> <a class="tb-item-wrapper tb-item-hbox tb-item-lvxing" href="javascript:;" title="旅行"> <div class="tb-item-iwrapper"> <i class="tb-item-icon iconfont icon-hanglvxingye"></i> <p class="tb-item-text">旅行</p> </div> <div class="tb-item-box"> </div> </a> </li> <li class="tb-item"> <a class="tb-item-wrapper tb-item-hbox tb-item-baoxian" href="javascript:;" title="保险"> <div class="tb-item-iwrapper"> <i class="tb-item-icon iconfont icon-baoxian"></i> <p class="tb-item-text">保险</p> </div> <div class="tb-item-box"> </div> </a> </li> <li class="tb-item"> <a class="tb-item-wrapper" href="javascript:;" title="彩票"> <div class="tb-item-iwrapper"> <i class="tb-item-icon iconfont icon-caipiao"></i> <p class="tb-item-text">彩票</p> </div> </a> </li> ... </ul> </div>
最后几个省略,跟彩票应用实现相同。
结合html结构,描述下实现思路,主要是各个html元素的作用和css类的组织: 1. 整个应用包裹在div里,加了一个toolbox的类标识它这个容器
2. toolbox>ul,这个ul元素没有必要加css类,因为toobox的子元素从需求考虑不会再有其它元素,如果要对这个ul添加样式,利用子元素选择器即可
3. 每个li元素都加了一个类,一方面是为了结构更加清晰,另一方面是因为有些应用内部还会有div包括它的具体内容,这些内容很有可能也会用li元素来实现,所以要对跟应用直接相关的li元素添加css类,以便对它设置的样式不会影响更加深远的后代li元素,其实因为这个原因,li元素下面的a,div,i,p都必须加css类,道理同理
4. tb-item表示一个应用,同时考虑到话费对应的tb-item,占了两行两列,所以单独加了两个类tb-rs-2,tb-cs-2,表示rowspan或colspan为2,命名简便了点,有注释的话,代码就不难理解了,原本是想借助less的循环和mixin,将这个占多行多列的类做的更加灵活,从实际结果来看,这个还是不太好实现。。。。
5. li下面直接元素是a元素,因为字体大小,颜色和图标闪一下的动画效果都需要利用a元素的hover伪类实现
6. a元素还有一些其他的辅助类,如tb-item-big的作用是可以利用它,对需要显示大字体的应用进行处理,如tb-item-hbox,其实是tb-item-hasbox的简写,意思是它里面还有更多的内容,需要一个box来包裹,所以它里面has a box,如tb-item-huafei,tb-item-youxi,这个是用来单独标识每一个应用的,利用它可以实现它里面的box在显示的时候,left值可以得到不同的控制,以便box的左右边框总是能够跟toolbox的两边重合。
7. a元素里面有两个元素,第一个元素时tb-item-iwrapper,它把tb-item-icon和tb-item-text包裹起来,目的是为了在显示box的时候,这个iwrapper元素的底部能够把box的border-top盖住一部分以便,这个元素与box看起来是一种连通的效果;第二个元素是tb-item-box,这个没啥好说的。这两个元素都是绝对定位的,默认的时候tb-item-box不会显示,top值为父元素的100%,当父元素hover的时候,tb-item-box就会显示出来了。然后控制好left等等,微调之后就能实现效果了。
8. 网格的实现,可以这么干:每个tb-item都设置border,然后全部左浮动,并且都设置margin-top: -1px ,margin-left: -1px就搞定了。
css代码实现:
@import (inline)"icon-font.css";
* {
box-sizing: border-box
}
@tb-cols: 5;//5行
@tb-rows: 3;//3列
@tb-item-width: 59px;//每个item的宽
@tb-item-height: 78px;//每个item的高
@tb-item-bdcolor: #EAEAEA;//item默认的边框颜色
@tb-item-icon-small-size: 24px;//图标默认的字体大小
@tb-item-icon-big-size: 60px;//大图标的字体大小
body {
font: 12px/1.5 tahoma,arial,‘Hiragino Sans GB‘,sans-serif;
}
/*设置整站的a元素,ul元素,li元素的默认样式*/
a {
text-decoration: none;
}
ul {
list-style: none;
}
ul,li {
margin: 0;
padding: 0;
}
//以上元素应该在整站做一些整体样式的设置,以便整个网站的风格能够一致
@-webkit-keyframes toTopFromBottom {
49% {
-webkit-transform: translateY(-100%);
}
50% {
opacity: 0.3;
-webkit-transform: translateY(40%);
}
51% {
opacity: 1;
}
/* 假如动画动画声明的时候使用了forwards,在动画结束后,元素将保持在to定义的状态,如果没有定义to这个状态,即使配置了forwards,元素在动画结束后会回到起始状态
意思就是本例中,不使用forwards也没有关系
to {
opacity: 0.3;
}
*/
}
//从bootstrap中找出来的清除浮动的mixin
.clearfix() {
&:before,
&:after {
content: " ";
display: table;
}
&:after {
clear: both;
}
}
//forwards 参考:http://www.w3school.com.cn/cssref/pr_animation-fill-mode.asp,
.toTopFromBottom() {
-webkit-animation: toTopFromBottom 0.3s forwards;
-moz-animation: toTopFromBottom 0.3s forwards;
animation: toTopFromBottom 0.3s forwards;
}
.toolbox {
//这部分样式设置其实是根据需求定的,比如宽度跟定位,本例只是为了实现效果,毕竟这个toolbox的样式不太关键
width: 600px;
height: 600px;
position: fixed;
top: 50%;
left: 50%;
margin-left: -300px;
margin-top: -300px;
//组件内部可能还包含有其它的ul,li,p,a,i等元素,先用元素选择器定义一些统一的样式,针对不同位置的元素,可以结合类选择器来单独定义
//设置本组件内p元素的默认样式,之所以不设置在外面,是因为不是整站的p元素都需要清掉padding和margin,段落还是带一些行距要好看些
p {
margin: 0;
padding: 0;
}
ul {
//根据行列数跟每个item的高宽计算整个ul元素的高宽
width: @tb-item-width * @tb-cols - @tb-cols + 1;
height: @tb-item-height * @tb-rows - @tb-rows + 1;
.clearfix();
}
.tb-item {
float: left;
width: @tb-item-width;
height: @tb-item-height;
border: 1px solid @tb-item-bdcolor;
margin-left: -1px;
margin-top: -1px;
position: relative;
//定义占两列的item宽度
&.tb-cs-2 {
width: @tb-item-width * 2 - 1;
}
//定义占两行的item高度
&.tb-rs-2 {
height: @tb-item-height * 2 - 1;
}
}
.tb-item-wrapper {
text-align: center;
&,& .tb-item-iwrapper {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
& .tb-item-iwrapper {
overflow: hidden;
}
//图标
.tb-item-icon {
display: block;
color: #ff4400;
font-size: @tb-item-icon-small-size;
margin-top: 12px;
}
//文本
.tb-item-text {
transition: color 0.3s ease-in-out;
color: #6c6c6c;
}
//大图标
&.tb-item-big .tb-item-icon {
font-size: @tb-item-icon-big-size;
transition: font-size 0.3s ease-in-out;
}
.tb-item-box {
position: absolute;
display: none;
background-color: #fff;
top: @tb-item-height - 2;
height: @tb-item-height * 2 - 1;
width: @tb-item-width * @tb-cols - @tb-cols + 1;
border: 1px solid #ff4400;
z-index: 1;
}
//以下几处控制每个应用的box的left
&.tb-item-huafei .tb-item-box {
left: -1px;
}
&.tb-item-youxi .tb-item-box {
left: -@tb-item-width * 2 + 1;
}
&.tb-item-lvxing .tb-item-box {
left: -@tb-item-width * 3 + 2;
}
&.tb-item-baoxian .tb-item-box {
left: -@tb-item-width * 4 + 3;
}
&:hover .tb-item-text {
color: #ff4400;
}
//定义带box的wrapper元素hover时候的样式,主要是为了显示红色的边框,并且盖住父的item元素的边框
&.tb-item-hbox:hover {
top: -1px;
left: -1px;
bottom: -1px;
right: -1px;
border: 1px solid #ff4400;
z-index: 1;
.tb-item-iwrapper {
bottom: -1px;
z-index: 2;
background-color: #fff;
}
}
&.tb-item-big:hover .tb-item-iwrapper {
bottom: @tb-item-height - 2;
}
&.tb-item-hbox:hover .tb-item-box {
display: block;
}
&.tb-item-big:hover .tb-item-icon {
font-size: @tb-item-icon-small-size;
}
&:hover .tb-item-icon {
.toTopFromBottom();
}
}
//tb-on的添加和删除是通过js控制的,完全通过css做实现不了,主要是为了鼠标在滑入游戏,保险,旅行等item时,话费item的文字大小能够跟它们保持一致
&.tb-on {
.tb-item-big {
.tb-item-icon{
font-size: @tb-item-icon-small-size;
}
}
}
}
Js部分:
<script type="text/javascript">
(function() {
var $tb = $(‘.toolbox‘);
var toggleTb = function(e){
$(‘.toolbox‘).toggleClass(‘tb-on‘);
}
$(‘.toolbox‘).on(‘mouseenter‘,‘.tb-item-hbox‘,toggleTb).on(‘mouseleave‘,‘.tb-item-hbox‘,toggleTb);
})();
</script>
这个tb-on的作用是为了实现,比如鼠标滑过游戏这个应用,话费这个应用的图标能够设置成普通的字体大小而不是大图标大小。
原文:http://my.oschina.net/lyzg/blog/488857