Search code examples
javascriptcsstransition

How do I add transition to styles changed on mouseover and mouseout events


I changed styles on anchor tags and icons I want to add a transition to them and I don't know how.

const listItems = document.querySelectorAll("nav ul li");
const icons = document.querySelectorAll("nav ul li i");
const visitButtons = document.querySelectorAll("nav ul li a.visit--link");

listItems.forEach((item, id) => {
  item.addEventListener("mouseover", function() {
    icons[id].style.display = "none";
    visitButtons[id].style.transform = "translateX(0%)";
    visitButtons[id].style.display = "inline-block";
  });
  item.addEventListener("mouseout", function() {
    icons[id].style.display = "inline-block";
    visitButtons[id].style.transform = "translateX(100%)";
    visitButtons[id].style.display = "none";
  });
});
nav {
  width: 30%;
  border: 1px solid #333;
  border-radius: 5px;
  display: flex;
  flex-direction: column;
}

h2 {
  font-size: 36px;
  text-align: center;
  border-bottom: 1px solid #333;
  justify-content: center;
  margin: 0;
  padding: 15px 30px;
}

nav ul {
  padding: 0;
  margin: 0;
}

nav ul li {
  list-style-type: none;
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: 2s;
}

nav ul li i {
  margin: 0px 5px;
}

nav ul li a {
  text-decoration: none;
  margin: 0;
  color: #000;
}

nav ul li i,
nav ul li a {
  font-size: 36px;
  padding: 15px;
}

nav ul li a.visit--link {
  background-color: #80d6ff;
  color: #fff;
  transform: translateX(100%);
  display: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Sliding Sidebar</title>
  <script src="https://kit.fontawesome.com/02de928ecb.js" crossorigin="anonymous"></script>
</head>

<body>
  <nav>
    <h2>MOST POPULAR CASINOS</h2>
    <ul>
      <li>
        <div>
          <a href="#"><i class="fa-brands fa-fantasy-flight-games"></i>MUCHO VEGAS</a
            >
          </div>
          <a href="#" class="visit--link">VISIT</a>
      </li>
      <li>
        <div>
          <a href="#"><i class="fa-brands fa-fantasy-flight-games"></i>LOKI</a
            >
          </div>
          <a href="#" class="visit--link">VISIT</a>
      </li>
      <li>
        <div>
          <a href="#"><i class="fa-brands fa-fantasy-flight-games"></i>GOLDEN STAR</a
            >
          </div>
          <a href="#" class="visit--link">VISIT</a>
      </li>
      <li>
        <div>
          <a href="#"><i class="fa-brands fa-fantasy-flight-games"></i>BITSTARY</a
            >
          </div>
          <a href="#" class="visit--link">VISIT</a>
      </li>
      <li>
        <div>
          <a href="#"><i class="fa-brands fa-fantasy-flight-games"></i>GUNSBET</a
            >
          </div>
          <a href="#" class="visit--link">VISIT</a>
      </li>
    </ul>
  </nav>
</body>

</html>

I am adding a Visit link at mouseover on list items and hide the icons. On mouseout I'm hiding the link and showing the icons. I thought that just adding transition 1s to anchor tags would add the transition to all styling changes on anchor tags.


Solution

  • Avoid using display: none when you want to transition the element because it will ignore all transitions and animations, instead you can use opacity: 0 and width: 0 or move it outside screen view using transform property:

    const listItems = document.querySelectorAll("nav ul li");
    const icons = document.querySelectorAll("nav ul li i");
    const visitButtons = document.querySelectorAll("nav ul li a.visit--link");
    
    listItems.forEach((item, id) => {
      item.addEventListener("mouseover", function () {
        icons[id].style.transform = "translateX(-100px)"; // to move it outside screen
        icons[id].style.width = 0; // remove width for the text next to it to move in place of it
        visitButtons[id].style.transform = "translateX(0%)";
        visitButtons[id].style.opacity = 1; // fade in
      });
      item.addEventListener("mouseout", function () {
        icons[id].style.transform = "translate(0)"; // return it to it's initial position
        icons[id].style.width = "auto"; // add width back to icon
        visitButtons[id].style.transform = "translateX(100%)";
        visitButtons[id].style.opacity = 0; // unfade, hide
      });
    });
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Sliding Sidebar</title>
        <script
          src="https://kit.fontawesome.com/02de928ecb.js"
          crossorigin="anonymous"
        ></script>
        <style>
          nav {
            width: 40%;
            border: 1px solid #333;
            border-radius: 5px;
            display: flex;
            flex-direction: column; 
            overflow: hidden; /* this is needed for the visit text to not show up outside the nav when entering the screen  */
          }
          h2 {
            font-size: 36px;
            text-align: center;
            border-bottom: 1px solid #333;
            justify-content: center;
            margin: 0;
            padding: 15px 30px;
          }
          nav ul {
            padding: 0;
            margin: 0;
          }
          nav ul li {
            list-style-type: none;
            position: relative;
            display: flex;
            justify-content: space-between;
            align-items: center;
            transition: all 1s;
          }
          nav ul li i {
            margin: 0px 5px;
            transition: all 1s;
          }
          nav ul li a {
            text-decoration: none;
            margin: 0;
            color: #000;
          }
          nav ul li i,
          nav ul li a {
            font-size: 36px;
            padding: 15px;
          }
          nav ul li a.visit--link {
            background-color: #80d6ff;
            color: #fff;
            transform: translateX(100%);
            opacity: 0;
            transition: all 1s;
          }
        </style>
      </head>
      <body>
        <nav>
          <h2>MOST POPULAR CASINOS</h2>
          <ul>
            <li>
              <div>
                <a href="#"
                  ><i class="fa-brands fa-fantasy-flight-games"></i>MUCHO VEGAS</a
                >
              </div>
              <a href="#" class="visit--link">VISIT</a>
            </li>
            <li>
              <div>
                <a href="#"
                  ><i class="fa-brands fa-fantasy-flight-games"></i>LOKI</a
                >
              </div>
              <a href="#" class="visit--link">VISIT</a>
            </li>
            <li>
              <div>
                <a href="#"
                  ><i class="fa-brands fa-fantasy-flight-games"></i>GOLDEN STAR</a
                >
              </div>
              <a href="#" class="visit--link">VISIT</a>
            </li>
            <li>
              <div>
                <a href="#"
                  ><i class="fa-brands fa-fantasy-flight-games"></i>BITSTARY</a
                >
              </div>
              <a href="#" class="visit--link">VISIT</a>
            </li>
            <li>
              <div>
                <a href="#"
                  ><i class="fa-brands fa-fantasy-flight-games"></i>GUNSBET</a
                >
              </div>
              <a href="#" class="visit--link">VISIT</a>
            </li>
          </ul>
        </nav>
    
        <script src="main.js"></script>
      </body>
    </html>