先看图:
需求:
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>