导航菜单

Google Nexus 7 侧边栏导航菜单特效

阿里云


本教程将和大家分享 Google Nexus 7 网站的滑动侧边栏的制作方法。这个侧边栏的效果非常好,当我们用鼠标 hover 特定的按钮时,会有一排侧边栏图标出现,再用鼠标 hover 这些图标时,整个侧边栏将出现。第一个侧边框项是一个搜索框,但它的样式和其它的项是一样的,鼠标点击它是能输入搜索的文本。我们将使用无序列表的嵌套和 CSS transitions 来完成它。我们使用 JavaScript 来切换侧边栏打开的样式和完成鼠标 hover、click 事件。我们还要将它做成响应式的,以适应各种屏幕。

HTML 结构:

这个侧边栏效果将包含两个部分。第一部分是顶部的主菜单,第二部分是侧边栏。我们给底部的主菜单一个 classgn-menu-main,它里面还会包含一个 nav。第一个 li 元素中包含了一个 a 元素,用它来做侧边栏的 hover 按钮。

也想出现在这里?联系我们
创客主机
  1. <ul id="gn-menu" class="gn-menu-main">
  2.     <li class="gn-trigger">
  3.         <a class="gn-icon gn-icon-menu"><span>Menu</span></a>
  4.         <nav class="gn-menu-wrapper">
  5.             <!-- ... -->
  6.         </nav>
  7.     </li>
  8.     <li><a href="http://www.htmleaf.com/">Htmleaf</a></li>
  9.     <li><!-- ... --></li>
  10.     <!-- ... -->
  11. </ul>

在 nav 元素中,我们还要添加一个 divwrapper,用它来隐藏浏览器的滚动条。侧边栏子菜单的核心是一个无序列表,我们给它一个 classgn-menu,它包含一些子项,其中的一些子项中可能还包含子项。第一个子项是一个搜索框。

  1. <div class="gn-scroller">
  2.     <ul class="gn-menu">
  3.         <li class="gn-search-item">
  4.             <input placeholder="Search" type="search" class="gn-search">
  5.             <a class="gn-icon gn-icon-search"><span>Search</span></a>
  6.         </li>
  7.         <li>
  8.             <a class="gn-icon gn-icon-download">Downloads</a>
  9.             <ul class="gn-submenu">
  10.                 <li><a class="gn-icon gn-icon-illustrator">Vector Illustrations</a></li>
  11.                 <li><a class="gn-icon gn-icon-photoshop">Photoshop files</a></li>
  12.             </ul>
  13.         </li>
  14.         <li><a class="gn-icon gn-icon-cog">Settings</a></li>
  15.         <li><!-- ... --></li>
  16.         <!-- ... -->
  17.     </ul>
  18. </div><!-- /gn-scroller -->

CSS 样式:

首先将所有元素和伪元素的 box-sizing 都设置为 border-box。

  1. *,
  2. *:after,
  3. *::before {
  4.     box-sizing: border-box;
  5. }

左上角的导航按钮需要一个图标,我们使用 IcoMoon 的字体图标。

  1. @font-face {
  2.     font-weight: normal;
  3.     font-style: normal;
  4.     font-family: 'ecoicons';
  5.     src: url("../fonts/ecoicons/ecoicons.eot");
  6.     src: url("../fonts/ecoicons/ecoicons.eot?#iefix") format("embedded-opentype"), url("../fonts/ecoicons/ecoicons.woff") format("woff"), url("../fonts/ecoicons/ecoicons.ttf") format("truetype"), url("../fonts/ecoicons/ecoicons.svg#ecoicons") format("svg");
  7. }

后面我们将使用伪元素把字体图标添加到 a 元素上,我们先给列表定义样式。

  1. .gn-menu-main,
  2. .gn-menu-main ul {
  3.     margin: 0;
  4.     padding: 0;
  5.     background: white;
  6.     color: #5f6f81;
  7.     list-style: none;
  8.     text-transform: none;
  9.     font-weight: 300;
  10.     font-family: 'Lato', Arial, sans-serif;
  11.     line-height: 60px;
  12. }

