Problem with animation in the Menu

1

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

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

The code is in pure css, because this type of animation I do not know how to 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;
    }
}
    
asked by anonymous 01.01.2019 / 16:45

3 answers

1

An example to just register 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>
    
01.01.2019 / 17:56
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 resolve it with just CSS and HTML

In CSS the pseudo class :active is applied only when you press the "click" element, as soon as you release the mouse button the status :active is removed, so you see the animation quickly and then she disappeared.

To solve this problem you had to adjust the HTML, I placed its icon inside a label with a for to a checkbox that is hidden with display:none . When you click on label you change the state of this checkbox hidden to :checked and it opens the menu with the animation, when you click on label it takes out the :checked state from the checkbox menu some. Another thing, now cloque the styles of class .icone into label only, type label {csss} .

Although I see that you need to make a lot of CSS adjustments there to be nice, the example itself is not perfect because I did not want to mess around with CSS and I changed the minimum for it to work, but you need to study more about positions , margins and paddings to use them in the most appropriate way

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

OBS: All LI must be the child of a UL or OL , so I've arranged this in your HTML, read the documentation about the Sorted and Unordered Lists here: a href="https://developer.mozilla.org/en/docs/Web/HTML/Element/ul"> link

.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>
    
01.01.2019 / 17:31
0

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

Here's how:

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>
    
01.01.2019 / 23:49