导航菜单

CSS3 超炫丽环状导航菜单动画效果

阿里云


这是两款使用 css3 transform 属性制作的环状导航菜单动画效果。当点击导航按钮时,菜单像扇子一样打开,效果很华丽。这个教程里我们将向大家展示如何使用 css transforms 来创建一个漂亮的圆形菜单。我们将一步步的带你创建样式表,然后解释一些使用到的数学计算公式和简单逻辑,以便使你有一个很清晰的思路。正如上面所说的,我们将使用到一些基本的数学计算公式和 css transforms 来创建样式。但是你不用担心,这些公式都非常简单,我将一步步的给大家解释。

HTML 结构:

我们要创建的是一个菜单,让我们先从正常的菜单结构开始。我们需要一个包含无序列表的 div,一个触发打开关闭动作的按钮。在第一种效果中,当菜单打开时我们还需要一个遮罩层来遮住页面。

也想出现在这里?联系我们
创客主机
  1. <button class="cn-button" id="cn-button">+</button>
  2. <div class="cn-wrapper" id="cn-wrapper">
  3.    <ul>
  4.        <li><a href="#"><span class="icon-picture"></span></a></li>
  5.        <li><a href="#"><span class="icon-headphones"></span></a></li>
  6.        <li><a href="#"><span class="icon-home"></span></a></li>
  7.        <li><a href="#"><span class="icon-facetime-video"></span></a></li>
  8.        <li><a href="#"><span class="icon-envelope-alt"></span></a></li>
  9.    </ul>
  10. </div>
  11. <div id="cn-overlay" class="cn-overlay"></div>

这个例子中的图标我们将使用 Font Awesome。

数学公式:

最好的理解这些公式的方式是使用画图的方式来。所以下面会用图解的方式来解释每一步的 css 样式是如何来的。

先来看看每个扇形的角度是多少,下面是一张示意图:

扇形示意图

所以扇形的分布如上图所示,我们的 demo 中有 6 个 li,那么每个 li 的角度为:

180deg / 6 = 30deg

如果你想做一个完整的圆形,那么角度值为:

360deg / 6 = 60deg

以此类推,你可以计算出你想要的扇形角度。我们将在 css 中使用这些角度。

要创建一个刚好等于我们所需要的角度的扇形,可以使用 skew()来将它们倾斜。倾斜的值为:

90deg – x deg

这里的 x 为我们需要的角度。这时候,列表中的所有 li 都将因倾斜而产生扭曲,因此我们需要所有的 a 元素设置为不倾斜,

CSS 部分:

我们将使用 Modernizr 来检测页面是否支持 CSS transforms,并且当检测到不支持 CSS transforms 的浏览器时给出一个简单的回调函数。现在开始写菜单样式。菜单应该是固定在页面底部的,在页面初始化时是最小化的,当点击了按钮后才开始放大并展开。

  1. .csstransforms .cn-wrapper {
  2.   font-size:1em;
  3.   width: 26em;
  4.   height: 26em;
  5.   overflow: hidden;
  6.   position: fixed;
  7.   z-index: 10;
  8.   bottom: -13em;
  9.   left: 50%;
  10.   border-radius: 50%;
  11.   margin-left: -13em;
  12.   transform: scale(0.1);
  13.   transition: all .3s ease;
  14. }
  15. /* class applied to the container via JavaScript that will scale the navigation up */
  16. .csstransforms .opened-nav {
  17.   border-radius: 50%;
  18.   transform: scale(1);
  19. }

给菜单触发按钮添加一些样式

  1. .cn-button {
  2.   border:none;
  3.   background:none;
  4.   color: white;
  5.   text-align: Center;
  6.   font-size: 1.5em;
  7.   padding-bottom: 1em;
  8.   height: 3.5em;
  9.   width: 3.5em;
  10.   background-color: #111;
  11.   position: fixed;
  12.   left: 50%;
  13.   margin-left: -1.75em;
  14.   bottom: -1.75em;
  15.   border-radius: 50%;
  16.   cursor: pointer;
  17.   z-index: 11
  18. }
  19. .cn-button:hover,
  20. .cn-button:active,
  21. .cn-button:focus{
  22.   background-color: #222;
  23. }