现在来指定主菜单的样式。它是固定在页面顶部的,我们给它 60 像素的高度。

  1. .gn-menu-main {
  2.     position: fixed;
  3.     top: 0;
  4.     left: 0;
  5.     width: 100%;
  6.     height: 60px;
  7.     font-size: 13px;
  8. }

所有的链接按钮的通用样式如下:

  1. .gn-menu-main a {
  2.     display: block;
  3.     height: 100%;
  4.     color: #5f6f81;
  5.     text-decoration: none;
  6.     cursor: pointer;
  7. }

为链接按钮的 hover 添加一些反色。侧边栏的第一个子项是一个搜索框,我们需要指定它的 hover 样式。搜索框上将不会有 a 元素,所以我们直接在 li 元素上定义 hover。

  1. .no-touch .gn-menu-main a:hover,
  2. .no-touch .gn-menu li.gn-search-item:hover,
  3. .no-touch .gn-menu li.gn-search-item:hover a {
  4.     background: #5f6f81;
  5.     color: white;
  6. }

列表的所有子项都将左浮动并且有一条右边框。

  1. .gn-menu-main > li {
  2.     display: block;
  3.     float: left;
  4.     height: 100%;
  5.     border-right: 1px solid #c6d0da;
  6.     text-align: center;
  7. }

第一排的列表项的文字是隐藏的,并且用伪元素为它添加字体图标。我们设置 user-select 为 none,它的宽度和主菜单按钮的宽度相同。

  1. .gn-menu-main li.gn-trigger {
  2.     position: relative;
  3.     width: 60px;
  4.     user-select: none;
  5. }

主菜单上的最后一个元素将右浮动。

  1. .gn-menu-main > li:last-child {
  2.     float: right;
  3.     border-right: none;
  4.     border-left: 1px solid #c6d0da;
  5. }

为主菜单上的按钮添加一些 padding。

  1. .gn-menu-main > li > a {
  2.     padding: 0 30px;
  3.     text-transform: uppercase;
  4.     letter-spacing: 1px;
  5.     font-weight: bold;
  6. }

我们用 micro clearfix hack 来清除浮动。

  1. .gn-menu-main:after {
  2.     display: table;
  3.     clear: both;
  4.     content: '';
  5. }

现在让我们来处理一下侧边栏。这里为什么需要一个 wrapper 呢?如果你不介意在侧边栏上有一条滚动条,你可以简单的设置侧边栏的 overflow-y 属性为 scroll。这里我们用一个小技巧来隐藏它,将 wraaper 设置为 overflow hidden,然后给滚动条的 wraaper 一个稍大的宽度和 100%的高度。滚动条将被隐藏。我们的菜单将延伸到它所需要的高度,并且可以滚动。通常我们想隐藏侧边栏是给它一个等于宽度负值,仔细想想,为什么不使用 2D translate 来隐藏它呢?

  1. .gn-menu-wrapper {
  2.     position: fixed;
  3.     top: 60px;
  4.     bottom: 0;
  5.     left: 0;
  6.     overflow: hidden;
  7.     width: 60px; /* will be transitioned to 340px */
  8.     border-top: 1px solid #c6d0da;
  9.     background: white;
  10.     transform: translateX(-60px); /* will be transitioned to 0px */
  11.     transition: transform 0.3s, width 0.3s;
  12. }
  13.  
  14. .gn-scroller {
  15.     position: absolute;
  16.     overflow-y: scroll;
  17.     width: 370px;
  18.     height: 100%;
  19. }
  20.  
  21. .gn-menu {
  22.     border-bottom: 1px solid #c6d0da;
  23.     text-align: left;
  24.     font-size: 18px;
  25. }

现在为列表项添加一些 box-shadow,使它们分开一些,这将避免两条线重合的情况出现。

  1. .gn-submenu li {
  2.     overflow: hidden;
  3.     height: 0;
  4.     transition: height 0.3s;
  5. }

为列表子项添加 transition,并设置它们的初始高度为 0。

  1. .gn-submenu li {
  2.     overflow: hidden;
  3.     height: 0;
  4.     transition: height 0.3s;
  5. }

