这是一款效果非常炫酷的jQueryCSS3垂直固定侧边栏导航菜单特效。该侧边栏特效中,菜单开始以圆点的形式垂直排列,在用户用鼠标滑过圆点时,圆点动画过渡变形为菜单图标,效果非常的酷。

使用方法

垂直固定导航菜单

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 -->
 
<!-- additional sections here -->             
              
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 create 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-type(4) a::after {
  transform: translateX(-50%) translateY(-4.5em) scale(0);
}
.cd-vertical-nav li:nth-of-type(4) a::before {
  transform: translateX(-50%) translateY(-4.5em) scale(0.25);
}                
              

如果你使用的是不同的导航菜单项,你就需要根据实际情况来改变这些移动值。例如,如果你有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的点击事件,用于打开和关闭菜单按钮。