CSS实现垂直/水平导航栏
文章目录
一级基本导航栏
怎么显示?导航栏 = 链接列表
- 导航栏需要标准的 HTML 作为基础。在我们的例子中,将用标准的 HTML 列表来构建导航栏。导航栏基本上是一个链接列表,因此使用 ul 和 li 元素是非常合适的:
以上是标准的导航栏代码。<div id="nav"> <ul class="firstNav"> <li> <a href="#">一级菜单1</a> </li> <li> <a href="#">一级菜单2</a> </li> <li> <a href="#">一级菜单3</a> </li> </ul> </div>
- 去掉list-style-type,去掉默认的项目符号和外边距、内边距:
ul { list-style-type: none; padding: 0; margin: 0; }
垂直导航栏
- display: block:把链接显示为块元素可使整个链接区域可点击(不仅仅是文本),同时也允许我们规定宽度。行内元素无法设置物理width。
inline-block、block、inline分析
- width: 140px:块元素默认占用全部可用宽度。我们需要规定 140 像素的宽度。
- line-height:可以用来实现
垂直居中
效果,水平居中用text-align: center
。 - 对
锚点
设置而不是li设置,由此提供更好的浏览器兼容性
。
<!DOCTYPE html>
<html>
<head>
<title>导航栏</title>
<style type="text/css">
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
#nav>ul>li {
text-align: center;
}
a {
display: block; /*垂直排列,且点击区域为方块*/
width: 100px; /*block可设置width*/
line-height: 40px; /*获得垂直居中效果*/
text-decoration: none;
color: white;
background-color: black;
border: 1px solid white;
}
</style>
</head>
<body>
<div id="nav">
<ul class="firstNav">
<li>
<a href="#">一级菜单1</a>
</li>
<li>
<a href="#">一级菜单2</a>
</li>
<li>
<a href="#">一级菜单3</a>
</li>
</ul>
</div>
</body>
</html>
水平导航栏
两种方法:行内元素(inline-block)和浮动(float)
-
行内元素
#nav>ul>li { text-align: center; display: inline-block; }
li默认是块内元素,前后有换行,设置成inline-block后,同时具有inline同行水平排列和block可以设置width等属性的特点。
不足:会有间隔
,因为原本的block元素前后有换行,使用inline-block之后,元素之间会有间隔。如何解决看inline-block、block、inline分析
。 -
浮动
#nav>ul>li { text-align: center; float: left; }
- float:left - 使用 float 来把块元素滑向彼此。
可以发现,元素之间的间隔仅为设置的border的1px间隔,也就是浮动元素之间是紧挨着的
,这点与inline-block区分开。
不足:float会有副作用,需要设置clear:both清除浮动带来的可能的坍塌后果。
二级导航栏
垂直二级
css:
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
#nav>ul>li {
text-align: center;
float: left;
/*display: inline-block;*/
}
a {
display: block; /*垂直排列,且点击区域为方块*/
width: 100px; /*block可设置width*/
line-height: 40px; /*获得垂直居中效果*/
text-decoration: none;
color: rgb(133, 119, 114);
background-color: rgb(237, 237, 237);
/*border: 1px solid white;*/
}
.firstNav::after {
content: '';
clear: both;
display: block;
}
.secondNav a {
background-color: rgb(237, 237, 237);
border-bottom: 1px solid white;
}
.secondNav {
display: none;
}
.firstNav>li:hover >a{
background-color: rgb(101, 101, 101);
color: white;
}
.firstNav>li:hover .secondNav {
display: block;
}
结构:
<div id="nav">
<ul class="firstNav">
<li>
<a href="#">一级菜单1</a>
<ul class="secondNav">
<li><a href="#">二级菜单1.1</a></li>
<li><a href="#">二级菜单1.2</a></li>
<li><a href="#">二级菜单1.3</a></li>
</ul>
</li>
<li>
<a href="#">一级菜单2</a>
<ul class="secondNav">
<li><a href="#">二级菜单2.1</a></li>
<li><a href="#">二级菜单2.2</a></li>
<li><a href="#">二级菜单2.3</a></li>
</ul>
</li>
<li>
<a href="#">一级菜单3</a>
<ul class="secondNav">
<li><a href="#">二级菜单3.1</a></li>
<li><a href="#">二级菜单3.2</a></li>
<li><a href="#">二级菜单3.3</a></li>
</ul>
</li>
</ul>
</div>
水平二级
由于二级导航栏是水平的,要让多个li同行分布,按照水平基本导航栏的做法(1)float 或者(2)inline-block。注意一级导航要设置relative定位,二级导航设置absolute定位
来脱离文档流,此时二级导航的宽度仍然受一级导航的限制(此时一级导航是距离最近的非static定位
的元素),否则会有错位情况发生。
css改动:
.firstNav {
position: relative;
}
.secondNav {
display: none;
position: absolute;
}
.secondNav>li {
float: left;
}
动画效果
css改动:
.secondNav {
/*display: none;*/
position: absolute;
opacity: 0;
transition-property: opacity;
transition-duration: 1s;
}
.firstNav>li:hover .secondNav {
/*display: block;*/
opacity: 1;
}
需要注意:如果display:none没有去掉,最后没有过渡效果,仍为瞬时显示。
行内元素和块级元素的具体区别是什么?inline-block是什么?
行内元素与块级元素的区别
block
- 总在新的一行开始(换行)
- width、height以及padding、margin可设置
- 如果不设置width,默认为整个容器的100%
- 常用块元素:div、p、h1、form、ul、li
inline
- 和其他元素同一行(不换行)
- 行高width、height和padding、margin不可设置(img除外,img可设置width、height)
- widht为文字或图片的宽度,不可改变
- 常用行内元素:span、a、label、input、img
inline-block
- 和其他元素同一行(不换行)
- width、height、margin、padding可设置
- 默认底部在同一水平线,可使用vertical-align
其他不同
-
行内元素会在一条直线上排列(默认宽度只与内容有关),都是同一行的,水平方向排列。
块级元素各占据一行(默认宽度是它本身父容器的100%(和父元素的宽度一致),与内容无关),垂直方向排列。块级元素从新行开始,结束接着一个断行。 -
块级元素可以包含行内元素和块级元素。行内元素不能包含块级元素,只能包含文本或者其它行内元素。
-
行内元素与块级元素属性的不同,主要是盒模型属性上:行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效。
行内元素和块级元素转换
display:block; (字面意思表现形式设为块级元素)
display:inline; (字面意思表现形式设为行内元素)
inline-block
inline-block
的元素(如input、img)既具有 block
元素可以设置宽高
的特性,同时又具有 inline
元素默认不换行
的特性。当然不仅仅是这些特性,比如 inline-block
元素也可以设置 vertical-align
(因为这个垂直对齐属性只对设置了inline-block的元素有效) 属性。
HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符自然占据一定的宽度,使用inline-block 会产生元素间的空隙。
在导航栏中可设置水平导航,与float相比没有浮动副作用。
举个例子
虽然原理很清晰明了,但是实际做的时候总有很多意外情况,这里列举我遇到的关于导航栏的小demo,源自我自己的作业和小练习。
效果:
;
注意和关键:
- 记得导航元素的时候,设置
锚点
的宽度而不是li
(这次代码中忘记了); - 使用CSS增加后序
after
的方式清除浮动
时,注意是在最外层ul的后面
添加,display设置为block
; - 注意
base标签
为页面上的所有链接
规定默认地址href
或默认目标target
。 - 二级导航设置
绝对定位
脱离文档流可以不受一级导航宽度的限制,前提是一级导航为static元素,否则将会以最近的非static即一级导航为相对位置定位。
代码:
<!DOCTYPE html>
<html>
<head>
<title>menu</title>
<base href="http://www.sysu.edu.cn/2012/cn/">
<style>
a:link,a:visited {text-decoration:none;color:blue}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
ul#nav {
background-color: rgb(208, 208, 208);
}
ul>li {
background-color: rgb(208, 208, 208);
padding: 4px 6px;
}
ul#nav::after {
content: "";
display: block;
clear: both;
}
ul#nav>li {
float: left;
padding: 0 10px;
}
ul#nav>li>ul {
display: none;
position: absolute;
border: 1px solid gray;
background-color: rgb(208, 208, 208);
/*top: 30px;*/
/*使得二级导航栏的宽度不受一级导航栏的限制*/
}
span.home {
display: inline-block;
width: 25px;
height: 21px;
margin-left: 250px;
background-image: url("F:/中大/大三下/专业工程项目实践/js实验2/code/images/home.gif");
/*由于使用了base,要用绝对路径*/
background-position: -3px -8px;
}
/*ul#nav>li:hover ul { <!-- hover控制二级导航栏显示隐藏 -->
display: block;
}*/
</style>
<script>
</script>
</head>
<body>
<ul id="nav">
<li><a href="index.htm"><span class="home"> </span></a>
</li>
<li><a href="zdgk/index.htm"><span>学校概况</span></a>
<ul> <li><a href="zdgk/zdgk01/index.htm">中大简介</a></li>
<li><a href="zdgk/zdgk02/index.htm">中大校区</a></li>
<li><a href="zdgk/zdgk03/index.htm">现任领导</a></li>
<li><a href="zdgk/zdgk04/index.htm">管理服务</a></li>
<li><a href="zdgk/zdgk06/index.htm">校歌 校训 校徽</a></li>
<li><a href="zdgk/zdgk07/index.htm">数字中大</a></li>
<li><a href="zdgk/zdgk05/index.htm">中大校史</a></li>
<li><a href="zdgk/zdgk08/index.htm">中大图志</a></li>
</ul>
</li>
<li><a href="yx/index.htm"><span>院系设置</span></a>
</li>
<li><a href="xksz/index.htm"><span>学科与师资</span></a>
<ul>
<li><a href="xksz/xksz01/index.htm">学科建设</a></li>
<li><a href="xksz/xksz02/index.htm">人才名录</a></li>
<li><a href="xksz/xksz03/index.htm">名师垂范</a></li>
</ul>
</li>
<li><a href="jyjx/index.htm"><span>教育教学</span></a>
<ul>
<li><a href="jyjx/jyjx01/index.htm">本科教育</a></li>
<li><a href="jyjx/jyjx02/index.htm">研究生教育</a></li>
<li><a href="jyjx/jyjx03/index.htm">国际教育</a></li>
<li><a href="jyjx/jyjx04/index.htm">继续教育</a></li>
</ul>
</li>
<li><a href="kxyj/index.htm"><span>科学研究</span></a>
<ul>
<li><a href="kxyj/kxyj01/index.htm">重点研究机构</a></li>
<li><a href="kxyj/kxyj04/index.htm">学术期刊</a></li>
<li><a href="kxyj/kxyj05/index.htm">博士后科研流动站</a></li>
</ul>
</li>
<li><a href="zsjy/index.htm"><span>招生与就业</span></a>
<ul>
<li><a href="zsjy/zsjy01/index.htm">本科招生</a></li>
<li><a href="zsjy/zsjy02/index.htm">研究生招生</a></li>
<li><a href="zsjy/zsjy03/index.htm">留学生招生</a></li>
<li><a href="jyjx/jyjx04/index.htm">继续教育招生</a></li>
<li><a href="zsjy/zsjy04/index.htm">就业指导与服务</a></li>
</ul>
</li>
<li><a href="http://library.sysu.edu.cn"><span>图书馆</span></a>
</li>
<li><a href="rczp/index.htm"><span>人才招聘</span></a>
</li>
<li><a href="xyjj/index.htm"><span>校友与基金</span></a>
</li>
<li><a href="zjzd/index.htm"><span>走进中大</span></a>
<ul>
<li><a href="http://myspace.sysu.edu.cn">5D空间</a>
<li><a href="zjzd/zjzd02/index.htm">校区地图</a>
<li><a href="zjzd/zjzd03/index.htm">生活服务</a>
<li><a href="zjzd/zjzd04/index.htm">中大博物馆</a>
<li><a href="zjzd/zjzd05/index.htm">校园文化</a>
</ul>
</li>
</ul>
<script>
window.onload = function() {
<!-- 使用JS控制二级导航栏显示/隐藏 -->
var item = document.querySelectorAll("ul#nav>li");
for (let i = 0; i < item.length; ++ i) {
item[i].addEventListener("mouseover", function() {
console.log(item[i].childNodes);
if (item[i].childNodes.length > 2)
item[i].childNodes[2].style.display = "block";
});
item[i].addEventListener("mouseout", function() {
console.log(item[i].childNodes);
if (item[i].childNodes.length > 2) {
console.log(item[i].childNodes[2]);
item[i].childNodes[2].style.display = "none";
}
});
}
}
</script>
</body>
</html>