资讯专栏INFORMATION COLUMN

CSS学习笔记(九) 界面组件之导航菜单

pingink / 1725人阅读

摘要:为了让包围列表项,没有使用,而是使用了,是因为前者会导致后来添加到下拉菜单中的子菜单无法显示它们最终会显示在父元素的外面,结果会导致溢出而被隐藏。它与父元素之间的间隙,实际上下拉菜单中第一个链接的边框。

  

菜单由一组链接组成。用 HTML 中的列表元素(ulol)来分组链接不仅符合逻辑,而且即使没有额外的 CSS 也能适当显示链接的层次。默认情况下,由于列表(li)是块级元素,因此它们会上下堆叠。

1.纵向菜单

html 标记


css 规则

*{
    margin: 0;
    padding: 0;
}
nav{
    margin: 50px;width:150px;
}
.list ul{
    border: 1px solid #6a6b6c;
    border-radius: 3px;
    padding:5px 10px 3px;
}
.list li{
    list-style: none;
    /*padding: 3px 10px;*/
}
.list li + li a{       /* 注意这里! */
    border-top: 1px solid #6a6b6c;
}
.list a{
    display: block;    /* 这里! */
    padding:3px 10px;    /* 还有这里! */
    text-decoration: none;
    padding: 3px 10px;
}
.list a:hover{
    color:#069;
}

效果图

说明

相对于 div,使用 HTML5 新增的 nav 元素作为导航菜单的容器在语义上更恰当。

使用 非首位子元素 选择符。li + li选择符意思为:任何跟在 li 之后的 li。在上面表示给除第一个 li 之外的所有列表项上方加一条边框。这种选择符就称为 非首位子元素选择符。它在选择列表时非常使用。其它实现该效果的方法:

/*给所有 li 上方添加一条边框*/
li {
    border-top:1px solid #f00;
}
/*去掉第一个 li 上方的边框*/
li:first-child {
    border-top:none;
}

让列表可点击。为了不让只有文本可以点击(因为链接 a 是行内元素,它会收缩并包住其中的文本。),为了提高用户体验,我们需要 让列表项所在的整行都能点击。方法就是首先把内边距从 li 元素转移到链接内部,然后让链接完全填满整个列表项。如下所示:

.list a{
    display:block;
    padding:3px 10px;
}

然后就是把选择符 li + li 变成li + li a,就可以把上边框添加到列表后面的列表项所包含的链接元素上。

2.横向菜单

html 标记


CSS 规则

.list ul{
    overflow: hidden;   /*强制 ul 包围浮动的 li 元素*/
}
.list li{
    float: left;    /*让 li 元素水平排列*/
    list-style: none;
}
.list a{
    display: block;    /*让链接变成块级元素*/
    padding: 0 16px;
    text-decoration: none;
    color:#999;
}
.list li + li a{
    border-left:1px solid #aaa;
}
.list a:hover{
    color:#555;
}

效果图

说明

浮动可以让 li 元素从垂直变成水平。

display:block 让链接从收缩变成扩张,从而整个 li 元素都变成了可点击。

选择符 li + li a 为除第一个链接之外的每个链接左侧都加了一条竖线,作为视觉分割线。

3.下拉菜单

相对于前面两种菜单,这个实现起来有点复杂。

下面,我们分几个步骤来实现。

第1步-实现顶级菜单

HTMl 标记


CSS 规则:

/* ***************添加视觉样式************ */
.multi_drop_menu {
    font: 1em helvetica, arial, sans-serif;
}

.multi_drop_menu a{
    /*让链接充满列表项*/
    display: block;

    /*文本颜色*/
    color:#555;

    /*背景颜色*/
    background-color:#eee;

    /*链接的内边距*/
    padding: .2em 1em;

    /*分隔线宽度*/
    border-width:3px;

    /*可以有颜色,也可以透明*/
    border-color: transparent;
}

/*显示选择路径*/
.multi_drop_menu li:hover > a{ /*注意这里的选择符,使用了冒泡机制,后面会用到*/
    /*悬停时的文本颜色*/
    color:#fff;

    /*悬停时的背景颜色*/
    background-color: #aaa;
}

