任务目标

京东首页的这一部分:


像行高、背景颜色这样次要的属性设置就不作说明了。


整体规划

使用一个<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>

由于应该是hoversubmenu才显示,所以设置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;
}