- const vb = "0 0 24 24";
mixin box()
div.l1
svg(viewBox=vb)
path(d="M12.89 1.45l8 4A2 2 0 0 1 22 7.24v9.53a2 2 0 0 1-1.11 1.79l-8 4a2 2 0 0 1-1.79 0l-8-4a2 2 0 0 1-1.1-1.8V7.24a2 2 0 0 1 1.11-1.79l8-4a2 2 0 0 1 1.78 0z")
div.l2
svg(viewBox=vb, fill="none")
polyline(points="2.32 6.16 12 11 21.68 6.16")
div.l3
svg(viewBox=vb)
line(x1="12", y1="22.76", x2="12", y2="11")
mixin home()
div.l1
svg(viewBox=vb)
path(d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z")
div.l2
svg(viewBox=vb)
polyline(points="9 22 9 12 15 12 15 22")
mixin calender()
div.l1
svg(viewBox=vb)
rect(x="3", y="4", width="18", height="18", rx="2", ry="2")
div.l2
svg(viewBox=vb)
line(x1="16", y1="2", x2="16", y2="6")
line(x1="8", y1="2", x2="8", y2="6")
div.l3
svg(viewBox=vb)
line(x1="3", y1="10", x2="21", y2="10")
section#container
div#tab
div.icon.box.active(data-x="0")
+box
div.icon.home(data-x="1", style="animation: back 0s forwards")
+home
div.icon.calender(data-x="2", style="animation: back 0s forwards")
+calender
.circle(data-active="0", data-animating="true", style="top: 80%")
.circle-inner
a(href="https://twitter.com/AbubakerSaeed96", rel="nofollow noreferrer", target="_blank", class="abs-twitter")
svg(viewBox="0 0 32 32", height="28px", class="twitter-icon")
path(fill="hsl(358deg, 99%, 98%)", d="M32 7.075c-1.175 0.525-2.444 0.875-3.769 1.031 1.356-0.813 2.394-2.1 2.887-3.631-1.269 0.75-2.675 1.3-4.169 1.594-1.2-1.275-2.906-2.069-4.794-2.069-3.625 0-6.563 2.938-6.563 6.563 0 0.512 0.056 1.012 0.169 1.494-5.456-0.275-10.294-2.888-13.531-6.862-0.563 0.969-0.887 2.1-0.887 3.3 0 2.275 1.156 4.287 2.919 5.463-1.075-0.031-2.087-0.331-2.975-0.819 0 0.025 0 0.056 0 0.081 0 3.181 2.263 5.838 5.269 6.437-0.55 0.15-1.131 0.231-1.731 0.231-0.425 0-0.831-0.044-1.237-0.119 0.838 2.606 3.263 4.506 6.131 4.563-2.25 1.762-5.075 2.813-8.156 2.813-0.531 0-1.050-0.031-1.569-0.094 2.913 1.869 6.362 2.95 10.069 2.95 12.075 0 18.681-10.006 18.681-18.681 0-0.287-0.006-0.569-0.019-0.85 1.281-0.919 2.394-2.075 3.275-3.394z")
View Compiled
// SASS VARIABLES
// =====================================
$stroke-width: 1.4;
// DEFAULT
// =====================================
:root {
--tab-background: hsl(0deg, 33%, 99%);
--background: hsl(313deg, 96%, 10%);
--stroke-color: hsl(358deg, 99%, 65%);
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
box-sizing: border-box;
background: var(--background);
}
svg:not(.twitter-icon) {
color: var(--stroke-color);
height: inherit;
fill: var(--tab-background);
stroke: currentColor;
stroke-width: $stroke-width;
stroke-linecap: round;
stroke-linejoin: round;
pointer-events: none;
position: absolute;
}
// MAIN
// =====================================
#container {
--r: 50px;
min-width: 400px;
width: 400px;
max-width: 400px;
height: 380px;
display: flex;
align-items: flex-end;
border-radius: 2px 2px var(--r) var(--r);
overflow: hidden;
}
#tab {
background: var(--tab-background);
width: inherit;
height: 120px;
border-radius: inherit;
padding: 20px 80px;
box-sizing: border-box;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.icon {
$landed: -59px;
$back: 0px;
& {
width: 38px;
height: 38px;
position: relative;
z-index: 5;
cursor: pointer;
}
&.active {
&.box .l1,
&.home .l1,
&.calender .l1 {
--in: -252px;
animation: in 0.4s 1.1s forwards, landed 0.5s 1.5s forwards;
}
&.box .l2 {
--in: -212px;
}
&.box .l3 {
--in: -200px;
}
&.home .l2 {
--in: -216px;
animation: in 0.26s 1.14s forwards, landed 0.5s 1.5s forwards;
}
&.box .l2,
&.box .l3,
&.calender .l2,
&.calender .l3 {
animation: in 0.3s 1.1s forwards, landed 0.5s 1.5s forwards;
}
&.calender .l2 {
--in: -190px;
}
&.calender .l3 {
--in: -214px;
}
& .l1 svg {
animation: out 0.1s 1s forwards, in_again 0.2s 1.6s forwards;
}
}
&:not(.active) {
animation: back 0.2s forwards;
}
@keyframes in {
50% {
transform: translateY(calc(var(--in) + 10px));
}
100% {
transform: translateY(var(--in));
}
}
@keyframes out {
100% {
fill: transparent;
}
}
@keyframes landed {
70% {
transform: translateY($landed + 4px);
}
100% {
transform: translateY($landed);
}
}
@keyframes in_again {
100% {
fill: var(--tab-background);
}
}
@keyframes back {
0% {
transform: translateY($landed);
}
100% {
transform: translateY($back);
}
}
}
.box {
.l2 svg {
fill: transparent;
}
}
.home {
.l2 svg {
transform: translateY(-1px);
fill: transparent;
}
}
.circle {
$y-start: 80%;
$y-slow: -62%;
$y-landed: -34%;
& {
--s: 86px;
width: var(--s);
height: var(--s);
border-radius: var(--s);
transform: translateX(0);
position: absolute;
top: $y-landed;
left: 56px;
display: flex;
justify-content: center;
align-items: center;
}
&[data-active="0"] {
transform: translateX(0);
}
&[data-active="1"] {
transform: translateX(101px);
}
&[data-active="2"] {
transform: translateX(202px);
}
&[data-animating="true"] {
animation: landY 0.5s forwards, moveX 0.5s 0.5s forwards,
jumpY 0.5s 1s forwards, landedY 0.5s 1.5s forwards;
&>.circle-inner::before {
transform: scale(0);
animation: scale 0.3s 1.2s forwards;
}
}
@keyframes landY {
100% {
top: $y-start;
}
}
@keyframes moveX {
100% {
transform: translateX(var(--x));
}
}
@keyframes jumpY {
100% {
top: $y-slow;
}
}
@keyframes landedY {
70% {
top: $y-landed + 4%;
}
100% {
top: $y-landed;
}
}
&-inner {
& {
width: inherit;
height: inherit;
border-radius: inherit;
}
&::before,
&::after {
content: "";
display: inline-block;
width: inherit;
height: inherit;
border-radius: inherit;
transform-origin: center center;
position: absolute;
}
&::before {
background: var(--tab-background);
opacity: 0.1;
transform: scale(1.4);
}
&::after {
background: var(--stroke-color);
}
@keyframes scale {
0% {
transform: scale(1);
}
100% {
transform: scale(1.4);
}
}
}
}
// ABS
// =====================================
.abs-twitter {
& {
position: fixed;
right: calc(24px + .6vw);
top: calc(22px + .6vw);
transform: translate(-8px, 4px);
opacity: 0;
transition: .3s ease-in;
}
&--show {
transform: translate(0, 0);
opacity: 1;
animation: birdie 1s .8s linear infinite;
}
@keyframes birdie {
13% {
transform: rotate(14deg);
}
26% {
transform: rotate(28deg)
}
100% {
transform: rotate(0deg)
}
}
}
View Compiled
// By @AbubakerSaeed96 (Twitter)
// ===================
// Inspiration:
// Taras Migulko's dribbble shot: https://dribbble.com/shots/6798414
// Aaron Iker's codepen pen: https://codepen.io/aaroniker/pen/bGbBQaR
// Thank You For Viewing!
// Say 👋🏻 or hire me 👉🏻 abubaker.saeed.1996@gmail.com
// ================================================================
// Helpers
// =======
const $ = (e) => document.querySelector(e);
const $$ = (e) => document.querySelectorAll(e);
// Main
// ====
const t = $("#tab");
const ics = $$(".icon");
const c = $(".circle");
let s = {
animating: false,
animated: true,
};
// On Load
setTimeout(() => {
ics[1].removeAttribute("style");
ics[2].removeAttribute("style");
c.removeAttribute("style");
c.setAttribute("data-animating", "false");
}, 2000);
// On Event
ics.forEach((i, index) => {
i.addEventListener("click", ({ target }) => {
if (s.animated === true && index != c.getAttribute("data-active")) {
t.style.setProperty("--x", target.getAttribute("data-x") * 101 + "px");
$(".active").classList.remove("active");
i.classList.add("active");
c.setAttribute("data-animating", "true");
s.animating = true;
s.animated = false;
setTimeout(() => {
c.setAttribute("data-active", index);
c.setAttribute("data-animating", "false");
s.animating = false;
s.animated = true;
}, 2000);
}
});
});
// Professional Abubaker ;P
// =====================
const twitter = $(".abs-twitter");
window.addEventListener(
"mousemove",
() => twitter.classList.add("abs-twitter--show"),
{ once: true }
);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.