Demo: http://sparanoid.com/lab/path-menu/
Dribbble page: http://drbl.in/cwcK
Forked from Tunghsiao Liu's Pen Path 2.0 Flyout Menu using CSS .
A Pen by Marcello Africano on CodePen.
| <div class="testfield"> | |
| <div class="flyout-wrap"> | |
| <a class="flyout-btn" href="#" title="Toggle"><span>Flyout Menu Toggle</span></a> | |
| <ul class="flyout flyout-init"> | |
| <li><a href="#"><span>Item</span></a></li> | |
| <li><a href="#"><span>Item</span></a></li> | |
| <li><a href="#"><span>Item</span></a></li> | |
| <li><a href="#"><span>Item</span></a></li> | |
| <li><a href="#"><span>Item</span></a></li> | |
| <li><a href="#"><span>Item</span></a></li> | |
| </ul><!-- .flyout --> | |
| </div><!-- .flyout-wrap --> | |
| <h1><a href="https://path.com/">Path</a> 2.0 Flyout Menu using CSS by <a href="http://sparanoid.com/">Tunghsiao Liu</a></h1> | |
| </div><!-- #testfield --> |
| $(".flyout-btn").click -> | |
| $(".flyout-btn").toggleClass "btn-rotate" | |
| $(".flyout").find("a").removeClass() | |
| $(".flyout").removeClass("flyout-init fade").toggleClass "expand" | |
| $(".flyout").find("a").click -> | |
| $(".flyout-btn").toggleClass "btn-rotate" | |
| $(".flyout").removeClass("expand").addClass "fade" | |
| $(this).addClass "clicked" |
| <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> |
| // Basic reset | |
| p, hr, pre, blockquote, | |
| ol, ul, li, dl, dt, dd, | |
| a, em, strong, small, s, cite, q, dfn, abbr, time, code, var, i, b, u, span, br, wbr, | |
| h1, h2, h3, h4, h5, h6 { | |
| padding: 0; | |
| margin: 0; | |
| } | |
| :root { | |
| padding: 60px; | |
| font-family: Helvetica, 'Hiragino Sans GB', Arial, sans-serif; | |
| font-smoothing: antialiased; | |
| background: #f9f4f0; | |
| -webkit-tap-highlight-color: rgba(0, 0, 0, 0); | |
| } | |
| @d1: (@r * 0); | |
| @d2: (@r * 1); | |
| @d3: (@r * 2); | |
| @d4: (@r * 3); | |
| @d5: (@r * 4); | |
| @d6: (@r * 5); | |
| @r: 18deg; | |
| @n: 6; | |
| .testfield { | |
| width: 210px; | |
| margin: 0 auto; | |
| // background: #fff; | |
| } | |
| h1 { | |
| padding: 7px 10px; | |
| margin: 20px 0 10px; | |
| font-size: 12px; | |
| line-height: 1.6; | |
| @color: #6d492a; | |
| color: fade(@color, 80%); | |
| text-shadow: #fff 0 1px 1px; | |
| background: #f1e7de; | |
| border: 1px solid #d3bfae; | |
| border-radius: 3px; | |
| box-shadow: inset #fff 0 1px 0 0; | |
| a { | |
| color: #6d492a; | |
| text-decoration: none; | |
| border-bottom: 1px dotted #d3bfae; | |
| &:hover { | |
| border-color: #6d492a; | |
| } | |
| } | |
| } | |
| .flyout-wrap { | |
| position: relative; | |
| height: 191px; | |
| .flyout { | |
| position: relative; | |
| margin: 0 0 1px 6px; | |
| line-height: 0; | |
| & > li { | |
| position: absolute; | |
| display: block; | |
| height: 170px; | |
| background: yellow; | |
| transform-origin: (25px / 2) bottom; | |
| // Transform loop | |
| .generate-rotate-loop (@i) when (@i =< @n) { | |
| &:nth-of-type(@{i}) { transform: rotate(@r * (@i - 1)); } | |
| .generate-rotate-loop(@i + 1); | |
| } | |
| .generate-rotate-loop(1); | |
| a { | |
| position: absolute; | |
| display: block; | |
| width: 26px; | |
| height: 26px; | |
| overflow: hidden; | |
| text-indent: -99999px; | |
| background: #444; | |
| border: 3px solid #fff; | |
| border-radius: 50%; | |
| box-shadow: rgba(0, 0, 0, .4) 0 0 5px 0, rgba(0, 0, 0, .2) 0 0 0 1px, inset rgba(0, 0, 0, .5) 0 0 2px 0; | |
| &:active { | |
| background: #000; | |
| border-color: #555; | |
| span { | |
| opacity: .3; | |
| } | |
| } | |
| span { | |
| display: block; | |
| width: 26px; | |
| height: 26px; | |
| background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16px' height='16px'><path fill='#fff' d='M11.045,9.879l1.906,6.114l-4.949-3.791L3.059,16l1.9-6.117L0,6.114l6.123,0.013L7.998,0l1.879,6.12L16,6.104L11.045,9.879z'/></svg>") no-repeat center center; | |
| background-size: 16px 16px; | |
| // mask-image: url(star.svg); | |
| } | |
| } | |
| } | |
| } | |
| // Triggers | |
| .flyout-init li { | |
| display: none; | |
| } | |
| // Normal | |
| .flyout li a { | |
| top: 150px; | |
| animation: contract .35s ease-out 1 backwards; | |
| } | |
| // Active | |
| .flyout.expand li a { | |
| top: 10px; | |
| animation: expand .6s ease 1 backwards; | |
| } | |
| // Clicked | |
| .flyout.fade li a.clicked { | |
| top: 10px; | |
| animation: clicked .5s ease-out 1 forwards; | |
| } | |
| .flyout.fade li a:not(.clicked) { | |
| top: 10px; animation: fade .5s ease-out 1 forwards; | |
| span { | |
| opacity: .1; | |
| transition: opacity .5s ease; | |
| } | |
| } | |
| // Animation loop | |
| .generate-item-loop (@i) when (@i =< @n) { | |
| .flyout li:nth-of-type(@{i}) a { animation-delay: (.20s - .04s * (@i - 1)); } | |
| .flyout li:nth-of-type(@{i}) a:not(.clicked) span { animation: ~"spin@{i}-contract .9s ease-out 1 backwards"; } | |
| .flyout.expand li:nth-of-type(@{i}) a { animation-delay: (.04s * (@i - 1)); } | |
| .flyout.expand li:nth-of-type(@{i}) a span { transform: rotate(-(@r * (@i - 1))); animation: ~"spin@{i}-expand .6s ease-out 1 backwards"; } | |
| .flyout.fade li:nth-of-type(@{i}) a.clicked span { transform: rotate(-(@r * (@i - 1))); } | |
| .generate-item-loop(@i + 1); | |
| } | |
| .generate-item-loop(1); | |
| .flyout-btn { | |
| position: absolute; | |
| bottom: 0; | |
| left: 0; | |
| z-index: 9999; | |
| width: 36px; | |
| height: 36px; | |
| overflow: hidden; | |
| text-indent: -99999px; | |
| background: #f76f54; | |
| background: linear-gradient(top, #f76f54 0, #dd3535 49%, #d32121 51%, #c61f1f 100%); | |
| border: 4px solid #fff; | |
| border-radius: 50%; | |
| outline: none; | |
| box-shadow: rgba(0, 0, 0, .3) 0 3px 8px 0, rgba(0, 0, 0, .2) 0 0 0 1px, inset rgba(0, 0, 0, .3) 0 0 0 1px, inset rgba(255, 255, 255, .3) 0 1px 0 1px; | |
| &:hover { | |
| // never mind | |
| } | |
| span { | |
| display: block; | |
| width: 36px; | |
| height: 36px; | |
| background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='20px' height='20px'><g><path fill='#fff' d='M20,11.402c0,0.453-0.367,0.82-0.822,0.82H0.82c-0.453,0-0.82-0.367-0.82-0.82V8.598 c0-0.454,0.367-0.821,0.82-0.821h18.357C19.633,7.776,20,8.144,20,8.598V11.402z'/><path fill='#fff' d='M8.598,20c-0.453,0-0.821-0.367-0.821-0.82V0.821c0-0.452,0.368-0.82,0.821-0.82h2.804 c0.453,0,0.82,0.368,0.82,0.82V19.18c0,0.453-0.367,0.82-0.82,0.82H8.598z'/></g></svg>") no-repeat center center; | |
| transition: transform .4s ease; | |
| } | |
| } | |
| .flyout-btn.btn-rotate span { | |
| transform: rotate(-135deg); | |
| } | |
| .ani-expand { | |
| 0% { top: 150px; } | |
| 50% { top: -10px; } | |
| 70% { top: 15px; } | |
| 100% { top: 10px; } | |
| } | |
| .ani-contract { | |
| 0% { top: 10px; } | |
| 40% { top: -25px; } | |
| 100% { top: 150px; } | |
| } | |
| .ani-clicked { | |
| 0% { opacity: 1; transform: scale(1); } | |
| 100% { opacity: 0; transform: scale(5); } | |
| } | |
| @keyframes expand { .ani-expand } | |
| @keyframes contract { .ani-contract } | |
| // A small trick | |
| @keyframes clicked { | |
| 0% { transform: scale(1); opacity: 1; top: 10px; } | |
| 90% { top: 10px; } | |
| 99% { transform: scale(6); opacity: 0; top: 150px; } | |
| 100% { transform: scale(0); } | |
| } | |
| @keyframes fade { | |
| 0% { transform: scale(1); opacity: 1; top: 10px; } | |
| 90% { opacity: 0; top: 10px; } | |
| 99% { transform: scale(0); top: 150px; } | |
| 100% { transform: scale(0); } | |
| } | |
| // Item animation loop | |
| .loop-content(@v) { | |
| @var: "d@{v}"; | |
| @var-keyframe-expand: ~"spin@{v}-expand"; | |
| @var-keyframe-contract: ~"spin@{v}-contract"; | |
| } | |
| .generate-slide-loop (@i) when (@i =< @n) { | |
| .loop-content(@i); | |
| @keyframes @var-keyframe-expand { | |
| 0% { transform: rotate((0 - @@var)); } | |
| 60% { transform: rotate((-360deg - @@var)); } | |
| 100% { transform: rotate((-360deg - @@var)); } | |
| } | |
| @keyframes @var-keyframe-contract { | |
| 0% { transform: rotate((0 - @@var)); } | |
| 50% { transform: rotate( 360deg); } | |
| 100% { transform: rotate( 360deg); } | |
| } | |
| .generate-slide-loop(@i + 1); | |
| } | |
| .generate-slide-loop(1); | |
| } |