先看图:
需求:
1.子菜单的列数和高度都是不确定的,例如上图的菜单一有两列子菜单,菜单二只有一列子菜单,菜单四有四列子菜单,并且高度也不一样。要求整个子菜单在父菜单下居中显示。
2.要求子菜单列之间有分割线。
3.父菜单的宽度和子菜单的列宽度是固定的、已知的。
解决办法:
一、居中定位问题:
1.为了能让子菜单定位到相应的父菜单之下,直接将子菜单代码写在父菜单里
<li>
<a href="javascript:">菜单一</a>
<div class="sub-menu">
<div class="sub-wrap">
<div class="sub-content">
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
</div>
</div>
</div>
</li>
2.为了避免影响到其他的文档流需要对其设置为绝对定位,使其脱离正常的文档流,同时父菜单设置为相对定位,使得子菜单能相对父菜单定位。
.sub-menu{
position:absolute;
}
.navbar>li{
position:relative;
}
3.为了使子菜单的所有列在同一“行”显示,需要设置子菜单列的显示方式为:inline-block,并且不换行,另外视情况还需要设置垂直对其方式为text-top。
.sub-menu dl{
vertical-align: text-top;
display:inline-block;
}
.sub-menu .sub-content{
white-space: nowrap;
}
4.这时子菜单应该是在父菜单的正下方,并且左侧和父菜单的左侧对齐,拥有自己的大小。为了能相对父菜单居中显示,需要增加一层包裹容器,同时进行以下设置:
.sub-menu{
margin-left:65px;/*值为菜单列宽度的一半*/
}
.sub-menu>.sub-wrap{
position:relative;
left:-50%;
}
至此便实现了子菜单相对父菜单的居中显示。
二、分割线问题:
由于每列子菜单的高度是不定的,同时也不能使用:height:100%,来使所有子菜单列的高度一致。所以不能简单地设置子菜单列的边框来实现分割线。
这时可以直接在文档中插入一个空标签来显示分割线,也可以使用:before伪类来添加一个分割线,同时为了使分割线的高度小于整个子菜单的高度,需要再加上一层包裹容器,并设置外层容器的内边距值。
.sub-menu>.sub-wrap{
padding:10px;
}
.sub-menu>.sub-wrap>.sub-content {
position:relative;
}
.sub-menu>.sub-wrap>.sub-content dl + dl:before{
content: "";
position: absolute;
height: 100%;
width: 2px;
background: #fff;
top:0;
margin-left: -49px;/*值为子菜单列宽度的一半(假如忽略分割线本身的宽度)*/
margin-left: 0\0\9;/*ie*/
}
这里值得注意的是设置分割线为绝对定位(相对于父容器的父容器定位)后,ie下分割线默认对齐父容器的左侧,其他浏览器(不知道是不是所有)默认居中对齐父容器,所以需要设置一个负的外边距,然后针对ie去掉这个外边距。
以下是图片例子的源码:
<!DOCTYPE html>
<html>
<head>
<style>
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
ol, ul{
padding:0;
margin: 0;
}
li{
list-style: none;
}
a{
text-decoration:none;
}
nav{
background-color:#e62129;
}
.navbar{
width:980px;
height:45px;
margin:0 auto;
}
.navbar>li{
float:left;
width:130px;
text-align:center;
position:relative;
}
.navbar>li>a{
color:#fff;
display: inline-block;
width: 100%;
height:45px;
line-height:45px;
}
.navbar>li:hover,.navbar>li>a:focus{
background-color:#ccc;
}
.navbar>li:hover .sub-menu,.navbar>li>a:focus+.sub-menu{
display:block;
}
.sub-menu{
position:absolute;
margin-left:65px;/*值为菜单列宽度的一半*/
display:none;
}
.sub-menu .sub-wrap{
position:relative;
left:-50%;
background-color:#ccc;
padding:10px;
}
.sub-menu .sub-content{
position:relative;
white-space: nowrap;
}
.sub-menu dl{
width:100px;
vertical-align: text-top;
display:inline-block;
padding:5px;
margin:0;
}
.sub-menu dl>dd{
margin:0;
}
.sub-menu .sub-content dl + dl:before{
content: "";
position: absolute;
height: 100%;
width: 2px;
background: #fff;
top:0;
margin-left: -50px;/*值为子菜单列宽度的一半(假如忽略分割线本身的宽度)*/
margin-left: 0\0\9;/*ie*/
}
</style>
</head>
<body >
<header>
<nav>
<ul class="navbar">
<li>
<a href="javascript:">菜单一</a>
<div class="sub-menu">
<div class="sub-wrap">
<div class="sub-content">
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
</div>
</div>
</div>
</li>
<li>
<a href="javascript:">菜单二</a>
<div class="sub-menu">
<div class="sub-wrap">
<div class="sub-content">
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
</div>
</div>
</div>
</li>
<li>
<a href="javascript:">菜单三</a>
<div class="sub-menu">
<div class="sub-wrap">
<div class="sub-content">
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
<dl>
<dt>子菜单一</dt>
<dd>子菜单</dd>
<dd>子菜单</dd>
<dd>子菜单</dd>
<dd>子菜单</dd>
</dl>
</div>
</div>
</div>
</li>
<li>
<a href="javascript:">菜单四</a>
<div class="sub-menu">
<div class="sub-wrap">
<div class="sub-content">
<dl>
<dt>子菜单一</dt>
</dl>
<dl>
<dt>子菜单一</dt>
</dl>
<dl>
<dt>子菜单一</dt>
</dl>
<dl>
<dt>子菜单一</dt>
</dl>
</div>
</div>
</div>
</li>
<li><a href="javascript:">菜单五</a></li>
</ul>
</nav>
</header>
</body>
</html>