子菜单的颜色要比父菜单的颜色要明亮一些。

  1. .gn-submenu li a {
  2.     color: #c1c9d1
  3. }

现在我们为搜索框指定样式。我们想做得和 Google Nexus 页面上一样,所以我们给它一个透明的背景色,并把它的占位符做得和其它子菜单的样式一样。

  1. input.gn-search {
  2.     position: relative;
  3.     z-index: 10;
  4.     padding-left: 60px;
  5.     outline: none;
  6.     border: none;
  7.     background: transparent;
  8.     color: #5f6f81;
  9.     font-weight: 300;
  10.     font-family: 'Lato', Arial, sans-serif;
  11.     cursor: pointer;
  12. }
  13.  
  14. /* placeholder */
  15.  
  16. .gn-search::-webkit-input-placeholder {
  17.     color: #5f6f81
  18. }
  19.  
  20. .gn-search:-moz-placeholder {
  21.     color: #5f6f81
  22. }
  23.  
  24. .gn-search::-moz-placeholder {
  25.     color: #5f6f81
  26. }
  27.  
  28. .gn-search:-ms-input-placeholder {
  29.     color: #5f6f81
  30. }

多数浏览器都会在用户点击了输入框时隐藏占位符,Chrome 浏览器却不会这样,所以我们使用一点小技巧,当用户点击输入框时,通过设置占位符的颜色为透明来达到同样的效果。

  1. .gn-search:focus::-webkit-input-placeholder,
  2. .no-touch .gn-menu li.gn-search-item:hover .gn-search:focus::-webkit-input-placeholder {
  3.     color: transparent
  4. }
  5.  
  6. input.gn-search:focus {
  7.     cursor: text
  8. }

当鼠标 hover 搜索框时,搜索框的颜色应该和其它子项被 hover 时一样,颜色由白色变为较深的颜色。

  1. .no-touch .gn-menu li.gn-search-item:hover input.gn-search {
  2.     color: white
  3. }

占位符文本也做同样的设置。

  1. /* placeholder */
  2.  
  3. .no-touch .gn-menu li.gn-search-item:hover .gn-search::-webkit-input-placeholder {
  4.     color: white
  5. }
  6.  
  7. .no-touch .gn-menu li.gn-search-item:hover .gn-search:-moz-placeholder {
  8.     color: white
  9. }
  10.  
  11. .no-touch .gn-menu li.gn-search-item:hover .gn-search::-moz-placeholder {
  12.     color: white
  13. }
  14.  
  15. .no-touch .gn-menu li.gn-search-item:hover .gn-search:-ms-input-placeholder {
  16.     color: white
  17. }

现在让我们用 ::before 伪元素为每一个子项添加图标。我们将它们设置为 inline-block,并给 60px 的宽度。为了使用字体图标,我们重置了它们的字体。

  1. .gn-icon::before {
  2.     display: inline-block;
  3.     width: 60px;
  4.     text-align: center;
  5.     text-transform: none;
  6.     font-weight: normal;
  7.     font-style: normal;
  8.     font-variant: normal;
  9.     font-family: 'ecoicons';
  10.     line-height: 1;
  11.     speak: none;
  12.     -webkit-font-smoothing: antialiased;
  13. }

下面是定义字体图标的代码。

  1. .gn-icon-help::before {
  2.     content: "\e000"
  3. }
  4.  
  5. .gn-icon-cog::before {
  6.     content: "\e006"
  7. }
  8.  
  9. .gn-icon-search::before {
  10.     content: "\e005"
  11. }
  12.  
  13. .gn-icon-download::before {
  14.     content: "\e007"
  15. }
  16.  
  17. .gn-icon-photoshop::before {
  18.     content: "\e001"
  19. }
  20.  
  21. .gn-icon-illustrator::before {
  22.     content: "\e002"
  23. }
  24.  
  25. .gn-icon-archive::before {
  26.     content: "\e00d"
  27. }
  28.  
  29. .gn-icon-article::before {
  30.     content: "\e003"
  31. }
  32.  
  33. .gn-icon-pictures::before {
  34.     content: "\e008"
  35. }
  36.  
  37. .gn-icon-videos::before {
  38.     content: "\e009"
  39. }

