Problem with animation in the Menu

Asked

Viewed 64 times

1

I’m trying to create a simple menu, with an animation that when clicking on the icon the menu options appears, if click on the icons again they disappear.

I only got so far, that the options appear when icon is clicked, but at the end of click the options disappear again

The code is in pure css, because this kind of animation I can’t do in Javascript

HTML code:

<div class="header">
    <i class="fas fa-sliders-h icone" id="icone"></i>
    <div class="nav">
        <li class="li" id="li"><a href="form.html" target="_black" class="link">Form <hr></a></li>
        <li class="li"><a href="#" class="link">Contact<hr></a></li>
        <li class="li"><a href="#" class="link">Article<hr></a></li>
    </div>              
</div>

CSS:

.nav li {opacity: 0;}
.nav{background: transparent; height: 50px; border:1px solid black;}

.icone{position: absolute; display: inline; color:white; font-size: 1.5em; text-align: left; width: 60px;}
.icone:active ~ .nav li{animation:Menu 0.1s; animation-fill-mode: forwards;}

@keyFrames Menu{
    80%{text-align: right;}
    90%{text-align: center;}
    100%{
        opacity: 1;
    }
}
  • Young man, what kind of animation did you want? Looking at your code I couldn’t quite understand what effect you want to get.

3 answers

2

Dude your code had some minor errors in both CSS and HTML. I’ll give you an explanation of your problem, and a way to solve it with CSS and HTML only

In CSS the pseudo class :active is applied only when you do the "press" by clicking on the element, as soon as you release the mouse button the status :active is removed, so you see the animation quickly and then it goes away.

To solve this problem you needed to adjust the HTML, I put its icon inside a label with a for for a checkbox that stays hidden with display:none. When you click on label you change the state of that checkbox hidden to :checked and it opens the menu with the animation, when you click again on label he strip the state :checked of checkbox and the menu goes away. Another thing, now clone the class styles .icone in label just, like label {csss}.

Although I see that you need to make many adjustments of CSS there to be cool, the example itself is not perfect because I didn’t want to mess with the CSS and changed the minimum just to make it work, but you need to study more about the positions, margins and paddings to use them in the most appropriate way

See the code to better understand, I commented in the code where it is for you to have more attention and to see what I changed.

OBS: All LI must be the son of a UL or OL, so I set this up in your HTML, read the documentation on the Ordered and Unordered Lists here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul

.nav ul {
    opacity: 0;
}

.nav {
    background: transparent;
    height: 50px;
    border: 1px solid black;
}

label {
    position: absolute;
    display: inline-block;
    color: gray;
    font-size: 1.5em;
    text-align: left;
    width: 60px;
}

/* agora é quando o btn está com estado :checked que a animação é aplicada */
#btn:checked~.nav ul  {
    animation: Menu 0.1s;
    animation-fill-mode: forwards;
}

@keyFrames Menu {
    80% {
        text-align: right;
    }

    90% {
        text-align: center;
    }

    100% {
        opacity: 1;
    }
}
#btn {
    display: none;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">


<div class="header">
<!-- coloquei o ícone dentro da label, com um for = para o ID do input-checkbox abaixo -->
    <label for="btn"><i class="fas fa-sliders-h icone" id="icone"></i></label>
<!-- quando esse inpute é :checked ele ativa a animação do menu -->
    <input type="checkbox" name="" id="btn">
    <div class="nav">
        <ul>
            <li class="li" id="li">
                <a href="form.html" target="_black" class="link">Form
                    <hr>
                </a>
            </li>
            <li class="li">
                <a href="#" class="link">Contact
                    <hr>
                </a>
            </li>
            <li class="li">
                <a href="#" class="link">Article
                    <hr>
                </a>
            </li>
        </ul>
    </div>
</div>

1


An example only to leave registered using Javascript:

var lis = document.getElementsByClassName("li");

for (var i = 0; i < lis.length; i++) {
  lis[i].style.display = 'none';
}