当菜单打开时,会有一个遮罩遮罩页面。

  1. .cn-overlay{
  2.   width:100%
  3.   height:100%;
  4.   background-color: rgba(0,0,0,0.6);
  5.   position:fixed;
  6.   top:0;
  7.   left:0;
  8.   bottom:0;
  9.   right:0;
  10.   opacity:0;
  11.   transition: all .3s ease;
  12.   z-index:2;
  13.   pointer-events:none;
  14. }
  15.  
  16. /* Class added to the overlay via JavaScript to show it when navigation is open */
  17. .cn-overlay.on-overlay{
  18.   pointer-events:auto;
  19.   opacity:1;
  20. }

现在按照先前的数学公式给菜单项和 a 元素添加样式。

  1. .csstransforms .cn-wrapper li {
  2.   position: absolute;
  3.   font-size: 1.5em;
  4.   width: 10em;
  5.   height: 10em;
  6.   transform-origin: 100% 100%;
  7.   overflow: hidden;
  8.   left: 50%;
  9.   top: 50%;
  10.   margin-top: -1.3em;
  11.   margin-left: -10em;
  12.   transition: border .3s ease;
  13. }
  14.  
  15. .csstransforms .cn-wrapper li a {
  16.   display: block;
  17.   font-size: 1.18em;
  18.   height: 14.5em;
  19.   width: 14.5em;
  20.   position: absolute;
  21.   position: fixed; /* fix the "displacement" bug in webkit browsers when using tab key */
  22.   bottom: -7.25em;
  23.   right: -7.25em;
  24.   border-radius: 50%;
  25.   text-decoration: none;
  26.   color: #fff;
  27.   padding-top: 1.8em;
  28.   text-align: center;
  29.   transform: skew(-50deg) rotate(-70deg) scale(1);
  30.   transition: opacity 0.3s, color 0.3s;
  31. }
  32.  
  33. .csstransforms .cn-wrapper li a span {
  34.   font-size: 1.1em;
  35.   opacity: 0.7;
  36. }
  37. /* for a central angle x, the list items must be skewed by 90-x degrees
  38. in our case x=40deg so skew angle is 50deg
  39. items should be rotated by x, minus (sum of angles - 180)2s (for this demo) */
  40.  
  41. .csstransforms .cn-wrapper li:first-child {
  42.   transform: rotate(-10deg) skew(50deg);
  43. }
  44.  
  45. .csstransforms .cn-wrapper li:nth-child(2) {
  46.   transform: rotate(30deg) skew(50deg);
  47. }
  48.  
  49. .csstransforms .cn-wrapper li:nth-child(3) {
  50.   transform: rotate(70deg) skew(50deg)
  51. }
  52.  
  53. .csstransforms .cn-wrapper li:nth-child(4) {
  54.   transform: rotate(110deg) skew(50deg);
  55. }
  56.  
  57. .csstransforms .cn-wrapper li:nth-child(5) {
  58.   transform: rotate(150deg) skew(50deg);
  59. }
  60.  
  61. .csstransforms .cn-wrapper li:nth-child(odd) a {
  62.   background-color: #a11313;
  63.   background-color: hsla(0, 88%, 63%, 1);
  64. }
  65.  
  66. .csstransforms .cn-wrapper li:nth-child(even) a {
  67.   background-color: #a61414;
  68.   background-color: hsla(0, 88%, 65%, 1);
  69. }
  70.  
  71. /* active style */
  72. .csstransforms .cn-wrapper li.active a {
  73.   background-color: #b31515;
  74.   background-color: hsla(0, 88%, 70%, 1);
  75. }
  76.  
  77. /* hover style */
  78. .csstransforms .cn-wrapper li:not(.active) a:hover,
  79. .csstransforms .cn-wrapper li:not(.active) a:active,
  80. .csstransforms .cn-wrapper li:not(.active) a:focus {
  81.   background-color: #b31515;
  82.   background-color: hsla(0, 88%, 70%, 1);
  83. }

