本教程将和大家一起来实现YouTuBe网站上的一种侧边栏菜单效果。主导航按钮使用的是一个小按钮加上一个图标和一个标题,当用户点击它的时候,一列导航菜单将出现。当菜单出现的时候,标题运动到右边。我们这里要添加更多得效果来使它更加完美。
HTML结构:
<nav id="dr-menu" class="dr-menu"> <div class="dr-trigger"><span class="dr-icon dr-icon-menu"></span><a class="dr-label">Account</a></div> <ul> <li><a class="dr-icon dr-icon-user" href="#">Xavier Densmore</a></li> <li><a class="dr-icon dr-icon-camera" href="#">Videos</a></li> <li><a class="dr-icon dr-icon-heart" href="#">Favorites</a></li> <li><a class="dr-icon dr-icon-bullhorn" href="#">Subscriptions</a></li> <li><a class="dr-icon dr-icon-download" href="#">Downloads</a></li> <li><a class="dr-icon dr-icon-settings" href="#">Settings</a></li> <li><a class="dr-icon dr-icon-switch" href="#">Logout</a></li> </ul> </nav>
每一个列表项都有一个小图标,我们使用IcoMoon来制作它。
CSS样式:
首先引入字体图标。
@font-face { font-family: 'icomoon'; src:url('../fonts/icomoon.eot'); src:url('../fonts/icomoon.eot?#iefix') format('embedded-opentype'), url('../fonts/icomoon.woff') format('woff'), url('../fonts/icomoon.ttf') format('truetype'), url('../fonts/icomoon.svg#icomoon') format('svg'); font-weight: normal; font-style: normal; }
为导航菜单设置一些基本样式。我们希望导航菜单是响应式的,但又不希望它太大或太小,所以设置了max-width
和min-width
。
.dr-menu { width: 100%; max-width: 400px; min-width: 300px; position: relative; font-size: 1.3em; line-height: 2.5; font-weight: 400; color: #fff; padding-top: 2em; }
菜单里包含的那个div设置为绝对定位,鼠标悬停在它上面是显示“小手”,另外它的z-index要比列表的高。
.dr-menu > div { cursor: pointer; position: absolute; width: 100%; z-index: 100; }
div中的span也需要绝对定位,为了让它运动起来,给它一个transition。
.dr-menu > div .dr-icon { top: 0; left: 0; position: absolute; font-size: 150%; line-height: 1.6; padding: 0 10px; transition: all 0.4s ease; }
当鼠标点击div的时候,我们给导航菜单一个class dr-menu-open
.dr-menu.dr-menu-open > div .dr-icon { color: #60a773; left: 100%; transform: translateX(-100%); }
最后为字体图标添加IcoMoon样式。主导航菜单在运动到右边时和原来的样子有些不同,我们使用:after
伪元素来添加一个小三角形。
.dr-menu > div .dr-icon:after { content: "\e008"; position: absolute; font-size: 50%; line-height: 3.25; left: -10%; opacity: 0; }
图标要绝对定位,离左边的距离为总宽度的10%,透明度初始值设置为0。
当我们打开菜单时,设置它的透明度为1,使它可见。
.dr-menu.dr-menu-open > div .dr-icon:after { opacity: 1; }
我们给标题设置一些样式,并给它一个transition,好让它在打开菜单时沿Y轴向上运动。
.dr-menu > div .dr-label { padding-left: 3em; position: relative; display: block; color: #60a773; font-size: 0.9em; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; line-height: 2.75; transition: all 0.2s ease-in; } .dr-menu.dr-menu-open > div .dr-label { transform: translateY(-90%); }
菜单开始时是看不见的,我们设置它的透明度为0。
.dr-menu ul { padding: 0; margin: 0 3em 0 0; list-style: none; opacity: 0; position: relative; z-index: 0; pointer-events: none; transition: opacity 0s linear 205ms; }当它打开时,设置它的透明度为1,使它可见,并设置一个较高的Z-index,让上面的div不能挡住它。
.dr-menu.dr-menu-open ul { opacity: 1; z-index: 200; pointer-events: auto; transition: opacity 0s linear 0s; }
上面的两个transition的作用分别是关闭和打开菜单。我们希望打开菜单时它立刻出现,而关闭菜单时有一些延时,所以分别设置了0ms和205ms。
为了使菜单项可见,我们用transition来控制它的透明度。
.dr-menu ul li { display: block; margin: 0 0 5px 0; opacity: 0; transition: opacity 0.3s ease; } .dr-menu.dr-menu-open ul li { opacity: 1; }
每一个菜单项的出现时间应该各部相同,上面的菜单项要先出现。
.dr-menu.dr-menu-open ul li:nth-child(2) { transition-delay: 35ms; } .dr-menu.dr-menu-open ul li:nth-child(3) { transition-delay: 70ms; } .dr-menu.dr-menu-open ul li:nth-child(4) { transition-delay: 105ms; } .dr-menu.dr-menu-open ul li:nth-child(5) { transition-delay: 140ms; } .dr-menu.dr-menu-open ul li:nth-child(6) { transition-delay: 175ms; } .dr-menu.dr-menu-open ul li:nth-child(7) { transition-delay: 205ms; }
菜单项的a元素设置为inline-block
,并给它一些padding。
.dr-menu ul li a { display: inline-block; padding: 0 20px; color: #fff; }
当鼠标滑过是让它改变一种颜色。
.dr-menu ul li a:hover { color: #60a773; }
接下来,让我们用伪元素来定义字体图标。
.dr-icon:before, .dr-icon:after { position: relative; font-family: 'icomoon'; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; } .dr-menu ul .dr-icon:before { margin-right: 15px; } .dr-icon-bullhorn:before { content: "\e000"; } .dr-icon-camera:before { content: "\e002"; } .dr-icon-heart:before { content: "\e003"; } .dr-icon-settings:before { content: "\e004"; } .dr-icon-switch:before { content: "\e005"; } .dr-icon-download:before { content: "\e006"; } .dr-icon-user:before { content: "\e001"; } .dr-icon-menu:before { content: "\e007"; }
JAVASCRIPT
当我们点击主按钮时,要让菜单获得一个classdr-menu-open
,我们希望菜单打开后只能通过点击主按钮来关闭菜单,来看一下代码。
var YTMenu = (function() { function init() { [].slice.call( document.querySelectorAll( '.dr-menu' ) ).forEach( function( el, i ) { var trigger = el.querySelector( 'div.dr-trigger' ), icon = trigger.querySelector( 'span.dr-icon-menu' ), open = false; trigger.addEventListener( 'click', function( event ) { if( !open ) { el.className += ' dr-menu-open'; open = true; } }, false ); icon.addEventListener( 'click', function( event ) { if( open ) { event.stopPropagation(); open = false; el.className = el.className.replace(/\bdr-menu-open\b/,''); return false; } }, false ); } ); } init(); })();
本教程就到这里,希望对你有所帮助。