/* ***************添加功能样式************* */
.multi_drop_menu *{
    margin:0;
    padding:0;
}

/*强制ul包围li*/
.multi_drop_menu ul{
    float: left;
}
.multi_drop_menu li{
    /*水平排列菜单项*/
    float: left;

    /*去掉默认的项目符合*/
    list-style: none;

    /*为子菜单提供定位上下文*/
    position: relative;
}

.multi_drop_menu li a{
    /*让链接填充列表项*/
    display: block;

    /*给每个链接添加一个右边框*/
    border-right-style: solid;

    /*背景只出现在内边距区域后面*/
    background-clip: padding-box;

    /*去掉链接的下划线*/
    text-decoration: none;
}

效果图

说明:

分离菜单的 视觉样式功能样式。有利于代码维护。

  

视觉样式:控制字体大小、边框和文本的颜色。
功能样式:控制布局和行为。

通过 浮动li 由垂直堆叠变成水平排列。

为了让 ul 包围列表项,没有使用 overflow:hide,而是使用了 float:left,是因为前者会导致后来添加到下拉菜单中的子菜单无法显示——它们最终会显示在父元素 ul 的外面,结果会导致 溢出(overflow) 而被 隐藏(hide)

为了提高用户体验,要让 热区(可点击区域) 最大化——所有视觉样式(内边距、背景、边框等)都应用给链接 a,而不要应用给 ulli

使用 background-clip:padding-box 阻止链接的背景延伸到边框后面。接着, border-color:transparent;让边框透明 ,在链接之间产生间隙,让后面的页面能够透过边框被看到。这样一来,不用外边距也能分隔链接,本质上是紧挨在一起,视觉上却是分开的。

第2步-实现菜单的下拉部分

CSS 规则:

/*二级菜单宽度*/
.multi_drop_menu li ul{
    width: 9em;
}
.multi_drop_menu li li a{
    /*去掉继承的右边框*/
    border-right-style: none;

    /*添加上边框*/
    border-top-style: solid;
}
/* 添加的功能样式 */
.multi_drop_menu li ul {
    /*临时显示二级下拉菜单*/
    display:block;
    /*相对于父菜单项定位*/
    position:absolute;
    /*左边与父菜单项对齐*/
    left:0;
    /*顶边与父菜单项底边对齐*/
    top:100%;
}
.multi_drop_menu li li {
    /*停止浮动,恢复堆叠*/
    float:none;
}
.multi_drop_menu li li ul {
    /*继续隐藏三级下拉菜单*/
    display:none;
}

效果图

说明:

通过将二级菜单的顶边位置(top)设定为 100%(相对于其相对定位的父元素 li),其顶边会与父元素底边恰好对齐。它与父元素之间的间隙,实际上下拉菜单中第一个链接的边框。

第3步-让下拉菜单响应鼠标事件

CSS 规则

.multi_drop_menu li ul {
    /*隐藏二级下拉菜单*/
    display:none;
    /*相对于父菜单项定位*/
    position:absolute;
    /*左边与父菜单项对齐*/
    left:0;
    /*顶边与父菜单项底边对齐*/
    top:100%;
}
.multi_drop_menu li:hover > ul {
    /*父元素悬停时显示*/
    display:block;
}
/*隐藏二级菜单*/
li ul {
    display:none;
}
/*显示二级菜单*/
li:hover > ul {
    display:block;
}

说明:

先把下一级的菜单隐藏,再在父元素鼠标悬停时把它显示出来。

:hover 触发器是设定在 li 元素而非链接身上。因为我们想要显示的是 li 的子元素 ul

悬停列表项与子列表之间还有一个子选择符 >,如果没有这个选择符,当顶级菜单项处于悬停状态时,会同时显示二级和三级菜单。

第4步-调整三级菜单的位置

CSS 规则

.multi_drop_menu li li ul {
    /*相对于父菜单定位*/
    position:absolute;
    /*与父菜单右侧对齐*/
    left:100%;
    /*与父菜单项顶边对齐*/
    top:0;
}

