Пример:
HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<div class="menu-container"> <div class="menu"> <button class="menu-item active" style="--bgColorItem: #ff8c00;" > <svg class="icon" viewBox="0 0 24 24"> <path d="M3.8,6.6h16.4"/> <path d="M20.2,12.1H3.8"/> <path d="M3.8,17.5h16.4"/> </svg> </button> <button class="menu-item" style="--bgColorItem: #337AB7;"> <svg class="icon" viewBox="0 0 24 24"> <path d="M6.7,4.8h10.7c0.3,0,0.6,0.2,0.7,0.5l2.8,7.3c0,0.1,0,0.2,0,0.3v5.6c0,0.4-0.4,0.8-0.8,0.8H3.8 C3.4,19.3,3,19,3,18.5v-5.6c0-0.1,0-0.2,0.1-0.3L6,5.3C6.1,5,6.4,4.8,6.7,4.8z"/> <path d="M3.4,12.9H8l1.6,2.8h4.9l1.5-2.8h4.6"/> </svg> </button> <button class="menu-item" style="--bgColorItem: #4343f5;"> <svg class="icon" viewBox="0 0 24 24"> <path d="M3.4,11.9l8.8,4.4l8.4-4.4"/> <path d="M3.4,16.2l8.8,4.5l8.4-4.5"/> <path d="M3.7,7.8l8.6-4.5l8,4.5l-8,4.3L3.7,7.8z"/> </svg> </button> <button class="menu-item" style="--bgColorItem: #e0b115;"> <svg class="icon" viewBox="0 0 24 24" > <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path> <polyline points="22,6 12,13 2,6"></polyline> </svg> </button> <button class="menu-item" style="--bgColorItem: #589f2c;"> <svg class="icon" viewBox="0 0 24 24" > <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"></path> <circle cx="12" cy="13" r="4"></circle> </svg> </button> <div class="menu-border"></div> </div> </div> <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> |
Цвет активной вкладки задается в переменной --bgColorItem
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
.menu-container * { box-sizing: border-box; } .menu-container { margin: 0; display: flex; height: 10em; overflow: hidden; align-items: flex-end; justify-content: center; } .menu { margin: 0; display: flex; width: 100%; font-size: 1.5em; padding: 0 2.5em; position: relative; align-items: center; justify-content: center; background-color: #1d1d27; } .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 , .7s); } .menu-item::before { content: ""; z-index: -1; width: 4.2em; height: 4.2em; border-radius: 50%; position: absolute; transform: scale(0); transition: background-color .7s, transform .7s; } .menu-item.active { transform: translate3d(0, -.8em , 0); } .menu-item.active::before { transform: scale(1); background-color: var(--bgColorItem); } .icon { width: 2.6em; height: 2.6em; 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(#menu); will-change: transform; background-color: #1d1d27; transition: transform var(--timeOut , .7s); } .svg-container { width: 0; height: 0; } @media screen and (max-width: 50em) { .menu-container { height: 6em; } .menu { font-size: .8em; } } |
JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
"use strict"; const menu = document.body.querySelector(".menu"); const menuItems = menu.querySelectorAll(".menu-item"); const menuBorder = menu.querySelector(".menu-border"); let activeItem = menu.querySelector(".active"); function clickItem(item, index) { menu.style.removeProperty("--timeOut"); if (activeItem == item) return; if (activeItem) { activeItem.classList.remove("active"); } item.classList.add("active"); activeItem = item; offsetMenuBorder(activeItem, menuBorder); } function offsetMenuBorder(element, menuBorder) { const offsetActiveItem = element.getBoundingClientRect(); const left = Math.floor(element.offsetLeft - (menuBorder.offsetWidth - offsetActiveItem.width) / 2) + "px"; menuBorder.style.transform = `translate3d(${left}, 0 , 0)`; } offsetMenuBorder(activeItem, menuBorder); menuItems.forEach((item, index) => { item.addEventListener("click", () => clickItem(item, index)); }) window.addEventListener("resize", () => { offsetMenuBorder(activeItem, menuBorder); menu.style.setProperty("--timeOut", "none"); }); |
Найдено на codepen.io у пользователя abxlfazl khxrshidi
Подскажите добавить ссылки в это меню. Всю голову сломала. Стандартные способы не работают.
Тут не ссылки нужны, иначе потеряется весь смысл кнопок - анимация .
Нужно под них писать различные действия на JS, например одна кнопка открывает одну вкладку, другая другую и т.д.
Если делать ссылки, то это по якорям на странице - просто заменить button на a, но тут тоже не лишнем будет добавить на JS активацию кнопки, когда мы перейдем на якорь прокруткой.
Подскажите пожалуйста как закрепить его внизу экрана телефона, чтобы не пропадало при скроллинге
Спасибо!! Все получилось.
Еще обнаружила, что остальные блоки проходят поверх него, когда страницу пролистываешь. А он должен быть поверх всего. Как настроить? Пробовала с z индексом пошаманить, не получается. 🙁
все решилось. Пошаманили с z индексом и легло как надо. Спасибо еще раз!
Подскажите пожалуйста, куда прописывается контент табы?
Это просто анимация кнопок для дальнейшего творчества, например перехода по якорям, подзагрузки контента или перелистывания табов.