document.getElementById('icone').addEventListener('click', function() {
  
    setTimeout(function() {
      for (var i = 0; i < lis.length; i++) {
        if (lis[i].style.display == "none") {
          lis[i].style.display = "block";
        } else {
          lis[i].style.display = "none";
        }
      }
    }, 500);
})
.nav {
  background: transparent;
  height: 60px;
  border: 1px solid black;
  text-align: right;
}

.icone {
  position: absolute;
  display: inline;
  color: black;
  font-size: 1.5em;
  text-align: left;
  width: 60px;
  cursor: pointer;
}
<div class="header">
  <i class="fas fa-sliders-h icone" id="icone">Icone</i>
  <div class="nav">
    <li class="li" id="li">
      <a href="#" class="link">Form</a>
    </li>
    <li class="li">
      <a href="#" class="link">Contact</a>
    </li>
    <li class="li">
      <a href="#" class="link">Article</a>
    </li>
  </div>
</div>

  • But I wanted to give a small delay, to run addeventlistener function. With pure javascript it is possible to do?

  • You say give a delay in the animation, click on the icon and take long to appear the lis is this?

  • Exactly that

  • I edited the answer by placing a timeout of 500 ms.

0

It is possible to do this animation with pure Javascript, now there are some problems in your HTML. One of them is the attribute target: instead of _blank you put "_black". Other are the <li> without <ul>, which is semantically incorrect. And instead of using <hr>, I suggest applying a lower edge to menu items. This is because the <hr> is an element that can vary visually in each browser and by the HTML5 specification, should be used to separate subjects, as in a text, for example.

See how it looks:

var el = document.querySelector(".nav ul");
var lis = document.querySelectorAll(".nav a");

// função que anima as <li>
function animaLi(ini, fim, atu){

   atu -= 4;
   var e = atu/100;
   var d = fim-ini;
   d *= e;
   d += ini;

   for(var x=0; x<lis.length; x++){
      lis[x].style.left = d+"%";
      lis[x].style.transform = "translateX(-"+d+"%)";
   }
   
   if(atu > 0){
   
      window.requestAnimationFrame(function(){
         animaLi(ini, fim, atu);
      });
      
   }

}

// função que anima o menu
function anima(ini, fim, atu, dis){

   atu += 4;
   var e = atu/100;
   var d = fim-ini;
   d *= e;
   d += ini;
   el.style.opacity = d;

   if(atu < 100){
   
      window.requestAnimationFrame(function(){
         anima(ini, fim, atu, dis);
      });
      
      if(atu >= 20 && !dis) animaLi(50, 150, 50);
      
   }else{

      if(dis) el.style.display = "none";
      for(var x=0; x<lis.length; x++){
         lis[x].style.left = "100%";
         lis[x].style.transform = "translateX(-100%)";
      }

   }
}

// captura o click no ícone
document.querySelector(".icone").onclick = function(){
   
   if(el.style.display != "block"){
      el.style.display = "block";
      anima(0, 1, 0); // chama a função para mostrar o menu
   }else{
      anima(1, 0, 1, 1); // chama a função para esconder o menu
   }

}
.nav{
   background: transparent;
   height: 50px;
   border: 1px solid black;
}

.nav ul, .nav li{
   margin: 0;
   padding: 0;
   list-style: none;
}

.nav ul{
   opacity: 0;
   display: none;
}

.nav li{
   border-bottom: 1px solid #ddd;
   padding: 10px 0;
}

.nav a{
   position: relative;
   left: 100%;
   display: inline-block;
   transform: translateX(-100%);
}

.icone{
   position: absolute;
   font-size: 1.5em;
   text-align: left;
   width: 60px;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">

<div class="header">
    <i class="fas fa-sliders-h icone" id="icone"></i>
    <div class="nav">
      <ul>
        <li class="li" id="li"><a href="form.html" target="_blank" class="link">Form</a></li>
        <li class="li"><a href="#" class="link">Contact</a></li>
        <li class="li"><a href="#" class="link">Article</a></li><br>
      </ul>
    </div>              
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.