当浏览器不支持 CSS transforms 时,我们给出一个简单的回调。

  1. .no-csstransforms .cn-wrapper{
  2.   font-size:1em;
  3.   height:5em;
  4.   width:25.15em;
  5.   bottom:0;
  6.   margin-left: -12.5em;
  7.   overflow: hidden;
  8.   position: fixed;
  9.   z-index: 10;
  10.   left:50%;
  11.   border:1px solid #ddd;
  12. }
  13.  
  14. .no-csstransforms .cn-button{
  15.   display:none;
  16. }
  17.  
  18. .no-csstransforms .cn-wrapper li{
  19.   position:static;
  20.   float:left;
  21.   font-size:1em;
  22.   height:5em;
  23.   width:5em;
  24.   background-color: #eee;
  25.   text-align:center;
  26.   line-height:5em;
  27. }
  28.  
  29. .no-csstransforms .cn-wrapper li a{
  30.   display:block;
  31.   width:100%;
  32.   height:100%;
  33.   text-decoration:none;
  34.   color:inherit;
  35.   font-size:1.3em;
  36.   border-right: 1px solid #ddd;
  37. }
  38.  
  39. .no-csstransforms .cn-wrapper li a:last-child{
  40.   border:none;
  41. }
  42.  
  43. .no-csstransforms .cn-wrapper li a:hover,
  44. .no-csstransforms .cn-wrapper li a:active,
  45. .no-csstransforms .cn-wrapper li a:focus{
  46.   background-color: white;
  47. }
  48.  
  49. .no-csstransforms .cn-wrapper li.active a {
  50.   background-color: #6F325C;
  51.   color: #fff;
  52. }

我们希望菜单是响应式的,以适应所有的屏幕。

  1. @media screen and (max-width:480px){
  2.   .csstransforms .cn-wrapper{
  3.     font-size:.68em;
  4.   }
  5.   .cn-button{
  6.     font-size:1em;
  7.   }
  8.   .csstransforms .cn-wrapper li {
  9.     font-size:1.52em;
  10.   }
  11. }
  12.  
  13. @media screen and (max-width:320px){
  14.   .no-csstransforms .cn-wrapper{
  15.     width:15.15px;
  16.     margin-left: -7.5em;
  17.   }
  18.   .no-csstransforms .cn-wrapper li{
  19.     height:3em;
  20.     width:3em;
  21.   }
  22. }

JAVASCRIPT

在这个 demo 中我们不想使用任何的 javascript 框架。我们用 Classie.js 来添加和删除 class,如果浏览器不支持 addEventListener 和 removeEventListener,可以使用 EventListener polyfill 来解决。我们将给按钮添加点击事件,点击按钮将使菜单打开或关闭。当菜单打开时,点击菜单外的任何地方,菜单也将关闭。

  1. (function(){
  2.  
  3.   var button = document.getElementById('cn-button'),
  4.     wrapper = document.getElementById('cn-wrapper'),
  5.     overlay = document.getElementById('cn-overlay');
  6.  
  7.   //open and close menu when the button is clicked
  8.   var open = false;
  9.   button.addEventListener('click', handler, false);
  10.   button.addEventListener('focus', handler, false);
  11.   wrapper.addEventListener('click', cnhandle, false);
  12.  
  13.   function cnhandle(e){
  14.     e.stopPropagation();
  15.   }
  16.  
  17.   function handler(e){
  18.     if (!e) var e = window.event;
  19.     e.stopPropagation();//so that it doesn't trigger click event on document
  20.  
  21.       if(!open){
  22.         openNav();
  23.       }
  24.     else{
  25.         closeNav();
  26.       }
  27.   }
  28.   function openNav(){
  29.     open = true;
  30.       button.innerHTML = "-";
  31.       classie.add(overlay, 'on-overlay');
  32.       classie.add(wrapper, 'opened-nav');
  33.   }
  34.   function closeNav(){
  35.     open = false;
  36.     button.innerHTML = "+";
  37.     classie.remove(overlay, 'on-overlay');
  38.     classie.remove(wrapper, 'opened-nav');
  39.   }
  40.   document.addEventListener('click', closeNav);
  41.  
  42. })();

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

CSS3 超炫丽环状导航菜单动画效果

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

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

发表回复

热销模板

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

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