Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save KalipheGTU/ac8dafb9b2a91c99ab3896cb651e8360 to your computer and use it in GitHub Desktop.
Save KalipheGTU/ac8dafb9b2a91c99ab3896cb651e8360 to your computer and use it in GitHub Desktop.
[in progress] Circular navigation
[[[https://codepen.io/sonjastrieder/pen/2d092b10733ad0676f682d49fad86076]]]
<svg class="svg-defs" style="height: 0; position: absolute;">
<defs>
<mask id="RingSm" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<circle cx=".5" cy=".5" r=".32" fill="white" />
<circle cx=".5" cy=".5" r=".23" fill="black" />
</mask>
<mask id="RingLg" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<circle cx=".5" cy=".5" r=".5" fill="white" />
<circle cx=".5" cy=".5" r=".41" fill="black" />
<!-- <circle cx=".5" cy=".5" r=".5" fill="white" />
<circle cx=".5" cy=".5" r=".41" fill="tomato" /> -->
</mask>
<symbol id="pic1">
<image xlink:href="https://images.unsplash.com/uploads/1412862685615b0212e3d/5fcb0a55?dpr=1&auto=format&fit=crop&w=1000&h=1000&q=80&cs=tinysrgb&crop=&bg=" width="500" height="500" />
<!-- <rect y="0" width="500" height="500" fill="#111" fill-opacity="0.6" /> -->
</symbol>
<symbol id="pic2">
<image xlink:href="https://images.unsplash.com/photo-1486122676632-ad1b5681fe33?dpr=1&auto=format&fit=crop&w=1000&h=1000&q=80&cs=tinysrgb&crop=&bg=" width="500" height="500" />
</symbol>
<symbol id="pic3">
<image xlink:href="https://images.unsplash.com/44/MIbCzcvxQdahamZSNQ26_12082014-IMG_3526.jpg?dpr=1&auto=format&fit=crop&w=1000&h=1000&q=80&cs=tinysrgb&crop=&bg=" width="500" height="500" />
</symbol>
</defs>
</svg>
<a class="u-vh Skip" href="#maincontent">Skip to main content</a>
<div class="Cover">
<header class="Cover-content">
<h1 class="MegaTitle MegaTitle--cover">
octopuses
<span class="MegaTitle-sub">Academy</span>
</h1>
<p class="Subtext Subtext--cover">Lorem ipsum consectetur<br>
adipisicing</p>
</header>
<div class="Cover-overlay">
<nav class="CircleMenu">
<ul class="CircleMenu-nav">
<li>
<a class="CircleMenu-nav-itemIco anim-triggerCircleMenu" href="#">
<span class="u-vh">Home</span>
<svg class="Ico"><use xlink:href="#icoLogo"></use></svg>
</a>
<div class="CircleMenu-nav-itemImg">
<div class="u-responsiveSquare">
<svg viewBox="0 0 500 500">
<use class="u-svgMaskRingLg anim-shiftOut" xlink:href="#pic2"></use>
<use class="u-svgMaskRingSm anim-shiftIn" xlink:href="#pic2"></use>
</svg>
</div>
</div>
</li>
<li>
<a class="anim-triggerCircleMenu" href="#">Eleven</a>
<div class="CircleMenu-nav-itemImg">
<div class="u-responsiveSquare">
<svg viewBox="0 0 500 500">
<use class="u-svgMaskRingLg anim-shiftOut" xlink:href="#pic1"></use>
<use class="u-svgMaskRingSm anim-shiftIn" xlink:href="#pic1"></use>
</svg>
</div>
</div>
</li>
<li>
<a class="anim-triggerCircleMenu" href="#">Twelve</a>
<div class="CircleMenu-nav-itemImg">
<div class="u-responsiveSquare">
<svg viewBox="0 0 500 500">
<use class="u-svgMaskRingLg anim-shiftOut" xlink:href="#pic3"></use>
<use class="u-svgMaskRingSm anim-shiftIn" xlink:href="#pic3"></use>
</svg>
</div>
</div>
</li>
<li>
<a class="anim-triggerCircleMenu" href="#">Thirteen</a>
<div class="CircleMenu-nav-itemImg">
<div class="u-responsiveSquare">
<svg viewBox="0 0 500 500">
<use class="u-svgMaskRingLg anim-shiftOut" xlink:href="#pic2"></use>
<use class="u-svgMaskRingSm anim-shiftIn" xlink:href="#pic2"></use>
</svg>
</div>
</div>
</li>
<li>
<a class="CircleMenu-nav-itemIco" href="#maincontent">
<span class="CircleMenu-nav-itemIco-text">Scroll</span>
<svg class="Ico"><use xlink:href="#icoMouse"></use></svg>
</a>
</li>
<li>
<a class="anim-triggerCircleMenu" href="#">Fourteen</a>
<div class="CircleMenu-nav-itemImg">
<div class="u-responsiveSquare">
<svg viewBox="0 0 500 500">
<use class="u-svgMaskRingLg anim-shiftOut" xlink:href="#pic1"></use>
<use class="u-svgMaskRingSm anim-shiftIn" xlink:href="#pic1"></use>
</svg>
</div>
</div>
</li>
<li>
<a class="anim-triggerCircleMenu" href="#">Fifteen</a>
<div class="CircleMenu-nav-itemImg">
<div class="u-responsiveSquare">
<svg viewBox="0 0 500 500">
<use class="u-svgMaskRingLg anim-shiftOut" xlink:href="#pic3"></use>
<use class="u-svgMaskRingSm anim-shiftIn" xlink:href="#pic3"></use>
</svg>
</div>
</div>
</li>
<li>
<a class="anim-triggerCircleMenu" href="#">Sixteen</a>
<div class="CircleMenu-nav-itemImg">
<div class="u-responsiveSquare">
<svg viewBox="0 0 500 500">
<use class="u-svgMaskRingLg anim-shiftOut" xlink:href="#pic2"></use>
<use class="u-svgMaskRingSm anim-shiftIn" xlink:href="#pic2"></use>
</svg>
</div>
</div>
</li>
</ul>
</nav>
</div>
</div>
<main id="maincontent">
Thanks for watching!
</main>
<script src="https://codepen.io/sonjastrieder/pen/56a60d968903c65fa7983f3e6877510e"></script>
//
// Circular nav
$CircleMenu-count: 8;
$CircleMenu-size: 70vmin;
$CircleMenu-offset: 9%; // >>> remember to update svg mask radius too :( <<<
$CircleMenu-color: #fff;
$CircleMenu-lineHeight: 2em;
$CircleMenu-keyline: rgba($CircleMenu-color, 0.12);
//
// Cover
$Cover-color: #fff;
$Cover-titleWidth: $CircleMenu-size + 8vmin;
//
// Icon
$Ico-size: unitSize(3);
$Ico-color: currentColor;
//
// Base
$bg: "https://images.unsplash.com/photo-1490260933405-2d50861204d1?dpr=1&auto=format&fit=crop&w=1199&h=799&q=80&cs=tinysrgb&crop=";
$z-indexes: (
cover: (
overlay,
content
),
header: (),
modal: (),
skip: ()
);
// ========================================
// Base
//
@at-root {
.dev {
body {
&:after,
&:before {
content: "";
position: fixed;
z-index: 1;
top: 50%;
left: 0;
width: 100%;
border-top: 1px dashed rgba(yellow, 0.1);
pointer-events: none;
}
&:after {
transform: rotate(90deg);
}
}
}
body {
letter-spacing: 0.04em;
}
.Skip {
&:focus,
&:active {
color: inherit;
font-size: 75%;
font-style: italic;
display: block;
text-decoration: none;
position: relative;
z-index: z(skip);
width: 100%;
height: auto;
text-align: center;
clip-path: none;
background-color: color(background);
}
}
}
// ========================================
// Typography
//
@at-root {
h1, h2, h3, h4, h5, h6, p {
margin-top: 0;
margin-bottom: unitSize(2.5);
}
.MegaTitle {
font-weight: 400;
line-height: 1;
text-transform: uppercase;
}
.MegaTitle-sub {
font-size: 0.333em;
letter-spacing: 0.42em;
display: block;
margin-top: unitSize(2.5);
}
.MegaTitle--cover {
font-size: $CircleMenu-size / 6.45;
margin-bottom: $CircleMenu-size / 21;
.MegaTitle-sub {
margin-top: $CircleMenu-size / 21;
}
}
.Subtext {
letter-spacing: 0.42em;
}
.Subtext--cover {
@include responsive-font(2vmin, 12px, 16px, 16px);
}
}
// ========================================
// Utilities
//
@at-root {
//
// Wrapper - Responsive media
//
.u-responsiveSquare {
position: relative;
width: 100%;
height: 0;
padding-bottom: 100%;
margin: 0 auto;
overflow: hidden;
//
// extendable with img, video, ...
svg {
position: absolute;
top: 0;
left: 0;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
}
//
// SVG masks
//
.u-svgMaskRingSm {
mask: url(#RingSm);
}
.u-svgMaskRingLg {
mask: url(#RingLg);
}
//
// Visually hidden
//
.u-vh {
@extend %visuallyHidden;
}
//
// Hidden xs down
//
@include media-breakpoint-down(xs) {
.u-hidden-xs-down {
display: none;
}
}
}
// ========================================
// Layout
//
@at-root {
main {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
}
// ========================================
// Icon
//
@at-root {
.Ico {
display: inline-block;
width: $Ico-size;
height: $Ico-size;
vertical-align: middle;
box-sizing: content-box;
fill: $Ico-color;
}
}
// ========================================
// Circle Menu
//
@at-root {
%CircleMenu-ringPseudo {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border-radius: 50%;
border: 1px solid $CircleMenu-keyline;
}
.CircleMenu {
position: relative;
width: $CircleMenu-size;
height: $CircleMenu-size;
border-radius: 50%;
//
// Inner ring 2 and 3
&:before {
@extend %CircleMenu-ringPseudo;
width: 100% - $CircleMenu-offset * 6;
height: 100% - $CircleMenu-offset * 6;
}
&:after {
@extend %CircleMenu-ringPseudo;
width: 100% - $CircleMenu-offset * 4;
height: 100% - $CircleMenu-offset * 4;
}
//
// Breakpoint - hide on small viewports
@media (max-width: 550px), (max-height: 400px) {
display: none;
}
}
.CircleMenu-nav {
color: $CircleMenu-color;
font-size: 1.4rem;
line-height: $CircleMenu-lineHeight;
text-transform: uppercase;
width: 100%;
height: 100%;
margin: 0;
padding-left: 0;
border-radius: 50%;
border: 1px solid $CircleMenu-keyline;
list-style: none;
//
// Inner ring 1
&:before {
@extend %CircleMenu-ringPseudo;
width: 100% - $CircleMenu-offset * 2;
height: 100% - $CircleMenu-offset * 2;
}
a {
color: inherit;
text-decoration: none;
white-space: nowrap;
position: relative;
display: block;
//
// Small dot in front of link
//
// Requires :after for flipped links on the left hand
// side of the circle
&:not(.CircleMenu-nav-itemIco) {
margin-left: -0.3em;
&:before,
&:after {
font-size: 2em;
line-height: 0;
vertical-align: middle;
}
&:before {
content: "\00B7\00a0";
}
}
}
//
// 1. Make sure image overlay is not coverying parts
// of the menu items by moving it behind all other
// li elements
li {
position: absolute;
z-index: 10; // 1
top: 50%;
left: 50%;
padding-left: 50%;
margin-top: -$CircleMenu-lineHeight / 2;
transform-origin: 0 50%;
&:hover {
z-index: 5; // 1
}
//
// Position menu items around the circle and
// reset rotation for hover images
@for $i from 1 to $CircleMenu-count + 1 {
&:nth-child(#{$i}) {
$deg: 360deg/$CircleMenu-count * $i - 90deg - 45deg;
transform: rotate($deg);
.CircleMenu-nav-itemImg {
transform: rotate(-$deg) translateX(-50%) translateY(-50%);
}
}
}
//
// Flip link text on left side of circle
&:nth-child(#{floor($CircleMenu-count/2)}) ~ li {
a {
transform-origin: 50% 50%;
transform: rotate(180deg);
&:not(.CircleMenu-nav-itemIco) {
&:before {
content: "";
}
&:after {
content: "\00a0\00B7";
}
}
}
}
}
}
//
// Menu item image
//
.CircleMenu-nav-itemImg {
// display: none;
position: absolute;
z-index: -1;
top: $CircleMenu-lineHeight / 2;
left: 0;
width: $CircleMenu-size;
height: $CircleMenu-size;
transform-origin: 0 0;
pointer-events: none;
filter: brightness(70%) saturate(80%) grayscale(40%);
}
//
// Menu icon items (scroll, logo)
//
.CircleMenu-nav-itemIco {
transform: rotate(-90deg) translateY(-50%) !important;
}
.CircleMenu-nav-itemIco-text {
font-size: 0.7em;
position: absolute;
left: 50%;
top: -90%;
transform: translateX(-50%);
}
}
// ========================================
// Cover
//
@at-root {
.Cover {
display: flex;
justify-content: center;
align-items: center;
position: relative;
height: 100vh;
width: 100%;
background-color: #111;
//
// Transparent image overlay
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url("https://images.unsplash.com/photo-1487932451588-8f8110a354e7");
background-image: url(#{$bg});
background-size: cover;
background-position: center center;
opacity: 0.12;
}
}
.Cover-content {
color: $Cover-color;
text-align: center;
position: relative;
z-index: z(cover, content);
max-width: $Cover-titleWidth;
}
.Cover-overlay {
position: absolute;
z-index: z(cover, overlay);
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
}
}
// ========================================
// Animation
//
@at-root {
.anim-trigger:hover,
.anim-triggerCircleMenu:hover + .CircleMenu-nav-itemImg {
.anim-shiftOut {
transform: scale(1);
opacity: 1;
}
.anim-shiftIn {
transform: scale(1);
opacity: 1;
}
}
.anim-shiftOut {
opacity: 0;
transform: scale(0.64);
transform-origin: 50% 50%;
transition: transform 0.5s ease, opacity 0.5s ease;
}
.anim-shiftIn {
opacity: 0;
transform: scale(1.56);
transform-origin: 50% 50%;
transition: transform 0.5s ease, opacity 0.5s ease;
}
}
<link href="https://codepen.io#__TOOLS__/sonjastrieder/pen/abf169df77e0bc560c3d98672426fa26" rel="stylesheet" />
<link href="https://codepen.io#__BASE__/sonjastrieder/pen/e9a828d8e47cd73a24b9bc110e7d41fa" rel="stylesheet" />
<link href="https://codepen.io#__sassEXTENDS__/sonjastrieder/pen/198d5c34967e4772bc398cb9c9238944" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment