首页 > 代码库 > 一个二级菜单引发的血案

一个二级菜单引发的血案

近期发现自己css不是很好,于是又看了一遍《css权威指南》。总感觉自己抓不到重点。弃疗中。。。于是看看其他书。然后学妹跟我说她的二级菜单写得很乱。当时我心里就在想二级菜单,有何难?自认为10分钟能搞定。跟她要效果图并很自大的说了句“等会儿,我写个简单的”。于是血案由此引发。。。

二级菜单要实现的原效果图是:

(如发现雷同,不是巧合,是我从别的网页上截屏下来的 ~_~)。既然说了简单,肯定效果没这么精美。但是至少基本效果和原理要实现。

10分钟过去了....15分钟过去了....这个“等会儿”貌似有点久。恰好此时学妹说晚上再找我(我两没在一起,通过QQ聊的,住在一层楼)。我当时很淡定的回了一个:“也行”。其实内心很不淡定,因为至今还没实现出来,晚上来问我,我肯定不能说我也不会。于是继续研究。不知过了多长时间,终于写出来了。。。

实际效果图:

不要喷太早。不是搓是非常挫。。。。

后来晚上和学妹一起交流的时候发现,其实里面隐藏很多问题。

附上我实现效果的代码:(代码有点长,自行折叠)

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title>    <style>    *{        margin: 0;        padding: 0;    }    ul{        list-style: none;    }    a{        text-decoration: none;    }    .clearfix:after{        content: ‘.‘;        height: 0;        display: block;        visibility: hidden;        clear: both;    }    .clearfix{        zoom:1;    }    .nav{        position: relative;        margin-left: 10px;    }    .nav a{        display: block;        padding: 0 10px;        width: 80px;        line-height: 40px;        text-align: center;        cursor: pointer;        color: white;    }    .nav li{        float: left;    }    .nav>li{        background: rgb(18, 104, 191);        border-right: 1px solid #fff;    }    .nav ul{        display: none;        background: #ccc;        position: absolute;        top: 40px;    }    .nav ul li a{        color: #000;    }    .nav li:hover {        background: rgba(18, 104, 191, 0.8);    }    .parent:hover ul{        display: block;    }    </style></head><body>    <ul class="nav clearfix">        <li>            <a href="">首页</a>        </li>        <li>            <a href="">贷款资助</a>        </li>        <li class="parent">            <a>思想教育>></a>            <ul class="clearfix">                <li>                    <a href="">政治解读</a>                </li>                <li>                    <a href="">政治解读</a>                </li>            </ul>        </li>        <li class="parent">            <a>队伍建设>></a>            <ul class="clearfix">                <li>                    <a href="">政治解读</a>                </li>                <li>                    <a href="">政治解读</a>                </li>                <li>                    <a href="">政治解读</a>                </li>                <li>                    <a href="">政治解读</a>                </li>            </ul>        </li>        <li>            <a href="">学风建设</a>        </li>        <li>            <a href="">校园服务</a>        </li>        <li>            <a href="">下载中心</a>        </li>        <li>            <a href="">金石滩</a>        </li>    </ul></body></html>

总结一下:

1.实现横向导航条,水平排列有两种方法。一种是float:left,一种是display:inline-block。优点是:都能实现该效果。

缺点是:都有兼容问题。

float:left。带来的兼容问题:

(1)清除浮动:我一般常用的有两种

//第一种     .clearfix:after{        content: ‘.‘;        height: 0;        display: block;        visibility: hidden;        clear: both;    }    .clearfix{        zoom:1;    }//第二种       .clearfix{                overflow:hidden;                zoom:1;     }

我平时用的都是第一种,因为他不会出现什么问题。但是其实个人更喜欢第二种,因为它代码短。但是呢,第二种有些缺点:比如说我现在就不能用,因为子菜单需要通过定位溢出父元素,overflow:hidden;的话导致溢出不显示。所以我还是选择用第一种。

(2)在IE6中浮动双外边距:产生条件:block+水平margin+float。解决方法:_display:inline;。但是因为我这没有用到margin,所以我这也没写。

(3)IE6中3px偏移:当一个元素浮动,不希望相邻段落围绕于是设置margin-left,在IE6中产生3px偏移_height:1%;,因为这样可以触发IE的haslayout。而且在IE中当高度与实际不符时,IE采用的是拉伸将子元素包含,而不是溢出。当然二级菜单中也没用到这个。只是想到了,算总结一下吧。

其他的关于float,还有一些兼容性,就不说太多了。

display:inline-block。带来的兼容性。

(1)各浏览器关于inline-block显示不一致。解决方法: *display:inline; /* IE6、7 block 元素 */ *zoom:1;。

(2)空白占位符间隙。解决方法:font-size:0。但是!有些浏览器不支持font-size:0,Safari 仍然有5px的间隙 ,而IE6,7下仍然有1px的间隙。所以解决方法是:将ul元素样式设置为:font-size:0;/* 所有浏览器 */ *word-spacing:-1px;/* IE6、7 */  letter-spacing:-5px;/* Safari 等不支持字体大小为 0 的浏览器, N 根据父级字体调节*/。但li的将字体样式设置回去:font-size: 16px; letter-spacing: normal; word-spacing: normal; vertical-align:top;。

2.实现子菜单的放置位置。将子菜单绝对定位,但绝对定位相对于谁?子菜单的直接父元素,还是祖先元素?最后我的选择是祖先元素。 (即祖先元素:position:relative;)

原因是:通过测试将绝对定位相对于直接父元素 (即.parent{position:relative;})或相对于祖先元素 (即.nav{position:relative;})的区别是。因为将li设置为float:left的原因,导致相对于祖先元素定位的时候是在父元素下方水平排列,而相对于父元素定位的时候是在父元素下方垂直排列。(top:40px;所以在下方)

其实这上面又产生一个问题:既然是相对于祖先元素排列为什么是在父元素的下方水平排列,而不是祖先元素下方水平排列??原因在于:我没指定left:0;

那么,在绝对定位的时候指定left:0与不指定left的值(默认值为auto)有什么区别呢?难道处理不是效果一样的吗?

其实不是,关于绝对定位:当元素设置为position:absolutetopauto时,元素的顶端,要相对于其未定位前本来的顶端位置对齐(left:auto, right:auto也使用这个原则)。是不是平时没注意到,认为设置left:0与不设置left是一致的呢?

那么引申一个问题。当只指定position:absolute而设置top、right、bottom、left值的时候是怎么定位的呢?是在祖先元素的左上角呢?还是在原处?

答案是:都不是。因为默认情况下四个值默认都是auto,根据刚刚的原则:元素的顶端,要相对于其未定位前本来的顶端位置对齐。元素在未定位前的下面一点点,其他不变。

3.关于选择器权重:!important(无限大)>inline(1000)>id(100)>class/伪类(10)>tag/伪元素(1)>*(0)>inherit(无)。

4.关于内容重叠问题。

如果是浮动和其他元素的话:

         当行内框与一个浮动元素重叠时,其边框、背景、和内容都在该浮动元素“之上”显示。

         块框与一个浮动元素重叠时,其边框和背景在该浮动元素“之下”显示吗,内容在浮动元素“之上”显示。

如果是定位导致重叠则使用z-index。注意z-index只能用于定位元素。

5.关于二级菜单中的子菜单实际要实现内容位于其父元素下方中间问题。我看了一下文章开头网页的源码,他是在子菜单里面加了个空的li。通过js计算这个li的width。我本来以为应该在设置子菜单第一个元素的margin设置不同的值。但是这值怎么来。其实我没想好。求指导~~

除了发现这些css技术问题。其实我更想说:不管学啥,特别是学技术,要学会分享与交流。如果学妹没问我,或许我至今认为二级菜单是很简单的一个效果。如果我不去完成,或许我不知道其实我连二级菜单都不会写。如果我不交流,我会只求完成结果不求过程的实现效果却不会如此的去思考、去实践举例、去讲明白。

多一份分享,多一份智慧;多一份交流,多一份收获。各位,晚安。