通常,我们需要在图标旁显示一些文字,但有时我们仅需要显示图标。但我们又不希望出现一个空的 a 元素,而锚文本仍然在 HTML 上,所以我们将它们用 span 包围起来,这样我们就可以只简单的设置宽和高为 0,overflow 为 hidden 来隐藏它们。为何不使用 display: none?隐藏内容就像是 inaccessible to screen readers,所以你要确定是不是要“erase”它们。

  1. .gn-icon span {
  2.     width: 0;
  3.     height: 0;
  4.     display: block;
  5.     overflow: hidden;
  6. }

现在来设置主菜单中的样式。这里我们没有使用字体图标。我们使用 box shadow 来创建三条竖线来分割它们。

  1. .gn-icon-menu::before {
  2.     margin-left: -15px;
  3.     vertical-align: -2px;
  4.     width: 30px;
  5.     height: 3px;
  6.     background: #5f6f81;
  7.     box-shadow: 0 3px white, 0 -6px #5f6f81, 0 -9px white, 0 -12px #5f6f81;
  8.     content: '';
  9. }

当鼠标 hover 的时候,设置 box shadow 为反色。

  1. .no-touch .gn-icon-menu:hover::before,
  2. .no-touch .gn-icon-menu.gn-selected:hover::before {
  3.     background: white;
  4.     box-shadow: 0 3px #5f6f81, 0 -6px white, 0 -9px #5f6f81, 0 -12px white;
  5. }

当它被选中,我们设置它的颜色更蓝一些。

  1. .gn-icon-menu.gn-selected::before {
  2.     background: #5993cd;
  3.     box-shadow: 0 3px white, 0 -6px #5993cd, 0 -9px white, 0 -12px #5993cd;
  4. }

最后我们需要定义两个样式,一是侧边栏打开时只显示图标,二是整个侧边栏。当我们 hover 主菜单按钮时,只显示一排图标按钮,我们把这个 class 定义为 gn-open-part,另一个样式是 gn-open-all,当我们用鼠标点击主菜单按钮或 hover 子菜单图标按钮时,整个侧边栏将出现。

  1. .gn-menu-wrapper.gn-open-all,
  2. .gn-menu-wrapper.gn-open-part {
  3.     transform: translateX(0px);
  4. }

如果想打开侧边栏,需要设置它的宽度。

  1. .gn-menu-wrapper.gn-open-all {
  2.     width: 340px;
  3. }

打开的侧边栏子项的高度要和字体图标按钮的高度相同。

  1. .gn-menu-wrapper.gn-open-all .gn-submenu li {
  2.     height: 60px;
  3. }

最后,我们将它设置为响应式的,以适应所有的屏幕。现在,我们已经设置好所有的样式,我们将使用 JavaScript 来打开关闭侧边栏。

JAVASCRIPT

我们逍遥的效果是,当我们 hover 主菜单按钮时,想先让一排图标按钮出现。当我们点击了主菜单按钮或是 Hover 子菜单图标,才让这个侧边栏出现。当再次点击主菜单按钮或是屏幕的其它地方,侧边栏消失。我们先定义一些元素和初始化一些变量。bodyClickFn 函数定义了当侧边栏打开时我们点击屏幕的其它地方所触发的事件。我们还应该注意触摸事件。

  1. _init : function() {
  2.     this.trigger = this.el.querySelector( 'a.gn-icon-menu' );
  3.     this.menu = this.el.querySelector( 'nav.gn-menu-wrapper' );
  4.     this.isMenuOpen = false;
  5.     this.eventtype = mobilecheck() ? 'touchstart' : 'click';
  6.     this._initEvents();
  7.  
  8.     var self = this;
  9.     this.bodyClickFn = function() {
  10.         self._closeMenu();
  11.         this.removeEventListener( self.eventtype, self.bodyClickFn );
  12.     };
  13. }

