<nav class="tab" data-selected="2">
<div class="icons">
<div data-index="1" class="icon fad fa-home"></div>
<div data-index="2" class="icon fal fa-plus"></div>
<div data-index="3" class="icon fad fa-user fa-swap-opacity"></div>
</div>
<div class="bar">
<div class="cap"></div>
<div class="middle">
<div class="side"></div>
<div class="circle"></div>
<div class="side"></div>
</div>
<div class="cap"></div>
</div>
</nav>
$transition:.75s;
body {
display:flex;
justify-content:center;
align-items:center;
background:#E6E9ED;
//background-image: linear-gradient(-45deg, #8067B7, #EC87C0);
//That circle gap is a real gap, uncomment above
min-height:100vh;
nav.tab {
position: relative;
display:flex;
align-items:stretch;
width:23rem;
height:4rem;
&.moving .icon {
pointer-events:none;
}
&[data-selected="1"] .icon:nth-child(1),
&[data-selected="2"] .icon:nth-child(2),
&[data-selected="3"] .icon:nth-child(3) {
top:-1.5rem;
color:#2ABA66;
font-size:2rem;
transition:.25s $transition/2;
pointer-events:none;
&.initialised {
animation: hide $transition*1.2 forwards;
}
}
&[data-selected="1"] .bar .middle .side:first-child,
&[data-selected="3"] .bar .middle .side:last-child{
flex-grow:0;
//Sliding works with 2 `flex-grow:1` elements either side of the circle
//To animate set the one you want to go to 0
}
.icons {
position: absolute;
z-index:2;
display:flex;
justify-content:space-around;
width:calc(100% - 2rem);
padding:0 1rem;
.icon {
position: relative;
top:0rem;
width:4rem;
line-height:4rem;
font-size:1.5rem;
text-align:center;
cursor: pointer;
transition-delay:$transition/4;
&.initialised { //So animations don't start on load, .icon gets .initialised after it is clicked
animation: hide2 $transition/2;
}
}
}
.bar {
z-index:1;
position: absolute;
display:flex;
align-items:stretch;
filter: drop-shadow(0 0 0.5rem rgba(0,0,0,0.1)) drop-shadow(0 0 0.25rem rgba(0,0,0,0.1));
//^ Otherwise everything is pointless, everything has lead up to this shadow
width:100%;
height:100%;
.cap {
background:white;
width:1rem;
&:first-child {
border-bottom-left-radius:1rem;
border-top-left-radius:0.5rem;
box-shadow:0.25rem 0 0 white;
//^ Sometimes when the circle moves small gaps <1px form on the sides, this makes an overlap to hide it
}
&:last-child {
border-bottom-right-radius:1rem;
border-top-right-radius:0.5rem;
box-shadow:-0.25rem 0 0 white;
}
}
.middle {
flex-grow:1;
position: relative;
display:flex;
.circle {
position: relative;
top:-1.75rem;
width:7rem;
height:5.75rem;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='112' height='92' viewBox='0 0 112 92'%3E%3Ccircle cx='56' cy='36' r='36' fill='%23FFF'/%3E%3Cpath d='M104 35.2L104 35.2c0 26.3-20.9 48.3-47.2 48.8C29.9 84.4 8 62.8 8 36v-0.8c0-4-3.2-7.2-7.2-7.2H0v64h112V28h-0.8C107.2 28 104 31.2 104 35.2z' fill='%23FFF'/%3E%3C/svg%3E");
//^ Cheating, or being smart?
}
.side {
flex-grow:1;
background:white;
transition:$transition ease;
}
}
}
}
}
@keyframes hide {
0%, 100% {
opacity:1;
}
25%, 75% {
opacity:0;
}
}
@keyframes hide2 {
0%, 100% {
opacity:1;
}
15% /*This is the difference*/, 75% {
opacity:0;
}
}
View Compiled
let previous = -1;
$(".icon[data-index]").click(function(){
$(this).addClass("initialised");
let index = $(this).attr("data-index");
let navtab = $(this).closest("nav.tab").addClass("moving").attr("data-selected", index);
if(previous == -1) navtab.find('.icon[data-index="2"]').addClass("initialised")
if(previous == 1 && index == 3 || previous == 3 && index == 1) { //If going from one side to the other and middle needs to be hidden
navtab.find('.icon[data-index="2"]').removeClass("initialised");
setTimeout(function(){ //Because apparently this is the only way it will work
navtab.find('.icon[data-index="2"]').addClass("initialised"); //Same animation as the other so they line up
});
}
previous = index;
setTimeout(function(){
navtab.removeClass("moving").removeClass("hidemiddle");
}, 750);
});
/*🤢 If someone knows how to sort out the animations in a non-garbage way please fork and mention in a comment, I kinda got stuck.*/