一款效果非常炫酷的jQuery和CSS3垂直固定侧边栏导航菜单特效。该侧边栏特效中,菜单开始以圆点的形式垂直排列,在用户用鼠标滑过圆点时,圆点动画过渡变形为菜单图标,效果非常的酷。
HTML结构
该菜单使用无序列表的结构,它包裹在一个nav.cd-vertical-nav元素中。 button.cd-nav-trigger元素是用于在移动手机上打开菜单的按钮。另外,每一个菜单项都对应一个section.cd-section的内容段落。
<nav class="cd-vertical-nav">
<ul>
<li>
<a href="#section1" class="active">
<span class="label">Intro</span>
</a>
</li>
<li>
<a href="#section2">
<span class="label">Events</span>
</a>
</li>
<!-- additional navigation items here -->
</ul>
</nav><!-- .cd-vertical-nav -->
<button class="cd-nav-trigger cd-image-replace">Open navigation
<span aria-hidden="true"></span>
</button>
<section id="section1" class="cd-section">
<div class="content-wrapper">
<h1>Vertical Fixed Navigation #2</h1>
<a href="#section2" class="cd-scroll-down cd-image-replace">scroll down</a>
</div>
</section><!-- cd-section -->
<section id="section2" class="cd-section">
<div class="content-wrapper">
<!-- section content here -->
</div>
</section><!-- cd-section -->
CSS样式
在小屏幕设备中(视口宽度小于800像素),.cd-nav-trigger元素和<nav>元素被设置为position: fixed,并把它们放置在屏幕右下角的位置,然后使用右下角为转换原点,将菜单进行缩小操作。
当用户点击了.cd-nav-trigger元素,导航菜单被添加一个.open class,该class将它的scale值从0次该为1,并带有平滑的CSS3过渡效果。
.cd-nav-trigger {
display: block;
position: fixed;
z-index: 2;
bottom: 30px;
right: 5%;
}
.cd-vertical-nav {
position: fixed;
z-index: 1;
right: 5%;
bottom: 30px;
transform: scale(0);
transform-origin: right bottom;
transition: transform 0.2s;
}
.cd-vertical-nav.open {
transform: scale(1);
}
在大屏幕设备中,特效中使用Modernizr来检测移动触摸和非移动触摸设备。(使用.touch和.no-touch class)
在移动触摸设备中,侧边栏菜单项默认是可见的,而在非移动触摸的设备中,它们默认显示为圆点,当用户用鼠标滑过时才转换为图标。
<nav>元素被设置了固定的宽度和高度,并将它放置在视口的右侧。然后使用::before伪元素来创建导航菜单的背景。在非移动触摸设备中,::before伪元素默认被移动到右侧视口之外,然后当用户鼠标滑过时才从视口之外移动会原来的位置。同样在span.label元素上也会执行相同的效果。
@media only screen and (min-width: 800px) {
.cd-vertical-nav {
right: 0;
top: 0;
height: 100vh;
width: 90px;
}
.cd-vertical-nav::before {
/* this is the navigation background */
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
transform: translateX(100%);
transition: transform 0.4s;
}
.no-touch .cd-vertical-nav:hover::before,
.touch .cd-vertical-nav::before {
transform: translateX(0);
}
.cd-vertical-nav .label {
display: block;
transform: translateX(100%);
transition: transform 0.4s;
}
.no-touch .cd-vertical-nav:hover .label,
.touch .cd-vertical-nav .label {
transform: translateX(0);
}
}
为了创建导航菜单的圆点和图标,特效中使用导航的锚链接元素(<a>元素)的::before和::after伪元素来制作它们。在非移动触摸设备中,::before和::after伪元素默认被缩小为0,然后在用户鼠标滑过时才被放大为原来的大小。
@media only screen and (min-width: 800px) {
.cd-vertical-nav a {
position: relative;
padding: 3em 0 0;
margin: 1.4em auto;
}
.cd-vertical-nav a::before,
.cd-vertical-nav a::after {
/* used to the filled circle and the background icon */
content: '';
position: absolute;
left: 50%;
transition: transform 0.4s 0s;
}
.cd-vertical-nav a::before {
/* filled circle */
top: 0;
height: 32px;
width: 32px;
border-radius: 50%;
background: #eaf2e3;
transform: translateX(-50%) scale(0.25);
}
.cd-vertical-nav a::after {
/* icon */
top: 8px;
height: 16px;
width: 16px;
background: url(../img/cd-nav-icons.svg) no-repeat;
transform: translateX(-50%) scale(0);
}
.no-touch .cd-vertical-nav:hover a::before,
.no-touch .cd-vertical-nav:hover a::after,
.touch .cd-vertical-nav li:nth-of-type(n) a::before,
.touch .cd-vertical-nav li:nth-of-type(n) a::after {
transform: translateX(-50%) scale(1);
}
}
现在,当导航的圆点被缩小之后,它们之间的间隔会非常的远,我们必须沿Y轴移动它们来调整它们之间的距离。
首先我们从中间的圆点开始(在这个DEMO中是第二和第三个圆点)。我们向下移动第二个圆点(必须给它设置一个正值),同时使第三个圆点向上移动(要给它设置一个负值),所以,在DEMO中的代码如下:
.cd-vertical-nav li:nth-of-type(2) a::after {
transform: translateX(-50%) translateY(1.5em) scale(0);
}
.cd-vertical-nav li:nth-of-type(2) a::before {
transform: translateX(-50%) translateY(1.5em) scale(0.25);
}
.cd-vertical-nav li:nth-of-type(3) a::after {
transform: translateX(-50%) translateY(-1.5em) scale(0);
}
.cd-vertical-nav li:nth-of-type(3) a::before {
transform: translateX(-50%) translateY(-1.5em) scale(0.25);
}
然后,第一个圆点的移动值要是第二个圆点的3倍,第四个圆点的移动值是第三个圆点的3倍。
.cd-vertical-nav li:first-of-type a::after {
transform: translateX(-50%) translateY(4.5em) scale(0);
}
.cd-vertical-nav li:first-of-type a::before {
transform: translateX(-50%) translateY(4.5em) scale(0.25);
}
.cd-vertical-nav li:nth-of-typ
如果你使用的是不同的导航菜单项,你就需要根据实际情况来改变这些移动值。例如,如果你有6个菜单项,仍然是从中间开始移动(第三和第四个圆点),你可以将它们沿Y轴的移动值分别设置为1.5em和-1.5em,然后第二个和第五个元素分别设置为4.5em和-4.5em(3*1.5em),最后,第一个和最后一个圆点的移动值设置为7.5em和-7.5em(5*1.5em)。
如果你是奇数的菜单项,例如5个菜单项,那么中间的菜单项不需要移动,你只需要移动第二个和第四个菜单项,分别沿Y轴移动它们3em和-3em(2*1.5em),第一个和第四个菜单项移动6em和-6em(4*1.5em)。
JavaScript
当用户向下滚动页面的时候,updateSections()函数会计算当前在视口中的是哪一个section,并为相应的导航菜单项添加.active的class。
另外在小屏幕设备中,插件会监听button.cd-nav-trigger的点击事件,用于打开和关闭菜单按钮。