当鼠标 hover 主菜单按钮时,我们希望菜单的第一部分出现。当鼠标离开主菜单按钮时,希望它们消失。

  1. this.trigger.addEventListener( 'mouseover', function(ev) { self._openIconMenu(); } );
  2. this.trigger.addEventListener( 'mouseout', function(ev) { self._closeIconMenu(); } );

当侧边栏按钮菜单出现,用鼠标 hover 它们将使整个侧边栏出现。点击侧边栏外的任何地方,侧边栏消失。我们需要为它们各自绑定事件。

  1. this.menu.addEventListener( 'mouseover', function(ev) {
  2.     self._openMenu(); 
  3.     document.addEventListener( self.eventtype, self.bodyClickFn ); 
  4. } );

最后,我们希望点击主菜单按钮时,侧边栏消失或出现。同样需要为它们各自绑定事件。

  1. this.trigger.addEventListener( this.eventtype, function( ev ) {
  2.     ev.stopPropagation();
  3.     ev.preventDefault();
  4.     if( self.isMenuOpen ) {
  5.         self._closeMenu();
  6.         document.removeEventListener( self.eventtype, self.bodyClickFn );
  7.     }
  8.     else {
  9.         self._openMenu();
  10.         document.addEventListener( self.eventtype, self.bodyClickFn );
  11.     }
  12. } );

另外,如果鼠标点击在侧边栏上,我们不希望它消失。

  1. this.menu.addEventListener( this.eventtype, function(ev) { ev.stopPropagation(); } );

_initEvents 函数定义了打开或关闭侧边栏的方法。

  1. _initEvents : function() {
  2.     var self = this;
  3.  
  4.     if( !mobilecheck() ) {
  5.         this.trigger.addEventListener( 'mouseover', function(ev) { self._openIconMenu(); } );
  6.         this.trigger.addEventListener( 'mouseout', function(ev) { self._closeIconMenu(); } );
  7.  
  8.         this.menu.addEventListener( 'mouseover', function(ev) {
  9.             self._openMenu(); 
  10.             document.addEventListener( self.eventtype, self.bodyClickFn ); 
  11.         } );
  12.     }
  13.     this.trigger.addEventListener( this.eventtype, function( ev ) {
  14.         ev.stopPropagation();
  15.         ev.preventDefault();
  16.         if( self.isMenuOpen ) {
  17.             self._closeMenu();
  18.             document.removeEventListener( self.eventtype, self.bodyClickFn );
  19.         }
  20.         else {
  21.             self._openMenu();
  22.             document.addEventListener( self.eventtype, self.bodyClickFn );
  23.         }
  24.     } );
  25.     this.menu.addEventListener( this.eventtype, function(ev) { ev.stopPropagation(); } );
  26. },
  27. _openIconMenu : function() {
  28.     classie.add( this.menu, 'gn-open-part' );
  29. },
  30. _closeIconMenu : function() {
  31.     classie.remove( this.menu, 'gn-open-part' );
  32. },
  33. _openMenu : function() {
  34.     if( this.isMenuOpen ) return;
  35.     classie.add( this.trigger, 'gn-selected' );
  36.     this.isMenuOpen = true;
  37.     classie.add( this.menu, 'gn-open-all' );
  38.     this._closeIconMenu();
  39. },
  40. _closeMenu : function() {
  41.     if( !this.isMenuOpen ) return;
  42.     classie.remove( this.trigger, 'gn-selected' );
  43.     this.isMenuOpen = false;
  44.     classie.remove( this.menu, 'gn-open-all' );
  45.     this._closeIconMenu();
  46. }

到这里,本教程就结束了,希望它对你有所帮助!

Google Nexus 7 侧边栏导航菜单特效

已有 459 人购买
查看演示升级 VIP立刻购买

演示地址 下载地址
收藏
(0)

发表回复

热销模板

Ashade - 作品展示摄影相册WordPress汉化主题
LensNews

本站承接 WordPress / PbootCMS / DedeCMS 等
系统建站、仿站、开发、定制等业务!