今天来做一个简单响应式导航
不想看具体制作过程的,请直接前往这里 Responsive Header Demo
先来码出基本的布局
<header>
<div class="logo">
<a href="#">Company Namea>
div>
<nav>
<div class="nav-responsive"><a id="nav-toggle" href="/"><span>span>a>div>
<ul class="navlist">
<li><a>Homea>li>
<li><a>Somethinga>li>
<li><a>othera>li>
<li><a>Abouta>li>
<li><a>Contacta>li>
ul>
nav>
header>
这里用html5的语义化标签header
来做头部导航,应该很合理吧,用nav
包裹导航列表也很合理。
加一些样式
html,
body {
margin: 0;
padding: 0;
}
header {
height: 50px;
background: #262626;
}
.logo {
position: absolute;
padding-left: 20px;
float: left;
line-height: 50px;
text-transform: uppercase;
font-size: 1.4em;
}
.logo a {
color: #fff;
text-decoration: none;
font-weight: bold;
}
nav {
float: right;
}
nav ul {
padding: 0;
margin: 0;
list-style: none;
}
nav ul li {
color: #a2a0a0;
float: left;
text-transform: uppercase;
transition: background 0.5s ease;
}
nav ul li:hover {
color: white;
background: #aaa;
}
nav ul li.active {
color: white;
background: #343831;
}
nav ul li a {
display: block;
padding: 0 20px;
line-height: 50px;
color: inherit;
cursor: pointer;
transition: all 0.3s ease;
}
来看看初步效果:
这一步没什么可讲的,总之是为了让logo靠左,导航链接靠右,并设置了背景样式,hover样式等。
当视窗宽度变窄时,加入响应式的设计能让导航栏便于用户的查看,如果不加相应式设计,导航栏挤在一起很影响美观,也不利于查看。
这里用CSS媒体查询来实现响应式:
@media all and (max-width: 768px) {
nav {
width: 100%;
padding: 50px 0 15px;
}
nav ul li {
float: none;
border-bottom: 1px solid lightgray;
}
}
当屏幕宽度<=768px时,清除li
的浮动,并将nav
的宽度设置为100%,使其横向撑满屏幕,这样这些链接就能垂直排列,像这样:
至此,一个简单的响应式导航基本完成,接下来加点折叠的功能,让其更加完善:
先加入div,将其设计为一个小的类似icon的东西
<div class="nav-responsive"><a id="nav-toggle" href="/"><span>span>a>div>
.nav-responsive {
display: none;
position: absolute;
top: 0;
right: 0;
background: #262626;
height: 50px;
width: 50px;
}
@media all and (max-width: 768px) {
.nav-responsive {
display: block;
}
}
最开始这个div是隐藏的,当屏幕宽度<=768px时,显示出来
可以看到右上角的三条小横线
三条小横线是通过伪元素来实现的,设置好span的宽度和高度,通过伪元素在span前后都插入同样的小横线,并通过定位来拉开三者的间距。
#nav-toggle span,
#nav-toggle span::before,
#nav-toggle span::after {
cursor: pointer;
border-radius: 2px;
height: 3px;
width: 30px;
background: white;
position: absolute;
display: block;
content: '';
transition: all 300ms ease-in-out;
}
#nav-toggle span::before {
top: -10px;
}
#nav-toggle span::after {
bottom: -10px;
}
#nav-toggle.active span {
background-color: transparent;
}
最后加入js完成折叠功能:
const toggle = document.querySelector('#nav-toggle');
const ul = document.querySelector('nav ul');
toggle.addEventListener('click', (e) => {
e.preventDefault();
let computestyle = getComputedStyle(ul);
if (computestyle.display != 'none') {
ul.style.display = 'none';
toggle.classList.remove('active');
} else {
ul.style.display = 'block';
toggle.classList.add('active');
}
});
如果你习惯使用jQuery,这里可以这样写:
$('#nav-toggle').click(function(e) {
e.preventDefault();
$('nav ul').slideToggle('slow');
$(this).toggleClass('active');
});
还有一点值得注意:当导航栏展开时,通过css的transform
将span
转成一个"X"的形状,中间span
设置为透明将其隐藏,前后的小横线top设置为0,分别正向和反向旋转45度
#nav-toggle.active span {
background-color: transparent;
}
#nav-toggle.active span::before,
#nav-toggle.active span::after {
top: 0;
}
#nav-toggle.active span::before {
transform: rotate(45deg);
}
#nav-toggle.active span::after {
transform: rotate(-45deg);
}
最终效果是这样的:
最后还要啰嗦一句,在我们的css中加入了这样一段样:
@media all and (min-width: 769px) {
.navlist {
display: block !important;
}
}
主要目的是,当隐藏了导航栏,将屏幕宽度拉大时,强制显示导航栏,如果不加这段代码,屏幕宽度>=769px时导航栏将是隐藏的
最终效果及源码见 Responsive Header Demo
写作时间:2020-06-06