效果图:

说明

由于三级菜单跟二级菜单一样垂直堆叠,因而会被二级菜单遮住,所以我们需要把三级菜单放到二级菜单右侧,让它的顶边与鼠标所在的菜单项的底边对齐。

其它-突出显示选择路径

CSS 规则

.multi_drop_menu li:hover > a {
 /*悬停时的文本颜色*/
 color:#fff;
 /*悬停时的背景颜色*/
 background-color:#aaa
}

效果图

其它-垂直的三级菜单

HTML 标记


CSS 规则

/*顶级垂直菜单宽度*/
.multi_drop_menu.vertical {
    width:8em;
}
.multi_drop_menu.vertical li a {
    border-right-style:none;

    border-top-style:solid;
}
.multi_drop_menu.vertical li li a {
    border-left-style:solid;
}
.multi_drop_menu.vertical ul,.multi_drop_menu.vertical li {
     /*让顶级菜单垂直显示*/
     float:none;
}
.multi_drop_menu.vertical li ul {
     /*子菜单左边与上一级菜单右边对齐*/
     left:100%;

     /*子菜单顶边与上一级菜单项顶边对齐*/
     top:0;
}

效果图:

源码下载

点击这里

参考资料

CSS设计指南

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110979.html

相关文章

  • CSS学习笔记(十二) CSS命名规范

    摘要:引言最近想将这几个月做过的东西组件化,然后首先想到的是编码规范化本文只涉及命名规范,搬来了造好的轮子。举例对齐样式使用对齐目标的英文名称。举例注意事项一律小写尽量用英文不加中杠和下划线尽量不缩写,除非一看就明白的单词。 引言:最近想将这几个月做过的东西组件化,然后首先想到的是 编码规范化!本文只涉及 CSS 命名规范,搬来了Alloyteam 造好的轮子。可能并不完全适用,在以后...

    stormjun 评论0 收藏0
  • 从服务器获取数据,引入组件

    摘要:博文原址从服务器获取数据,引入组件接着前面四篇环境搭建以及使用创建第一个静态页面引入计算属性动态内容模型,保存数据到数据库发布项目,加入功能清理模板,使用组件重构版本之后组件会越来越重要。 博文原址:从服务器获取数据,引入组件 接着前面四篇: 环境搭建以及使用Ember.js创建第一个静态页面 引入计算属性、action、动态内容 模型,保存数据到数据库 发布项目,加入CRUD功能 ...

    codecook 评论0 收藏0
  • 开发利器IntelliJ IDEA学习笔记

    摘要:旨在记录自己的学习过程,方便日后遇到问题是及时查阅复习,另一方面也希望能帮助像笔者一样从来没使用过的人快速熟悉。 这篇文章主要记录的是本人学习使用IntelliJ IDEA的笔记,可能不是特别的详细。旨在记录自己的学习过程,方便日后遇到问题是及时查阅复习,另一方面也希望能帮助像笔者一样从来没使用过IDEA的人快速熟悉IDEA。文章错误之处还请各位大佬批评指正。(文末有本人的微信公众号,...

    马永翠 评论0 收藏0
  • vue学习组件menu导航菜单

    摘要:后面就是和定位弹出框一样类似的操作,在导航菜单里面我并没有这么做,后面会改成这样的吧。一些多层嵌套的位置问题,尚未完成。在显示的时候会有高度抖动的问题。里面给某些子组件添加样式用到了深度作用。 效果尽量仿着element做。预览地址 组件之间的通信 showImg(https://segmentfault.com/img/remote/1460000018614516?w=788&h=...

    el09xccxy 评论0 收藏0
  • vue学习组件menu导航菜单

    摘要:后面就是和定位弹出框一样类似的操作,在导航菜单里面我并没有这么做,后面会改成这样的吧。一些多层嵌套的位置问题,尚未完成。在显示的时候会有高度抖动的问题。里面给某些子组件添加样式用到了深度作用。 效果尽量仿着element做。预览地址 组件之间的通信 showImg(https://segmentfault.com/img/remote/1460000018614516?w=788&h=...

    Vixb 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<