任务目标
京东首页的这一部分:
解
像行高、背景颜色这样次要的属性设置就不作说明了。
整体规划
使用一个<header>
元素表示导航栏,同时给<header>
赋值类名为class="header"
,因为元素选择器范围太广了,使用类选择器要精确些。<header>
的定位属性设置为position: fixed
,以实现固定在视口上方。同时width
设置为100%
,以在水平方向上撑满网页。<header>
内部用<ul>
、<li>
表示导航栏内的每一项内容,也给<ul>
赋值类名为class="topnav"
,理由同上。<li>
使用左浮动float: left
,所以<header>
加上clearfix
清除高度坍塌。
再添加一个<header>
的兄弟元素<div>
,充当网页内容。
<body>
<header class="header">
<ul class="topnav clearfix">
<li> </li>
...
<li> </li>
</ul>
</header>
<div>
li*100>lorem1
</div>
</body>
.header{
position: fixed;
width: 100%;
}
.header .topnav>li{
float: left;
}
<li>
的css修饰
由于<li>
下的二级菜单<div>
要用到绝对定位,所以将<li>
的定位方式设置为relative
来提供包含块。hover
时的<li>
只有左右上边框,没有下边框,所以要专门设置border-bottom: none
。
加上边框之后,<li>
盒子的尺寸就会变化,进而会“挤开”它后面的盒子,这样就导致文字在视觉上有错位效果:
水平方向上错位的解决方法:设置box-sizing: border-box
,即设置宽度为边框盒的宽度;
垂直方向上错位的解决方法:将hover
时<li>
的行高减去两个边框厚度,即设置为40px - 2*2px = 36px。
.header{
height: 40px;
line-height: 40px;
}
.header .topnav>li{
box-sizing: border-box;
position: relative;
}
.header .topnav>li:hover{
border: 2px solid red;
border-bottom: none;
line-height: 36px;
}
解决错位问题后:
二级菜单<div>
在其中一个<li>
下插入一个<div>
作为二级菜单内容,赋类名为submenu
:
<li>
<a href="">客户服务</a>
<div class="submenu">
<ul>
<li><a href="">客户服务1</a></li>
<li><a href="">客户服务2</a></li>
<li><a href="">客户服务3</a></li>
<li><a href="">客户服务4</a></li>
<li><a href="">客户服务5</a></li>
<li><a href="">客户服务6</a></li>
<li><a href="">客户服务7</a></li>
<li><a href="">客户服务8</a></li>
<li><a href="">客户服务9</a></li>
<li><a href="">客户服务10</a></li>
</ul>
</div>
</li>
由于应该是hover
时submenu
才显示,所以设置submenu
属性为display: none
,并添加hover时的选择器,设置为display: block
:
.header .topnav>li .submenu{
display: none;
}
.header .topnav>li:hover .submenu{
display: block;
}
为了使二级菜单与它的兄弟元素“客户服务”对齐,使用绝对定位position: absolute
进行调整。
.header .topnav>li .submenu{
position: absolute;
right: -2px;
}
目前的效果:
可以看到客户服务下面有一条碍眼的边框线,这个边框线是由submenu
产生的,所以无法直接消除。
可以采用间接的方式消除:使用伪元素选择器::after
手动在submenu
后加上一条白色线条覆盖之。
.header .topnav>li:hover::after{
content: "";
background: #fff;
position: absolute;
width: 100%;
height: 5px;
bottom: 0;
left: 0;
}
得到:
大功告成
(不知道为啥录屏后边框颜色变成黑的了)
完整代码
html
<body>
<header class="header">
<ul class="topnav clearfix">
<li><a href="">Lorem.</a></li>
<li><a href="">Corporis.</a> </li>
<li><a href="">Voluptate!</a></li>
<li>
<a href="">客户服务</a>
<div class="submenu">
<ul>
<li><a href="">客户服务1</a></li>
<li><a href="">客户服务2</a></li>
<li><a href="">客户服务3</a></li>
<li><a href="">客户服务4</a></li>
<li><a href="">客户服务5</a></li>
<li><a href="">客户服务6</a></li>
<li><a href="">客户服务7</a></li>
<li><a href="">客户服务8</a></li>
<li><a href="">客户服务9</a></li>
<li><a href="">客户服务10</a></li>
</ul>
</div>
</li>
<li><a href="">Officiis.</a></li>
</ul>
</header>
<div>
li*100>lorem1 <!-- 请自行拓展 -->
</div>
</body>
css
.clearfix::after{
content: "";
display: block;
clear: both;
}
.header{
background: #e3e4e5;
color: #999;
height: 40px;
line-height: 40px;
position: fixed;
width: 100%;
}
.header .topnav>li{
float: left;
margin: 0 15px;
padding: 0 8px;
width: 150px;
text-align: center;
height: 40px;
box-sizing: border-box;
position: relative;
}
.header .topnav>li:hover{
background: #fff;
border: 2px solid red;
border-bottom: none;
line-height: 36px;
}
.header .topnav>li .submenu{
text-align: left;
line-height: 1.5;
width: 300px;
display: none;
border: 2px solid red;
position: absolute;
right: -2px;
background: #fff;
}
.header .topnav>li:hover .submenu{
display: block;
}
.header .topnav>li:hover::after{
content: "";
background: #fff;
position: absolute;
width: 100%;
height: 5px;
bottom: 0;
left: 0;
}