5
respostas

Menu responsivo com sub itens

Boa noite, estou tentando por em prática o que vi no curso. Ao tentar incluir sub-links no menu ele ao ser acionado apresenta os links mas quando tento exibir os sublinks eles não são apresentados na versão abaixo de 800px.

index.html

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta charset="utf-8">
  <link rel="stylesheet" href="/style/reset.css">
  <link rel="stylesheet" href="/style/style.css">
</head>
<body>
  <header>
    <div class="logo">
      MeuSite
    </div>
    <button class="menu-abrir">☰</button>
    <nav>
      <button class="menu-fechar">Fecha Menu</button>
      <ul>
        <li><a href="#">home</a>
        </li>
        <li><a href="#" class="flexDown" tabindex="0">Link1</a>
          <ul>
            <li><a href="#">Link1.1</a></li>
            <li><a href="#">Link1.2</a></li>
            <li><a href="#">Link1.3</a></li>
            <li><a href="#">Link1.4</a></li>
            <li><a href="#">Link1.5</a></li>
            <li><a href="#">Link1.6</a></li>
          </ul>
        </li>
        <li>
          <a href="#">Link2</a>
        </li>
        <li>
          <a href="#">Link3</a>
        </li>
        <li>
          <a href="#">Link4</a>
        </li>
        <li><a href="#" class="danger">Logout</a></li>
      </ul>
    </nav>
  </header>
  <script src="/js/menu.js"></script>

style.css

header{
    width: 100%;
    background-color: #333;
    height: 50px;
    display: flex;
    justify-content: space-between;
}
.admin-logo{
    font-size: 30px;
    color: #FFFFFF;
    font-family: Luckiest Guy;
    padding: 10px 5px 10px 10px;
}
header nav{
    max-width: 95%;
    height: 100%;
    margin-right: 1%;
}
header nav ul{
    display: flex;
    margin: 0;
    padding: 0;
}
header nav ul li{
    padding: 15px 0px 10px 0px;
}

header nav ul li a{
    color: #FFFFFF;
    text-decoration: none;
    padding: 10px 10px 16px 10px;
}
.flexDown:after{
    content: '\23f7';
    }
header nav ul li ul{
    display: block;
    position: absolute;
    margin-top: 18px;
}
header nav ul li ul li{
    background-color: #2980B9;
    display: none;
    width: 100%;
    padding: 0px;
}
header nav ul li ul li a{
    width: 100%;
}
header nav ul li:active ul li,
header nav ul li:hover ul li{
    display: flex;
    border-bottom: 1px ;
}
header nav ul li ul li:hover{
    background-color: #03A9F4;
}

@media (max-width: 1000px){
    header nav ul li ul{
    margin-top: 0px;
}
}
@media not all and (max-width: 800px) {
    .menu-abrir,
    .menu-fechar {
        display: none;
    }
}

@media (max-width: 800px){
    *:focus {
    outline:none;
}
header nav ul{
    list-style:none;
    padding:0;
    margin:0;
    border:1px solid #ccc;
    border-bottom:none;
    display: block;
}
header nav ul li ul {
    display:none;
}
header nav ul li:focus ul{
    display:block;
}
header nav{
      background: #f0f0f0;
      padding: 1em;
      margin: 0;
      height: 100%;
      width: 90%;
      max-width: 320px;
      position: fixed;
      z-index: 1;
      top: 0;
      left: -90%;
      transition: left 0.3s ease-out;
  }
  .menu-ativo header nav {
    left: 0;
    background-color: #333;
  }

  header nav ul li{
      padding: 1em 0;
      width: 100%;
  }
  .menu-ativo:after {
        content: "";
        display: block;
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        background: rgba(0,0,0,0.4);
    }
.menu-abrir,
.menu-fechar {
    background: none;
    border: 0;
    outline: 0;
    -webkit-appearance: none;
    font-size: 1.6em;
    text-indent: -999em;
}
.menu-abrir {
    height: 0;
    width:.75em;
    padding-top:.125em;
    border-top: .375em double #000;
    border-bottom: .125em solid #000;

    vertical-align: middle;
    margin: 0.5em;    
}
.menu-fechar {
    position: relative;
    height: 1em;
    width: 1em;
}
.menu-fechar:before {
    content: '\00D7';
    position: absolute;
    top: 0;
    left: 0;
    text-indent: 0;
    }
}
.danger{
    background-color: #ff002f;
    color: #FFFFFF;
    text-decoration: none;
}
.danger:hover{
    background-color: #FD8D8D;
}

menu.js

document.querySelector('.menu-abrir').onclick = function() {
    document.documentElement.classList.add('menu-ativo');
};

document.querySelector('.menu-fechar').onclick = function() {
    document.documentElement.classList.remove('menu-ativo');
};

document.documentElement.onclick = function(event) {
    if (event.target === document.documentElement) {
        document.documentElement.classList.remove('menu-ativo');
    }
};
5 respostas

Fala ai Marcos, tudo bem? O problema está no seu :hover e :active.

Repare no seu código:

header nav ul li:active ul li,
header nav ul li:hover ul li{
    display: flex;
    border-bottom: 1px ;
}

Você somente está mudando o display do li, mas, o ul pai do li está como none, você também deveria mudar o display do ul.

Tente mudar para:

header nav ul li:active ul, // Adicionei
header nav ul li:active ul li,
header nav ul li:hover ul, // Adicionei
header nav ul li:hover ul li {
    display: flex;
    border-bottom: 1px ;
}

Espero ter ajudado.

obrigado pela ajuda Matheus.

isso resolveu uma parte do problema, os subitens agora são apresentados porém em linha e também sobrepondo os itens inferiores.

substituí o display:flex por display:block e isso resolveu a parte da exibição em linha.

Mas é possível fazer o abrir como uma sanfona quando eu clicar no link1 por exemplo:

Link1
    Link1.1
    Link1.2
link2

Fala ai Marcos, fico feliz que alguns problemas tenham sido resolvidos.

Realmente eu vi que estavam em linhas o sub menu, mas, ai você vai ter que ajustar no CSS.

Para fazer o efeito sanfona, também será necessário um pouco de CSS e JavaScript.

Ao clicar no item você pode adicionar ou remover uma classe da sub lista (assim como faz no responsivo), e essa classe mostrar a sub lista ou não.

Espero ter ajudado.

então, eu nunca estudei nada de JS, esse trecho foi só o que foi explicado no curso, quem sabe no futuro estude algo sobre isso mas por enquanto estou estudando PHP e nas horas vagas um pouco de html css.

Basicamente o que você vai precisar fazer é a mesma coisa, apenas mudando quem recebe os eventos de click e classes.

No caso, poderia buscar o elemento com a classe flexDown e adicionar um listener de click para ele:

document.querySelector('.flexDown').onclick = function() {
    const subList = this.querySelector('ul')
    if (subList) {
        subList..classList.toggle('show', 'show--inline');
    }
};

A ideia seria mais ou menos essa.

Espero ter ajudado.