Animowane menu CSS

Animowane menu CSS z kulą zmieniającą kolor

Menu CSS

Poziome, animowane menu nawigacyjne, wykonane za pomocą CSS3. Implementacja menu odbywa się poprzez umieszczenie kodu HTML w docelowym miejscu na stronie oraz edycję zmiennych CSS. Nawigacja jest responsywna - dostosowuje się do szerokości ekranu. Wykonana bez użycia JavaScript.

W celu dodania nawigacji na stronie internetowej należy umieścić kod z zakładki index.html w dowolnym miejscu strony docelowej. Następnie kod z zakładki menu.css umieszczamy w naszym arkuszu styli. Poniżej dema znajduje się instrukcja modyfikacji kodu.

<div class="compsoul-menu-ball-body">
<nav class="compsoul-menu-ball">
  <ul class="menu-container">
    <li class="menu-item">
      <a href="#" class="menu-link">Home</a>
    </li>
    <li class="menu-item">
      <a href="#" class="menu-link">About us</a>
    </li>
    <li class="menu-item">
      <a href="#" class="menu-link">Offer</a>
    </li>
    <li class="menu-item">
      <a href="#" class="menu-link">Contact</a>
    </li>
    <li class="menu-item-ball ball">
      <span class="ball-container">
        <span class="ball-gradient">
          <span class="hidden">
            Ball
          </span>
        </span>
      </span>
    </li>
  </ul>
</nav>
</div>
.hidden {
  border: 0 !important;
  height: 1px !important;
  opacity: 0;
  overflow: hidden;
  padding: 0 !important;
  pointer-events: none;
  position: absolute !important;
  width: 1px !important;
}

.compsoul-menu-ball-body {
  align-items: center;
  background: #2c3333;
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  width: 100%;
}

.compsoul-menu-ball {
  --number-of-items: 4;
  padding: 250px 0;
  width: 80%;
}

.compsoul-menu-ball .menu-container,
.compsoul-menu-ball .menu-item,
.compsoul-menu-ball .menu-link {
  border: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  text-decoration: none;
}

.compsoul-menu-ball .menu-container {
  display: flex;
  flex-flow: row wrap;
  position: relative;
  z-index: 0;
}

.compsoul-menu-ball .menu-container:before {
  background: #fff;
  bottom: 0;
  border-radius: 16px;
  content: "";
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  z-index: -2;
}

.compsoul-menu-ball .menu-item {
  width: calc(100% / var(--number-of-items));
}

.compsoul-menu-ball .menu-link {
  color: #2c3333;
  display: block;
  padding: 24px 0;
  text-align: center;
  width: 100%;
}

.compsoul-menu-ball .menu-item-ball {
  --background-ball: #005aab;
  align-items: center;
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  left: 0;
  position: absolute;
  top: 0;
  transform: translate(0, -100%);
  transition: transform 0.6s;
  width: calc(100% / var(--number-of-items));
}

.compsoul-menu-ball .menu-item:hover + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item-ball {
  --background-ball: #ffe162;
  transform: translate(calc((var(--number-of-items) - 1) * 100%), -100%);
}

.compsoul-menu-ball .menu-item:hover + .menu-item + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item + .menu-item-ball {
  --background-ball: #219f94;
  transform: translate(calc((var(--number-of-items) - 2) * 100%), -100%);
}

.compsoul-menu-ball .menu-item:hover + .menu-item + .menu-item + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item + .menu-item + .menu-item-ball {
  --background-ball: #fc4f4f;
  transform: translate(calc((var(--number-of-items) - 3) * 100%), -100%);
}

.compsoul-menu-ball .menu-item:hover + .menu-item + .menu-item + .menu-item + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item + .menu-item + .menu-item + .menu-item-ball {
  --background-ball: #005aab;
  transform: translate(calc((var(--number-of-items) - 4) * 100%), -100%);
}

.compsoul-menu-ball .menu-item:hover + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item-ball {
  transform: translate(calc((var(--number-of-items) - 5) * 100%), -100%);
}

.compsoul-menu-ball .menu-item:hover + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item + .menu-item + .menu-item  + .menu-item + .menu-item + .menu-item-ball {
  transform: translate(calc((var(--number-of-items) - 6) * 100%), -100%);
}

.compsoul-menu-ball .menu-item:hover + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item + .menu-item + .menu-item + .menu-item  + .menu-item + .menu-item + .menu-item-ball {
  transform: translate(calc((var(--number-of-items) - 7) * 100%), -100%);
}

.compsoul-menu-ball .menu-item:hover + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item-ball,
.compsoul-menu-ball .menu-item:focus-within + .menu-item + .menu-item + .menu-item + .menu-item + .menu-item  + .menu-item + .menu-item + .menu-item-ball {
  transform: translate(calc((var(--number-of-items) - 8) * 100%), -100%);
}

.compsoul-menu-ball .ball-container {
  align-items: center;
  border: 16px solid #2c3333;
  border-radius: 100%;
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  height: 64px;
  margin: 0 0 -16px;
  overflow: hidden;
  position: relative;
  width: 64px;
  z-index: 0;
}

.compsoul-menu-ball .ball-container:before,
.compsoul-menu-ball .ball-container:after{
  background: var(--background-ball);
  bottom: 0;
  content: "";
  left: 0;
  position: absolute;
  right: 0;
  transition: background 0.8s;
  top: 0;
  z-index: -1;
}

.compsoul-menu-ball .ball-container:after{
  background: linear-gradient(#0000001a, #ffffff1a); 
}

.compsoul-menu-ball .ball-gradient {
  background: linear-gradient(#ffffff33, #0000001a, #ffffff33);
  border-radius: 100%;
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  height: 100%;
  width: 90%;
}

.compsoul-menu-ball .ball-gradient:before {
  background: linear-gradient(#fff, #ffffff05);
  border-radius: 100%;
  content: "";
  height: 40%;
  transform: translate(0, 25%);
  width: 60%;
}

Edycja nawigacji odbywa się poprzez dostosowanie zmiennych CSS znajdujących się w kodzie:

  • number-of-items - zmienna odpowiada za ustalenie szerokości poszczególnych elementów. Wykorzystywana jest do obliczania animacji przesunięcia kuli. Zmienna jako wartość przyjmuje liczbę elementów.
  • background-ball - zmienna odpowiedzialna za przypisanie koloru kuli do poszczególnego elementu w menu. Zmienna przyjmuje różne wartości, zależne od pozycji elementu w menu.

Menu zostało zaprojektowane w sposób pozwalający dodanie maksymalnie 8 elementów. Można je jednak rozbudować do dowolnej liczby.