JSFiddle - React, Tailwind, and code Playground
by hmdadou
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<ul class="purr_menu">
<li class="menu__item active" style="--bgColorItem: #ff8c00;" >
<span class="material-icons-outlined">home</span>
</li>
<button class="menu__item" style="--bgColorItem: #f54888;">
<span class="material-icons-outlined">timer</span>
</button>
<button class="menu__item" style="--bgColorItem: #4343f5;" >
<span class="material-icons-outlined">add_a_photo</span>
</button>
<button class="menu__item" style="--bgColorItem: #e0b115;" >
<span class="material-icons-outlined">monitor_heart</span>
</button>
<button class="menu__item" style="--bgColorItem:#65ddb7;">
<span class="material-icons-outlined">help</span>
</button>
<div class="menu__border"></div>
</ul>
<div class="svg-container">
<svg viewBox="0 0 202.9 45.5" >
<clipPath id="menu" clipPathUnits="objectBoundingBox" transform="scale(0.0049285362247413 0.021978021978022)">
<path d="M6.7,45.5c5.7,0.1,14.1-0.4,23.3-4c5.7-2.3,9.9-5,18.1-10.5c10.7-7.1,11.8-9.2,20.6-14.3c5-2.9,9.2-5.2,15.2-7
c7.1-2.1,13.3-2.3,17.6-2.1c4.2-0.2,10.5,0.1,17.6,2.1c6.1,1.8,10.2,4.1,15.2,7c8.8,5,9.9,7.1,20.6,14.3c8.3,5.5,12.4,8.2,18.1,10.5
c9.2,3.6,17.6,4.2,23.3,4H6.7z"/>
</clipPath>
</svg>
</div>
CSS
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");
@import url("https://fonts.googleapis.com/icon?family=Material+Icons+Outlined");
html {
box-sizing: border-box;
--bgColorMenu : #1d1d27;
--duration: .7s;
}
html *,
html *::before,
html *::after {
box-sizing: inherit;
}
body{
margin: 0;
}
.purr_menu{
margin: 0;
display: flex;
/* Works well with 100% width */
width: 100%;
height:50px;
font-size: 1.5em;
padding: 0 2.85em;
position: relative;
align-items: center;
justify-content: center;
background-color: #f00;
margin-top:100px;
}
.menu__item{
all: unset;
flex-grow: 1;
z-index: 100;
display: flex;
cursor: pointer;
position: relative;
border-radius: 50%;
align-items: center;
will-change: transform;
justify-content: center;
padding: 0.55em 0 0.85em;
/* transition: transform var(--timeOut , var(--duration)); */
}
.menu__item::before{
content: "";
z-index: -1;
width: 2em;
height: 2em;
border-radius: 50%;
position: absolute;
transform: scale(0);
/* transition: background-color var(--duration), transform var(--duration); */
}
.menu__item.active {
transform: translate3d(0, -.8em , 0);
}
.menu__item.active::before{
transform: scale(1);
background-color: var(--bgColorItem);
}
.icon{
width: 1.5em;
height: 1.5em;
stroke: white;
fill: transparent;
stroke-width: 1pt;
stroke-miterlimit: 10;
stroke-linecap: round;
stroke-linejoin: round;
stroke-dasharray: 400;
}
.menu__item.active .icon {
animation: strok 1.5s reverse;
}
@keyframes strok {
100% {
/* stroke-dashoffset: 400; */
}
}
.menu__border{
left: 0;
bottom: 99%;
width: 10.9em;
height: 2.4em;
position: absolute;
/* clip-path: url(#1menu); */
will-change: transform;
...
JavaScript
$(document).ready(function(){
var body = $('body'),
bgColorsBody = ["#ffb457", "#ff96bd", "#9999fb", "#ffe797", "#cffff1"],
menu = $('.purr_menu'),
menuItems = $('.menu__item'),
menuBorder = $('.menu__border'),
activeItem = $('.active');
function clickItem(item, index){
menu.css('removeProperty', '--timeOut');
if(activeItem.is(item)) return;
activeItem.removeClass('active');
item.addClass('active');
body.css('background-color', bgColorsBody[index]);
activeItem = item;
offsetMenuBorder(activeItem, menuBorder);
}
/* left = -20; */
function offsetMenuBorder(element, menuBorder){
var offsetActiveItem = element.offset(),
left = Math.floor(offsetActiveItem.left - menu.offset().left - (menuBorder.width() - element.width()) / 2) + "px";
menuBorder.css('transform', 'translate3d(' + left + ', 0 , 0)');
}
offsetMenuBorder(activeItem, menuBorder);
menuItems.each(function(index){
$(this).click(function(){
clickItem($(this), index);
});
});
$(window).resize(function(){
offsetMenuBorder(activeItem, menuBorder);
menu.css('--timeOut', 'none');
});
});