Dropdown com clique
Criei um HTML e CSS de um menu porém não consigo criar o Dropdown com clique, apenas quando passa o mouse o menu recolhe ou expande e eu gostaria de fazer com um clique. Agradeço desde já a ajuda.
*{ margin: 0; paddin: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666;}
#nav li a {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555;}
#nav li a:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul{display: none;}
#nav li:hover ul { display: block; cursor:pointer;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
<ul id="nav">
<li><a href="#">Consultores</a>
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
html css
comentar |
Criei um HTML e CSS de um menu porém não consigo criar o Dropdown com clique, apenas quando passa o mouse o menu recolhe ou expande e eu gostaria de fazer com um clique. Agradeço desde já a ajuda.
*{ margin: 0; paddin: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666;}
#nav li a {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555;}
#nav li a:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul{display: none;}
#nav li:hover ul { display: block; cursor:pointer;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
<ul id="nav">
<li><a href="#">Consultores</a>
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
html css
Está bem difícil de entender. Você consegue editar a pergunta e colocar o seu CSS como código? Adiciona o HTML também.
– DaviAragao
11/03 às 19:31
Você já tentou ao invés de :hover usar um :focus? Acho que funciona ;-)
– Renato Muller Ventura
13/03 às 17:39
comentar |
Criei um HTML e CSS de um menu porém não consigo criar o Dropdown com clique, apenas quando passa o mouse o menu recolhe ou expande e eu gostaria de fazer com um clique. Agradeço desde já a ajuda.
*{ margin: 0; paddin: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666;}
#nav li a {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555;}
#nav li a:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul{display: none;}
#nav li:hover ul { display: block; cursor:pointer;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
<ul id="nav">
<li><a href="#">Consultores</a>
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
html css
Criei um HTML e CSS de um menu porém não consigo criar o Dropdown com clique, apenas quando passa o mouse o menu recolhe ou expande e eu gostaria de fazer com um clique. Agradeço desde já a ajuda.
*{ margin: 0; paddin: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666;}
#nav li a {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555;}
#nav li a:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul{display: none;}
#nav li:hover ul { display: block; cursor:pointer;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
<ul id="nav">
<li><a href="#">Consultores</a>
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
*{ margin: 0; paddin: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666;}
#nav li a {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555;}
#nav li a:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul{display: none;}
#nav li:hover ul { display: block; cursor:pointer;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
<ul id="nav">
<li><a href="#">Consultores</a>
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
*{ margin: 0; paddin: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666;}
#nav li a {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555;}
#nav li a:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul{display: none;}
#nav li:hover ul { display: block; cursor:pointer;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
<ul id="nav">
<li><a href="#">Consultores</a>
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
html css
html css
editada 11/03 às 20:36
Sam
54,5mil123772
54,5mil123772
perguntada 11/03 às 19:19
Victor RVictor R
261
261
Está bem difícil de entender. Você consegue editar a pergunta e colocar o seu CSS como código? Adiciona o HTML também.
– DaviAragao
11/03 às 19:31
Você já tentou ao invés de :hover usar um :focus? Acho que funciona ;-)
– Renato Muller Ventura
13/03 às 17:39
comentar |
Está bem difícil de entender. Você consegue editar a pergunta e colocar o seu CSS como código? Adiciona o HTML também.
– DaviAragao
11/03 às 19:31
Você já tentou ao invés de :hover usar um :focus? Acho que funciona ;-)
– Renato Muller Ventura
13/03 às 17:39
Está bem difícil de entender. Você consegue editar a pergunta e colocar o seu CSS como código? Adiciona o HTML também.
– DaviAragao
11/03 às 19:31
Está bem difícil de entender. Você consegue editar a pergunta e colocar o seu CSS como código? Adiciona o HTML também.
– DaviAragao
11/03 às 19:31
Você já tentou ao invés de :hover usar um :focus? Acho que funciona ;-)
– Renato Muller Ventura
13/03 às 17:39
Você já tentou ao invés de :hover usar um :focus? Acho que funciona ;-)
– Renato Muller Ventura
13/03 às 17:39
comentar |
3 Respostas
3
ativas
mais antigas
votos
Só com CSS você poderia usar um label
com checkbox
(oculto) apenas no botão que abre o submenu, em vez de usar um link <a>
. Ao usar um link <a>
com href="#"
apenas para abrir o submenu, irá alterar a URL adicionando o #
.
Ao clicar no label
irá marcar/desmarcar o checkbox, e você pode usar a pseudo-classe :checked
no checkbox para mostrar/ocultar o submenu. Coloque o input após o label e adicione um id
no checkbox e um for
na label apontando para a id
:
*{ margin: 0; padding: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666; outline: none;}
#nav li a, #nav li label {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555; cursor: pointer;}
#nav li a:hover, #nav li label:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul, #nav li input{display: none;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
#nav li input:checked + ul{
display: block; cursor:pointer;
}
<ul id="nav">
<li>
<label for="sub1">Consultores</label>
<input id="sub1" type="checkbox">
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
Tem um erro de digitação na primeira linha do seu CSS:
paddin
seria
padding
.
Mas essa aplicação é semanticamente incorreta. Além de ir contra as regras semânticas do W3C os leitores de tela lerão esse elemento como uma opção de formulário. A solução aqui deveria ser uma função de JS.
– teefars
12/03 às 18:37
Boa observação. Mas os leitores de tela não ignoram elementos com display: none?
– Sam
12/03 às 18:57
Ignora sim, você tem razão. Mas o label vai ficar aparecendo. E ainda é uma má prática semanticamente. Tem muita gente discutindo o uso semântico disso, mas maioria concorda que é 'gambi'. Dá uma olhada nesse post e nos comentários.
– teefars
12/03 às 19:24
Pq má prática semanticamente? Essa parte eu não entendi.
– Sam
13/03 às 1:26
Imagina que o HTML é a língua portuguesa, você pode falar "Mim não querer", dá pra entender mas tá errado. Aqui é a mesma coisa, todo elemento HTML tem um propósito e deve ser usado para isso. Usar uma palavra ou um tag HTML fora de cotexto é semanticamente errado para seu respectivo idioma. Olabel
define o rótulo de um item de formulário, e só deve ser usado para isso.
– teefars
13/03 às 15:47
|
mostrar mais 3 comentários
Boa tarde, pelo que entendi você não está usando nenhum framework, neste caso de uma olhada nesse código, ele mostra como fazer, basta adaptar no seu código.
$(document).ready(function(){
$('div.dropdown').each(function() {
var $dropdown = $(this);
$("a.dropdown-link", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.dropdown-container", $dropdown);
$div.toggle();
$("div.dropdown-container").not($div).hide();
return false;
});
});
$('html').click(function(){
$("div.dropdown-container").hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="dropdown-1" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-2" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-3" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
Para funcionar será necessário importar jquery na sua aplicação.
só não edito seu código inteiro pq estou sem tempo, mas isso resolve.
Olá Renan, poderia postar uma parte do código aqui ou explicar melhor a resposta? É possível por um código executável na resposta no botão Trecho HTML/CSS/JavaScript ou com o atalho do tecladoCtrl + M
.
– Laércio Lopes
11/03 às 19:54
1
Editei, vê se assim fico melhor.
– Renan
11/03 às 19:55
O ideal seria manter a hierarquia de listas (ul
li
) como estava na pergunta, pois é a forma mais 'correta' em termos de semãntica, boas práticas e acessibilidade. Além disso não é aconselhável inserirstyle
no código e adicionar um listener em todo HTML para sempre ser ativo no clique independente do estado do dropdown, é um processamento desnecessário. Talvez precisasse ter uma função checando se o dropdown está aberto mas até isso iria rodar ao todo clique na tela.
– teefars
12/03 às 20:16
comentar |
A forma mais simples e correta de ter o resultado esperado seria adicionar um javascript (ou jQuery) que ative o li
quando seu link é clicado com uma classe de CSS, e então você controla o efeito visual via CSS (em alguns casos também é feita a animação via JS, mas animações via CSS são aceleradas por hardware e têm um desempenho visual e de processamento muito melhor). É assim que maioria dos frameworks trabalham.
Segue mais ou menos o código (com JS bem fraco).
$(".nav li > span").click(function() {
// confesso que esse código parece pouco otimizado, aceito sugestões
$parent_list_item = $(this).parent("li");
// Remove todas as classes ativas de todos os itens dessa lista, para não ter 2 ativos ao mesmo tempo no mesmo dropdown. Mas ignora o item atual para checarmos depois de precisamos minimizar-lo
$parent_list_item.parent("ul").find(".active").not($parent_list_item).removeClass("active");
// adiciona classe ativa para o <li> (pai) do <a> clicado, se ele não for o item que já está ativo
if (!$parent_list_item.hasClass("active")) {
$parent_list_item.addClass("active");
}else{
// Se for o que já está ativo remove a classe
$parent_list_item.removeClass("active");
}
});
body{
padding:20px;
}
/* apenas para visualização */
.nav{
width:400px;
}
/* reseta as listas em .nav */
.nav, .nav ul{
list-style:none;
margin:0;
padding:0;
}
/* estiliza todos os botões dentro de nav */
.nav a,
.nav span{
display:block;
text-decoration:none;
transition:all .3s ease; /* essa animação é entre a cor de fundo e cor da fonte, sempre muito útil */
}
/* posiciona o item relativo para os subitens (flutuantes) respeitarem sua posição */
.nav li{
position:relative;
}
/* estiliza o primeiro nível */
.nav > li > a,
.nav > li > span{
padding:10px;
background:#eee;
margin-bottom:1px;
color:#333;
}
.nav li > span{
cursor:pointer;
}
.nav li > span:after{
display:inline-block;
content:"+";
font-weight:bold;
font-size:16px;
float:right;
line-height:1em;
}
.nav > li > a:hover,
.nav > li > span:hover{
background:green;
color:white;
}
/* estiliza todos os subitems, ou seja, a lista pode ter vários subdropdowns. Está flutuante pois inseri position:absolute, se você remover o item mostra abaixo;*/
.nav li > ul{
position:absolute; /* comente esta linha para mostrar abaixo*/
top:100%;
z-index:2;
background:#aaa;
max-height:0; /* limita a altura para animarmos (obs este elemento não pode ter padding) */
overflow:hidden;
transition:all 0.5s ease; /* anima os estados do elemento */
/*left: 100%; /* descomente esta linha para mostrar ao lado invés de abaixo */
width:100%; /* deixa o submenu com a largura do pai, depende do caso, ele sobrepõe todos os filhos nesse caso, que não é bom */
margin-left:5px; /* um espaçamento pra ficar visualmente compreensível os níveis */
}
/* 2º nível */
.nav li ul > li > a,
.nav li ul > li > span{
padding:9px;
font-size:0.9em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > a:hover,
.nav li > ul > li > span:hover{
background:tomato;
color:white;
}
/* 3º nível */
.nav li > ul > li > ul > li > a,
.nav li > ul > li > ul > li > span{
padding:7px;
font-size:0.8em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > ul > li > a:hover,
.nav li > ul > li > ul > li > span:hover{
background:limegreen;
color:white;
}
/* estiliza o link dentro do item quando está ativo */
.nav li.active > a,
.nav li.active > span{
background:#333;
color:#fff;
}
.nav li.active > span:after{
content:"-";
}
.nav li.active > ul{
max-height:100vh; /* remove a limitação de altura para animar para height:auto.*/
animation:0s 1s delay-overflow forwards; /* pequeno hack para o overflow mudar apenas para o item aberto depois da animação terminada */
}
@keyframes delay-overflow {
to { overflow:visible; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li><span>Consultores</span>
<ul>
<li><a href="#0">sub - 1</a></li>
<li><a href="#0">sub - 2</a></li>
<li><span>sub - 3 (com subs)</span> <!-- como aqui é um botão simples de ordenação, ele não deve ser um link -->
<ul>
<li><a href="#0">sub sub - 1</a></li>
<li><a href="#0">sub sub - 2</a></li>
<li><a href="#0">sub sub - 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#0">Colaboradores</a></li>
<li><a href="#0">Comercial</a></li>
<li><a href="#0">RH</a></li>
</ul>
Eu acho estranho como o stackoverflow insere o código direto na página, então sempre uso alternativas como o CodePen, clique aqui para ver essa solução.
Outras observações sobre seu código:
- Tente não usar
ID
s em elementos que podem ser genéricos / modularizados / componentizados ou repetíveis na página, tente tratar o ID apenas para seleções JS específicas. Ex: a página pode ter vários dropdowns, então o componente é genérico.
Espero ter ajudado (apesar desse JS ainda me incomodar rs)
comentar |
Sua resposta
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "526"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Desenvolvido por u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Registre-se ou faça log-in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Registre-se usando o Google
Registre-se usando o Facebook
Registre-se usando Email e Senha
Publicar como convidado
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fpt.stackoverflow.com%2fquestions%2f367600%2fdropdown-com-clique%23new-answer', 'question_page');
}
);
Publicar como convidado
Required, but never shown
3 Respostas
3
ativas
mais antigas
votos
3 Respostas
3
ativas
mais antigas
votos
ativas
mais antigas
votos
ativas
mais antigas
votos
Só com CSS você poderia usar um label
com checkbox
(oculto) apenas no botão que abre o submenu, em vez de usar um link <a>
. Ao usar um link <a>
com href="#"
apenas para abrir o submenu, irá alterar a URL adicionando o #
.
Ao clicar no label
irá marcar/desmarcar o checkbox, e você pode usar a pseudo-classe :checked
no checkbox para mostrar/ocultar o submenu. Coloque o input após o label e adicione um id
no checkbox e um for
na label apontando para a id
:
*{ margin: 0; padding: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666; outline: none;}
#nav li a, #nav li label {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555; cursor: pointer;}
#nav li a:hover, #nav li label:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul, #nav li input{display: none;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
#nav li input:checked + ul{
display: block; cursor:pointer;
}
<ul id="nav">
<li>
<label for="sub1">Consultores</label>
<input id="sub1" type="checkbox">
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
Tem um erro de digitação na primeira linha do seu CSS:
paddin
seria
padding
.
Mas essa aplicação é semanticamente incorreta. Além de ir contra as regras semânticas do W3C os leitores de tela lerão esse elemento como uma opção de formulário. A solução aqui deveria ser uma função de JS.
– teefars
12/03 às 18:37
Boa observação. Mas os leitores de tela não ignoram elementos com display: none?
– Sam
12/03 às 18:57
Ignora sim, você tem razão. Mas o label vai ficar aparecendo. E ainda é uma má prática semanticamente. Tem muita gente discutindo o uso semântico disso, mas maioria concorda que é 'gambi'. Dá uma olhada nesse post e nos comentários.
– teefars
12/03 às 19:24
Pq má prática semanticamente? Essa parte eu não entendi.
– Sam
13/03 às 1:26
Imagina que o HTML é a língua portuguesa, você pode falar "Mim não querer", dá pra entender mas tá errado. Aqui é a mesma coisa, todo elemento HTML tem um propósito e deve ser usado para isso. Usar uma palavra ou um tag HTML fora de cotexto é semanticamente errado para seu respectivo idioma. Olabel
define o rótulo de um item de formulário, e só deve ser usado para isso.
– teefars
13/03 às 15:47
|
mostrar mais 3 comentários
Só com CSS você poderia usar um label
com checkbox
(oculto) apenas no botão que abre o submenu, em vez de usar um link <a>
. Ao usar um link <a>
com href="#"
apenas para abrir o submenu, irá alterar a URL adicionando o #
.
Ao clicar no label
irá marcar/desmarcar o checkbox, e você pode usar a pseudo-classe :checked
no checkbox para mostrar/ocultar o submenu. Coloque o input após o label e adicione um id
no checkbox e um for
na label apontando para a id
:
*{ margin: 0; padding: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666; outline: none;}
#nav li a, #nav li label {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555; cursor: pointer;}
#nav li a:hover, #nav li label:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul, #nav li input{display: none;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
#nav li input:checked + ul{
display: block; cursor:pointer;
}
<ul id="nav">
<li>
<label for="sub1">Consultores</label>
<input id="sub1" type="checkbox">
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
Tem um erro de digitação na primeira linha do seu CSS:
paddin
seria
padding
.
Mas essa aplicação é semanticamente incorreta. Além de ir contra as regras semânticas do W3C os leitores de tela lerão esse elemento como uma opção de formulário. A solução aqui deveria ser uma função de JS.
– teefars
12/03 às 18:37
Boa observação. Mas os leitores de tela não ignoram elementos com display: none?
– Sam
12/03 às 18:57
Ignora sim, você tem razão. Mas o label vai ficar aparecendo. E ainda é uma má prática semanticamente. Tem muita gente discutindo o uso semântico disso, mas maioria concorda que é 'gambi'. Dá uma olhada nesse post e nos comentários.
– teefars
12/03 às 19:24
Pq má prática semanticamente? Essa parte eu não entendi.
– Sam
13/03 às 1:26
Imagina que o HTML é a língua portuguesa, você pode falar "Mim não querer", dá pra entender mas tá errado. Aqui é a mesma coisa, todo elemento HTML tem um propósito e deve ser usado para isso. Usar uma palavra ou um tag HTML fora de cotexto é semanticamente errado para seu respectivo idioma. Olabel
define o rótulo de um item de formulário, e só deve ser usado para isso.
– teefars
13/03 às 15:47
|
mostrar mais 3 comentários
Só com CSS você poderia usar um label
com checkbox
(oculto) apenas no botão que abre o submenu, em vez de usar um link <a>
. Ao usar um link <a>
com href="#"
apenas para abrir o submenu, irá alterar a URL adicionando o #
.
Ao clicar no label
irá marcar/desmarcar o checkbox, e você pode usar a pseudo-classe :checked
no checkbox para mostrar/ocultar o submenu. Coloque o input após o label e adicione um id
no checkbox e um for
na label apontando para a id
:
*{ margin: 0; padding: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666; outline: none;}
#nav li a, #nav li label {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555; cursor: pointer;}
#nav li a:hover, #nav li label:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul, #nav li input{display: none;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
#nav li input:checked + ul{
display: block; cursor:pointer;
}
<ul id="nav">
<li>
<label for="sub1">Consultores</label>
<input id="sub1" type="checkbox">
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
Tem um erro de digitação na primeira linha do seu CSS:
paddin
seria
padding
.
Só com CSS você poderia usar um label
com checkbox
(oculto) apenas no botão que abre o submenu, em vez de usar um link <a>
. Ao usar um link <a>
com href="#"
apenas para abrir o submenu, irá alterar a URL adicionando o #
.
Ao clicar no label
irá marcar/desmarcar o checkbox, e você pode usar a pseudo-classe :checked
no checkbox para mostrar/ocultar o submenu. Coloque o input após o label e adicione um id
no checkbox e um for
na label apontando para a id
:
*{ margin: 0; padding: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666; outline: none;}
#nav li a, #nav li label {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555; cursor: pointer;}
#nav li a:hover, #nav li label:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul, #nav li input{display: none;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
#nav li input:checked + ul{
display: block; cursor:pointer;
}
<ul id="nav">
<li>
<label for="sub1">Consultores</label>
<input id="sub1" type="checkbox">
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
Tem um erro de digitação na primeira linha do seu CSS:
paddin
seria
padding
.
*{ margin: 0; padding: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666; outline: none;}
#nav li a, #nav li label {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555; cursor: pointer;}
#nav li a:hover, #nav li label:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul, #nav li input{display: none;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
#nav li input:checked + ul{
display: block; cursor:pointer;
}
<ul id="nav">
<li>
<label for="sub1">Consultores</label>
<input id="sub1" type="checkbox">
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
*{ margin: 0; padding: 0;}
body {background: ffffff; margin: 5px; }
#nav {margin: 0; padding: 0; }
#nav li {list-style: none; background: #fff; width: 250 px; border-bottom: 1px solid #666; outline: none;}
#nav li a, #nav li label {display: block; padding: 8px; border-left: 4px solid #444; text-decoration: none; box-shadow: 2px 2px 5px #ccc; color: #555; cursor: pointer;}
#nav li a:hover, #nav li label:hover {border-left:4px solid #069; background: #f8f8f8;}
#nav li ul, #nav li input{display: none;}
#nav li:hover ul li{background: #333;}
#nav li:hover ul li a {color:ccc;}
#nav li:hover ul li a:hover{background: #222; border-left:4px solid #900;}
#nav li input:checked + ul{
display: block; cursor:pointer;
}
<ul id="nav">
<li>
<label for="sub1">Consultores</label>
<input id="sub1" type="checkbox">
<ul>
<li><a href="#">sub - 1</a></li>
<li><a href="#">sub - 2</a></li>
<li><a href="#">sub - 3</a></li>
</ul>
</li>
<li><a href="#">Colaboradores</a></li>
<li><a href="#">Comercial</a></li>
<li><a href="#">RH</a></li>
</ul>
respondida 11/03 às 20:28
SamSam
54,5mil123772
54,5mil123772
Mas essa aplicação é semanticamente incorreta. Além de ir contra as regras semânticas do W3C os leitores de tela lerão esse elemento como uma opção de formulário. A solução aqui deveria ser uma função de JS.
– teefars
12/03 às 18:37
Boa observação. Mas os leitores de tela não ignoram elementos com display: none?
– Sam
12/03 às 18:57
Ignora sim, você tem razão. Mas o label vai ficar aparecendo. E ainda é uma má prática semanticamente. Tem muita gente discutindo o uso semântico disso, mas maioria concorda que é 'gambi'. Dá uma olhada nesse post e nos comentários.
– teefars
12/03 às 19:24
Pq má prática semanticamente? Essa parte eu não entendi.
– Sam
13/03 às 1:26
Imagina que o HTML é a língua portuguesa, você pode falar "Mim não querer", dá pra entender mas tá errado. Aqui é a mesma coisa, todo elemento HTML tem um propósito e deve ser usado para isso. Usar uma palavra ou um tag HTML fora de cotexto é semanticamente errado para seu respectivo idioma. Olabel
define o rótulo de um item de formulário, e só deve ser usado para isso.
– teefars
13/03 às 15:47
|
mostrar mais 3 comentários
Mas essa aplicação é semanticamente incorreta. Além de ir contra as regras semânticas do W3C os leitores de tela lerão esse elemento como uma opção de formulário. A solução aqui deveria ser uma função de JS.
– teefars
12/03 às 18:37
Boa observação. Mas os leitores de tela não ignoram elementos com display: none?
– Sam
12/03 às 18:57
Ignora sim, você tem razão. Mas o label vai ficar aparecendo. E ainda é uma má prática semanticamente. Tem muita gente discutindo o uso semântico disso, mas maioria concorda que é 'gambi'. Dá uma olhada nesse post e nos comentários.
– teefars
12/03 às 19:24
Pq má prática semanticamente? Essa parte eu não entendi.
– Sam
13/03 às 1:26
Imagina que o HTML é a língua portuguesa, você pode falar "Mim não querer", dá pra entender mas tá errado. Aqui é a mesma coisa, todo elemento HTML tem um propósito e deve ser usado para isso. Usar uma palavra ou um tag HTML fora de cotexto é semanticamente errado para seu respectivo idioma. Olabel
define o rótulo de um item de formulário, e só deve ser usado para isso.
– teefars
13/03 às 15:47
Mas essa aplicação é semanticamente incorreta. Além de ir contra as regras semânticas do W3C os leitores de tela lerão esse elemento como uma opção de formulário. A solução aqui deveria ser uma função de JS.
– teefars
12/03 às 18:37
Mas essa aplicação é semanticamente incorreta. Além de ir contra as regras semânticas do W3C os leitores de tela lerão esse elemento como uma opção de formulário. A solução aqui deveria ser uma função de JS.
– teefars
12/03 às 18:37
Boa observação. Mas os leitores de tela não ignoram elementos com display: none?
– Sam
12/03 às 18:57
Boa observação. Mas os leitores de tela não ignoram elementos com display: none?
– Sam
12/03 às 18:57
Ignora sim, você tem razão. Mas o label vai ficar aparecendo. E ainda é uma má prática semanticamente. Tem muita gente discutindo o uso semântico disso, mas maioria concorda que é 'gambi'. Dá uma olhada nesse post e nos comentários.
– teefars
12/03 às 19:24
Ignora sim, você tem razão. Mas o label vai ficar aparecendo. E ainda é uma má prática semanticamente. Tem muita gente discutindo o uso semântico disso, mas maioria concorda que é 'gambi'. Dá uma olhada nesse post e nos comentários.
– teefars
12/03 às 19:24
Pq má prática semanticamente? Essa parte eu não entendi.
– Sam
13/03 às 1:26
Pq má prática semanticamente? Essa parte eu não entendi.
– Sam
13/03 às 1:26
Imagina que o HTML é a língua portuguesa, você pode falar "Mim não querer", dá pra entender mas tá errado. Aqui é a mesma coisa, todo elemento HTML tem um propósito e deve ser usado para isso. Usar uma palavra ou um tag HTML fora de cotexto é semanticamente errado para seu respectivo idioma. O
label
define o rótulo de um item de formulário, e só deve ser usado para isso.– teefars
13/03 às 15:47
Imagina que o HTML é a língua portuguesa, você pode falar "Mim não querer", dá pra entender mas tá errado. Aqui é a mesma coisa, todo elemento HTML tem um propósito e deve ser usado para isso. Usar uma palavra ou um tag HTML fora de cotexto é semanticamente errado para seu respectivo idioma. O
label
define o rótulo de um item de formulário, e só deve ser usado para isso.– teefars
13/03 às 15:47
|
mostrar mais 3 comentários
Boa tarde, pelo que entendi você não está usando nenhum framework, neste caso de uma olhada nesse código, ele mostra como fazer, basta adaptar no seu código.
$(document).ready(function(){
$('div.dropdown').each(function() {
var $dropdown = $(this);
$("a.dropdown-link", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.dropdown-container", $dropdown);
$div.toggle();
$("div.dropdown-container").not($div).hide();
return false;
});
});
$('html').click(function(){
$("div.dropdown-container").hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="dropdown-1" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-2" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-3" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
Para funcionar será necessário importar jquery na sua aplicação.
só não edito seu código inteiro pq estou sem tempo, mas isso resolve.
Olá Renan, poderia postar uma parte do código aqui ou explicar melhor a resposta? É possível por um código executável na resposta no botão Trecho HTML/CSS/JavaScript ou com o atalho do tecladoCtrl + M
.
– Laércio Lopes
11/03 às 19:54
1
Editei, vê se assim fico melhor.
– Renan
11/03 às 19:55
O ideal seria manter a hierarquia de listas (ul
li
) como estava na pergunta, pois é a forma mais 'correta' em termos de semãntica, boas práticas e acessibilidade. Além disso não é aconselhável inserirstyle
no código e adicionar um listener em todo HTML para sempre ser ativo no clique independente do estado do dropdown, é um processamento desnecessário. Talvez precisasse ter uma função checando se o dropdown está aberto mas até isso iria rodar ao todo clique na tela.
– teefars
12/03 às 20:16
comentar |
Boa tarde, pelo que entendi você não está usando nenhum framework, neste caso de uma olhada nesse código, ele mostra como fazer, basta adaptar no seu código.
$(document).ready(function(){
$('div.dropdown').each(function() {
var $dropdown = $(this);
$("a.dropdown-link", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.dropdown-container", $dropdown);
$div.toggle();
$("div.dropdown-container").not($div).hide();
return false;
});
});
$('html').click(function(){
$("div.dropdown-container").hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="dropdown-1" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-2" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-3" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
Para funcionar será necessário importar jquery na sua aplicação.
só não edito seu código inteiro pq estou sem tempo, mas isso resolve.
Olá Renan, poderia postar uma parte do código aqui ou explicar melhor a resposta? É possível por um código executável na resposta no botão Trecho HTML/CSS/JavaScript ou com o atalho do tecladoCtrl + M
.
– Laércio Lopes
11/03 às 19:54
1
Editei, vê se assim fico melhor.
– Renan
11/03 às 19:55
O ideal seria manter a hierarquia de listas (ul
li
) como estava na pergunta, pois é a forma mais 'correta' em termos de semãntica, boas práticas e acessibilidade. Além disso não é aconselhável inserirstyle
no código e adicionar um listener em todo HTML para sempre ser ativo no clique independente do estado do dropdown, é um processamento desnecessário. Talvez precisasse ter uma função checando se o dropdown está aberto mas até isso iria rodar ao todo clique na tela.
– teefars
12/03 às 20:16
comentar |
Boa tarde, pelo que entendi você não está usando nenhum framework, neste caso de uma olhada nesse código, ele mostra como fazer, basta adaptar no seu código.
$(document).ready(function(){
$('div.dropdown').each(function() {
var $dropdown = $(this);
$("a.dropdown-link", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.dropdown-container", $dropdown);
$div.toggle();
$("div.dropdown-container").not($div).hide();
return false;
});
});
$('html').click(function(){
$("div.dropdown-container").hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="dropdown-1" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-2" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-3" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
Para funcionar será necessário importar jquery na sua aplicação.
só não edito seu código inteiro pq estou sem tempo, mas isso resolve.
Boa tarde, pelo que entendi você não está usando nenhum framework, neste caso de uma olhada nesse código, ele mostra como fazer, basta adaptar no seu código.
$(document).ready(function(){
$('div.dropdown').each(function() {
var $dropdown = $(this);
$("a.dropdown-link", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.dropdown-container", $dropdown);
$div.toggle();
$("div.dropdown-container").not($div).hide();
return false;
});
});
$('html').click(function(){
$("div.dropdown-container").hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="dropdown-1" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-2" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-3" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
Para funcionar será necessário importar jquery na sua aplicação.
só não edito seu código inteiro pq estou sem tempo, mas isso resolve.
$(document).ready(function(){
$('div.dropdown').each(function() {
var $dropdown = $(this);
$("a.dropdown-link", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.dropdown-container", $dropdown);
$div.toggle();
$("div.dropdown-container").not($div).hide();
return false;
});
});
$('html').click(function(){
$("div.dropdown-container").hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="dropdown-1" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-2" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-3" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
$(document).ready(function(){
$('div.dropdown').each(function() {
var $dropdown = $(this);
$("a.dropdown-link", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.dropdown-container", $dropdown);
$div.toggle();
$("div.dropdown-container").not($div).hide();
return false;
});
});
$('html').click(function(){
$("div.dropdown-container").hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="dropdown-1" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-2" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
<div id="dropdown-3" class="dropdown dropdown-processed">
<a class="dropdown-link" href="#">Options</a>
<div class="dropdown-container" style="display: none;">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
editada 11/03 às 19:54
respondida 11/03 às 19:47
RenanRenan
45615
45615
Olá Renan, poderia postar uma parte do código aqui ou explicar melhor a resposta? É possível por um código executável na resposta no botão Trecho HTML/CSS/JavaScript ou com o atalho do tecladoCtrl + M
.
– Laércio Lopes
11/03 às 19:54
1
Editei, vê se assim fico melhor.
– Renan
11/03 às 19:55
O ideal seria manter a hierarquia de listas (ul
li
) como estava na pergunta, pois é a forma mais 'correta' em termos de semãntica, boas práticas e acessibilidade. Além disso não é aconselhável inserirstyle
no código e adicionar um listener em todo HTML para sempre ser ativo no clique independente do estado do dropdown, é um processamento desnecessário. Talvez precisasse ter uma função checando se o dropdown está aberto mas até isso iria rodar ao todo clique na tela.
– teefars
12/03 às 20:16
comentar |
Olá Renan, poderia postar uma parte do código aqui ou explicar melhor a resposta? É possível por um código executável na resposta no botão Trecho HTML/CSS/JavaScript ou com o atalho do tecladoCtrl + M
.
– Laércio Lopes
11/03 às 19:54
1
Editei, vê se assim fico melhor.
– Renan
11/03 às 19:55
O ideal seria manter a hierarquia de listas (ul
li
) como estava na pergunta, pois é a forma mais 'correta' em termos de semãntica, boas práticas e acessibilidade. Além disso não é aconselhável inserirstyle
no código e adicionar um listener em todo HTML para sempre ser ativo no clique independente do estado do dropdown, é um processamento desnecessário. Talvez precisasse ter uma função checando se o dropdown está aberto mas até isso iria rodar ao todo clique na tela.
– teefars
12/03 às 20:16
Olá Renan, poderia postar uma parte do código aqui ou explicar melhor a resposta? É possível por um código executável na resposta no botão Trecho HTML/CSS/JavaScript ou com o atalho do teclado
Ctrl + M
.– Laércio Lopes
11/03 às 19:54
Olá Renan, poderia postar uma parte do código aqui ou explicar melhor a resposta? É possível por um código executável na resposta no botão Trecho HTML/CSS/JavaScript ou com o atalho do teclado
Ctrl + M
.– Laércio Lopes
11/03 às 19:54
1
1
Editei, vê se assim fico melhor.
– Renan
11/03 às 19:55
Editei, vê se assim fico melhor.
– Renan
11/03 às 19:55
O ideal seria manter a hierarquia de listas (
ul
li
) como estava na pergunta, pois é a forma mais 'correta' em termos de semãntica, boas práticas e acessibilidade. Além disso não é aconselhável inserir style
no código e adicionar um listener em todo HTML para sempre ser ativo no clique independente do estado do dropdown, é um processamento desnecessário. Talvez precisasse ter uma função checando se o dropdown está aberto mas até isso iria rodar ao todo clique na tela.– teefars
12/03 às 20:16
O ideal seria manter a hierarquia de listas (
ul
li
) como estava na pergunta, pois é a forma mais 'correta' em termos de semãntica, boas práticas e acessibilidade. Além disso não é aconselhável inserir style
no código e adicionar um listener em todo HTML para sempre ser ativo no clique independente do estado do dropdown, é um processamento desnecessário. Talvez precisasse ter uma função checando se o dropdown está aberto mas até isso iria rodar ao todo clique na tela.– teefars
12/03 às 20:16
comentar |
A forma mais simples e correta de ter o resultado esperado seria adicionar um javascript (ou jQuery) que ative o li
quando seu link é clicado com uma classe de CSS, e então você controla o efeito visual via CSS (em alguns casos também é feita a animação via JS, mas animações via CSS são aceleradas por hardware e têm um desempenho visual e de processamento muito melhor). É assim que maioria dos frameworks trabalham.
Segue mais ou menos o código (com JS bem fraco).
$(".nav li > span").click(function() {
// confesso que esse código parece pouco otimizado, aceito sugestões
$parent_list_item = $(this).parent("li");
// Remove todas as classes ativas de todos os itens dessa lista, para não ter 2 ativos ao mesmo tempo no mesmo dropdown. Mas ignora o item atual para checarmos depois de precisamos minimizar-lo
$parent_list_item.parent("ul").find(".active").not($parent_list_item).removeClass("active");
// adiciona classe ativa para o <li> (pai) do <a> clicado, se ele não for o item que já está ativo
if (!$parent_list_item.hasClass("active")) {
$parent_list_item.addClass("active");
}else{
// Se for o que já está ativo remove a classe
$parent_list_item.removeClass("active");
}
});
body{
padding:20px;
}
/* apenas para visualização */
.nav{
width:400px;
}
/* reseta as listas em .nav */
.nav, .nav ul{
list-style:none;
margin:0;
padding:0;
}
/* estiliza todos os botões dentro de nav */
.nav a,
.nav span{
display:block;
text-decoration:none;
transition:all .3s ease; /* essa animação é entre a cor de fundo e cor da fonte, sempre muito útil */
}
/* posiciona o item relativo para os subitens (flutuantes) respeitarem sua posição */
.nav li{
position:relative;
}
/* estiliza o primeiro nível */
.nav > li > a,
.nav > li > span{
padding:10px;
background:#eee;
margin-bottom:1px;
color:#333;
}
.nav li > span{
cursor:pointer;
}
.nav li > span:after{
display:inline-block;
content:"+";
font-weight:bold;
font-size:16px;
float:right;
line-height:1em;
}
.nav > li > a:hover,
.nav > li > span:hover{
background:green;
color:white;
}
/* estiliza todos os subitems, ou seja, a lista pode ter vários subdropdowns. Está flutuante pois inseri position:absolute, se você remover o item mostra abaixo;*/
.nav li > ul{
position:absolute; /* comente esta linha para mostrar abaixo*/
top:100%;
z-index:2;
background:#aaa;
max-height:0; /* limita a altura para animarmos (obs este elemento não pode ter padding) */
overflow:hidden;
transition:all 0.5s ease; /* anima os estados do elemento */
/*left: 100%; /* descomente esta linha para mostrar ao lado invés de abaixo */
width:100%; /* deixa o submenu com a largura do pai, depende do caso, ele sobrepõe todos os filhos nesse caso, que não é bom */
margin-left:5px; /* um espaçamento pra ficar visualmente compreensível os níveis */
}
/* 2º nível */
.nav li ul > li > a,
.nav li ul > li > span{
padding:9px;
font-size:0.9em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > a:hover,
.nav li > ul > li > span:hover{
background:tomato;
color:white;
}
/* 3º nível */
.nav li > ul > li > ul > li > a,
.nav li > ul > li > ul > li > span{
padding:7px;
font-size:0.8em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > ul > li > a:hover,
.nav li > ul > li > ul > li > span:hover{
background:limegreen;
color:white;
}
/* estiliza o link dentro do item quando está ativo */
.nav li.active > a,
.nav li.active > span{
background:#333;
color:#fff;
}
.nav li.active > span:after{
content:"-";
}
.nav li.active > ul{
max-height:100vh; /* remove a limitação de altura para animar para height:auto.*/
animation:0s 1s delay-overflow forwards; /* pequeno hack para o overflow mudar apenas para o item aberto depois da animação terminada */
}
@keyframes delay-overflow {
to { overflow:visible; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li><span>Consultores</span>
<ul>
<li><a href="#0">sub - 1</a></li>
<li><a href="#0">sub - 2</a></li>
<li><span>sub - 3 (com subs)</span> <!-- como aqui é um botão simples de ordenação, ele não deve ser um link -->
<ul>
<li><a href="#0">sub sub - 1</a></li>
<li><a href="#0">sub sub - 2</a></li>
<li><a href="#0">sub sub - 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#0">Colaboradores</a></li>
<li><a href="#0">Comercial</a></li>
<li><a href="#0">RH</a></li>
</ul>
Eu acho estranho como o stackoverflow insere o código direto na página, então sempre uso alternativas como o CodePen, clique aqui para ver essa solução.
Outras observações sobre seu código:
- Tente não usar
ID
s em elementos que podem ser genéricos / modularizados / componentizados ou repetíveis na página, tente tratar o ID apenas para seleções JS específicas. Ex: a página pode ter vários dropdowns, então o componente é genérico.
Espero ter ajudado (apesar desse JS ainda me incomodar rs)
comentar |
A forma mais simples e correta de ter o resultado esperado seria adicionar um javascript (ou jQuery) que ative o li
quando seu link é clicado com uma classe de CSS, e então você controla o efeito visual via CSS (em alguns casos também é feita a animação via JS, mas animações via CSS são aceleradas por hardware e têm um desempenho visual e de processamento muito melhor). É assim que maioria dos frameworks trabalham.
Segue mais ou menos o código (com JS bem fraco).
$(".nav li > span").click(function() {
// confesso que esse código parece pouco otimizado, aceito sugestões
$parent_list_item = $(this).parent("li");
// Remove todas as classes ativas de todos os itens dessa lista, para não ter 2 ativos ao mesmo tempo no mesmo dropdown. Mas ignora o item atual para checarmos depois de precisamos minimizar-lo
$parent_list_item.parent("ul").find(".active").not($parent_list_item).removeClass("active");
// adiciona classe ativa para o <li> (pai) do <a> clicado, se ele não for o item que já está ativo
if (!$parent_list_item.hasClass("active")) {
$parent_list_item.addClass("active");
}else{
// Se for o que já está ativo remove a classe
$parent_list_item.removeClass("active");
}
});
body{
padding:20px;
}
/* apenas para visualização */
.nav{
width:400px;
}
/* reseta as listas em .nav */
.nav, .nav ul{
list-style:none;
margin:0;
padding:0;
}
/* estiliza todos os botões dentro de nav */
.nav a,
.nav span{
display:block;
text-decoration:none;
transition:all .3s ease; /* essa animação é entre a cor de fundo e cor da fonte, sempre muito útil */
}
/* posiciona o item relativo para os subitens (flutuantes) respeitarem sua posição */
.nav li{
position:relative;
}
/* estiliza o primeiro nível */
.nav > li > a,
.nav > li > span{
padding:10px;
background:#eee;
margin-bottom:1px;
color:#333;
}
.nav li > span{
cursor:pointer;
}
.nav li > span:after{
display:inline-block;
content:"+";
font-weight:bold;
font-size:16px;
float:right;
line-height:1em;
}
.nav > li > a:hover,
.nav > li > span:hover{
background:green;
color:white;
}
/* estiliza todos os subitems, ou seja, a lista pode ter vários subdropdowns. Está flutuante pois inseri position:absolute, se você remover o item mostra abaixo;*/
.nav li > ul{
position:absolute; /* comente esta linha para mostrar abaixo*/
top:100%;
z-index:2;
background:#aaa;
max-height:0; /* limita a altura para animarmos (obs este elemento não pode ter padding) */
overflow:hidden;
transition:all 0.5s ease; /* anima os estados do elemento */
/*left: 100%; /* descomente esta linha para mostrar ao lado invés de abaixo */
width:100%; /* deixa o submenu com a largura do pai, depende do caso, ele sobrepõe todos os filhos nesse caso, que não é bom */
margin-left:5px; /* um espaçamento pra ficar visualmente compreensível os níveis */
}
/* 2º nível */
.nav li ul > li > a,
.nav li ul > li > span{
padding:9px;
font-size:0.9em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > a:hover,
.nav li > ul > li > span:hover{
background:tomato;
color:white;
}
/* 3º nível */
.nav li > ul > li > ul > li > a,
.nav li > ul > li > ul > li > span{
padding:7px;
font-size:0.8em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > ul > li > a:hover,
.nav li > ul > li > ul > li > span:hover{
background:limegreen;
color:white;
}
/* estiliza o link dentro do item quando está ativo */
.nav li.active > a,
.nav li.active > span{
background:#333;
color:#fff;
}
.nav li.active > span:after{
content:"-";
}
.nav li.active > ul{
max-height:100vh; /* remove a limitação de altura para animar para height:auto.*/
animation:0s 1s delay-overflow forwards; /* pequeno hack para o overflow mudar apenas para o item aberto depois da animação terminada */
}
@keyframes delay-overflow {
to { overflow:visible; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li><span>Consultores</span>
<ul>
<li><a href="#0">sub - 1</a></li>
<li><a href="#0">sub - 2</a></li>
<li><span>sub - 3 (com subs)</span> <!-- como aqui é um botão simples de ordenação, ele não deve ser um link -->
<ul>
<li><a href="#0">sub sub - 1</a></li>
<li><a href="#0">sub sub - 2</a></li>
<li><a href="#0">sub sub - 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#0">Colaboradores</a></li>
<li><a href="#0">Comercial</a></li>
<li><a href="#0">RH</a></li>
</ul>
Eu acho estranho como o stackoverflow insere o código direto na página, então sempre uso alternativas como o CodePen, clique aqui para ver essa solução.
Outras observações sobre seu código:
- Tente não usar
ID
s em elementos que podem ser genéricos / modularizados / componentizados ou repetíveis na página, tente tratar o ID apenas para seleções JS específicas. Ex: a página pode ter vários dropdowns, então o componente é genérico.
Espero ter ajudado (apesar desse JS ainda me incomodar rs)
comentar |
A forma mais simples e correta de ter o resultado esperado seria adicionar um javascript (ou jQuery) que ative o li
quando seu link é clicado com uma classe de CSS, e então você controla o efeito visual via CSS (em alguns casos também é feita a animação via JS, mas animações via CSS são aceleradas por hardware e têm um desempenho visual e de processamento muito melhor). É assim que maioria dos frameworks trabalham.
Segue mais ou menos o código (com JS bem fraco).
$(".nav li > span").click(function() {
// confesso que esse código parece pouco otimizado, aceito sugestões
$parent_list_item = $(this).parent("li");
// Remove todas as classes ativas de todos os itens dessa lista, para não ter 2 ativos ao mesmo tempo no mesmo dropdown. Mas ignora o item atual para checarmos depois de precisamos minimizar-lo
$parent_list_item.parent("ul").find(".active").not($parent_list_item).removeClass("active");
// adiciona classe ativa para o <li> (pai) do <a> clicado, se ele não for o item que já está ativo
if (!$parent_list_item.hasClass("active")) {
$parent_list_item.addClass("active");
}else{
// Se for o que já está ativo remove a classe
$parent_list_item.removeClass("active");
}
});
body{
padding:20px;
}
/* apenas para visualização */
.nav{
width:400px;
}
/* reseta as listas em .nav */
.nav, .nav ul{
list-style:none;
margin:0;
padding:0;
}
/* estiliza todos os botões dentro de nav */
.nav a,
.nav span{
display:block;
text-decoration:none;
transition:all .3s ease; /* essa animação é entre a cor de fundo e cor da fonte, sempre muito útil */
}
/* posiciona o item relativo para os subitens (flutuantes) respeitarem sua posição */
.nav li{
position:relative;
}
/* estiliza o primeiro nível */
.nav > li > a,
.nav > li > span{
padding:10px;
background:#eee;
margin-bottom:1px;
color:#333;
}
.nav li > span{
cursor:pointer;
}
.nav li > span:after{
display:inline-block;
content:"+";
font-weight:bold;
font-size:16px;
float:right;
line-height:1em;
}
.nav > li > a:hover,
.nav > li > span:hover{
background:green;
color:white;
}
/* estiliza todos os subitems, ou seja, a lista pode ter vários subdropdowns. Está flutuante pois inseri position:absolute, se você remover o item mostra abaixo;*/
.nav li > ul{
position:absolute; /* comente esta linha para mostrar abaixo*/
top:100%;
z-index:2;
background:#aaa;
max-height:0; /* limita a altura para animarmos (obs este elemento não pode ter padding) */
overflow:hidden;
transition:all 0.5s ease; /* anima os estados do elemento */
/*left: 100%; /* descomente esta linha para mostrar ao lado invés de abaixo */
width:100%; /* deixa o submenu com a largura do pai, depende do caso, ele sobrepõe todos os filhos nesse caso, que não é bom */
margin-left:5px; /* um espaçamento pra ficar visualmente compreensível os níveis */
}
/* 2º nível */
.nav li ul > li > a,
.nav li ul > li > span{
padding:9px;
font-size:0.9em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > a:hover,
.nav li > ul > li > span:hover{
background:tomato;
color:white;
}
/* 3º nível */
.nav li > ul > li > ul > li > a,
.nav li > ul > li > ul > li > span{
padding:7px;
font-size:0.8em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > ul > li > a:hover,
.nav li > ul > li > ul > li > span:hover{
background:limegreen;
color:white;
}
/* estiliza o link dentro do item quando está ativo */
.nav li.active > a,
.nav li.active > span{
background:#333;
color:#fff;
}
.nav li.active > span:after{
content:"-";
}
.nav li.active > ul{
max-height:100vh; /* remove a limitação de altura para animar para height:auto.*/
animation:0s 1s delay-overflow forwards; /* pequeno hack para o overflow mudar apenas para o item aberto depois da animação terminada */
}
@keyframes delay-overflow {
to { overflow:visible; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li><span>Consultores</span>
<ul>
<li><a href="#0">sub - 1</a></li>
<li><a href="#0">sub - 2</a></li>
<li><span>sub - 3 (com subs)</span> <!-- como aqui é um botão simples de ordenação, ele não deve ser um link -->
<ul>
<li><a href="#0">sub sub - 1</a></li>
<li><a href="#0">sub sub - 2</a></li>
<li><a href="#0">sub sub - 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#0">Colaboradores</a></li>
<li><a href="#0">Comercial</a></li>
<li><a href="#0">RH</a></li>
</ul>
Eu acho estranho como o stackoverflow insere o código direto na página, então sempre uso alternativas como o CodePen, clique aqui para ver essa solução.
Outras observações sobre seu código:
- Tente não usar
ID
s em elementos que podem ser genéricos / modularizados / componentizados ou repetíveis na página, tente tratar o ID apenas para seleções JS específicas. Ex: a página pode ter vários dropdowns, então o componente é genérico.
Espero ter ajudado (apesar desse JS ainda me incomodar rs)
A forma mais simples e correta de ter o resultado esperado seria adicionar um javascript (ou jQuery) que ative o li
quando seu link é clicado com uma classe de CSS, e então você controla o efeito visual via CSS (em alguns casos também é feita a animação via JS, mas animações via CSS são aceleradas por hardware e têm um desempenho visual e de processamento muito melhor). É assim que maioria dos frameworks trabalham.
Segue mais ou menos o código (com JS bem fraco).
$(".nav li > span").click(function() {
// confesso que esse código parece pouco otimizado, aceito sugestões
$parent_list_item = $(this).parent("li");
// Remove todas as classes ativas de todos os itens dessa lista, para não ter 2 ativos ao mesmo tempo no mesmo dropdown. Mas ignora o item atual para checarmos depois de precisamos minimizar-lo
$parent_list_item.parent("ul").find(".active").not($parent_list_item).removeClass("active");
// adiciona classe ativa para o <li> (pai) do <a> clicado, se ele não for o item que já está ativo
if (!$parent_list_item.hasClass("active")) {
$parent_list_item.addClass("active");
}else{
// Se for o que já está ativo remove a classe
$parent_list_item.removeClass("active");
}
});
body{
padding:20px;
}
/* apenas para visualização */
.nav{
width:400px;
}
/* reseta as listas em .nav */
.nav, .nav ul{
list-style:none;
margin:0;
padding:0;
}
/* estiliza todos os botões dentro de nav */
.nav a,
.nav span{
display:block;
text-decoration:none;
transition:all .3s ease; /* essa animação é entre a cor de fundo e cor da fonte, sempre muito útil */
}
/* posiciona o item relativo para os subitens (flutuantes) respeitarem sua posição */
.nav li{
position:relative;
}
/* estiliza o primeiro nível */
.nav > li > a,
.nav > li > span{
padding:10px;
background:#eee;
margin-bottom:1px;
color:#333;
}
.nav li > span{
cursor:pointer;
}
.nav li > span:after{
display:inline-block;
content:"+";
font-weight:bold;
font-size:16px;
float:right;
line-height:1em;
}
.nav > li > a:hover,
.nav > li > span:hover{
background:green;
color:white;
}
/* estiliza todos os subitems, ou seja, a lista pode ter vários subdropdowns. Está flutuante pois inseri position:absolute, se você remover o item mostra abaixo;*/
.nav li > ul{
position:absolute; /* comente esta linha para mostrar abaixo*/
top:100%;
z-index:2;
background:#aaa;
max-height:0; /* limita a altura para animarmos (obs este elemento não pode ter padding) */
overflow:hidden;
transition:all 0.5s ease; /* anima os estados do elemento */
/*left: 100%; /* descomente esta linha para mostrar ao lado invés de abaixo */
width:100%; /* deixa o submenu com a largura do pai, depende do caso, ele sobrepõe todos os filhos nesse caso, que não é bom */
margin-left:5px; /* um espaçamento pra ficar visualmente compreensível os níveis */
}
/* 2º nível */
.nav li ul > li > a,
.nav li ul > li > span{
padding:9px;
font-size:0.9em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > a:hover,
.nav li > ul > li > span:hover{
background:tomato;
color:white;
}
/* 3º nível */
.nav li > ul > li > ul > li > a,
.nav li > ul > li > ul > li > span{
padding:7px;
font-size:0.8em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > ul > li > a:hover,
.nav li > ul > li > ul > li > span:hover{
background:limegreen;
color:white;
}
/* estiliza o link dentro do item quando está ativo */
.nav li.active > a,
.nav li.active > span{
background:#333;
color:#fff;
}
.nav li.active > span:after{
content:"-";
}
.nav li.active > ul{
max-height:100vh; /* remove a limitação de altura para animar para height:auto.*/
animation:0s 1s delay-overflow forwards; /* pequeno hack para o overflow mudar apenas para o item aberto depois da animação terminada */
}
@keyframes delay-overflow {
to { overflow:visible; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li><span>Consultores</span>
<ul>
<li><a href="#0">sub - 1</a></li>
<li><a href="#0">sub - 2</a></li>
<li><span>sub - 3 (com subs)</span> <!-- como aqui é um botão simples de ordenação, ele não deve ser um link -->
<ul>
<li><a href="#0">sub sub - 1</a></li>
<li><a href="#0">sub sub - 2</a></li>
<li><a href="#0">sub sub - 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#0">Colaboradores</a></li>
<li><a href="#0">Comercial</a></li>
<li><a href="#0">RH</a></li>
</ul>
Eu acho estranho como o stackoverflow insere o código direto na página, então sempre uso alternativas como o CodePen, clique aqui para ver essa solução.
Outras observações sobre seu código:
- Tente não usar
ID
s em elementos que podem ser genéricos / modularizados / componentizados ou repetíveis na página, tente tratar o ID apenas para seleções JS específicas. Ex: a página pode ter vários dropdowns, então o componente é genérico.
Espero ter ajudado (apesar desse JS ainda me incomodar rs)
$(".nav li > span").click(function() {
// confesso que esse código parece pouco otimizado, aceito sugestões
$parent_list_item = $(this).parent("li");
// Remove todas as classes ativas de todos os itens dessa lista, para não ter 2 ativos ao mesmo tempo no mesmo dropdown. Mas ignora o item atual para checarmos depois de precisamos minimizar-lo
$parent_list_item.parent("ul").find(".active").not($parent_list_item).removeClass("active");
// adiciona classe ativa para o <li> (pai) do <a> clicado, se ele não for o item que já está ativo
if (!$parent_list_item.hasClass("active")) {
$parent_list_item.addClass("active");
}else{
// Se for o que já está ativo remove a classe
$parent_list_item.removeClass("active");
}
});
body{
padding:20px;
}
/* apenas para visualização */
.nav{
width:400px;
}
/* reseta as listas em .nav */
.nav, .nav ul{
list-style:none;
margin:0;
padding:0;
}
/* estiliza todos os botões dentro de nav */
.nav a,
.nav span{
display:block;
text-decoration:none;
transition:all .3s ease; /* essa animação é entre a cor de fundo e cor da fonte, sempre muito útil */
}
/* posiciona o item relativo para os subitens (flutuantes) respeitarem sua posição */
.nav li{
position:relative;
}
/* estiliza o primeiro nível */
.nav > li > a,
.nav > li > span{
padding:10px;
background:#eee;
margin-bottom:1px;
color:#333;
}
.nav li > span{
cursor:pointer;
}
.nav li > span:after{
display:inline-block;
content:"+";
font-weight:bold;
font-size:16px;
float:right;
line-height:1em;
}
.nav > li > a:hover,
.nav > li > span:hover{
background:green;
color:white;
}
/* estiliza todos os subitems, ou seja, a lista pode ter vários subdropdowns. Está flutuante pois inseri position:absolute, se você remover o item mostra abaixo;*/
.nav li > ul{
position:absolute; /* comente esta linha para mostrar abaixo*/
top:100%;
z-index:2;
background:#aaa;
max-height:0; /* limita a altura para animarmos (obs este elemento não pode ter padding) */
overflow:hidden;
transition:all 0.5s ease; /* anima os estados do elemento */
/*left: 100%; /* descomente esta linha para mostrar ao lado invés de abaixo */
width:100%; /* deixa o submenu com a largura do pai, depende do caso, ele sobrepõe todos os filhos nesse caso, que não é bom */
margin-left:5px; /* um espaçamento pra ficar visualmente compreensível os níveis */
}
/* 2º nível */
.nav li ul > li > a,
.nav li ul > li > span{
padding:9px;
font-size:0.9em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > a:hover,
.nav li > ul > li > span:hover{
background:tomato;
color:white;
}
/* 3º nível */
.nav li > ul > li > ul > li > a,
.nav li > ul > li > ul > li > span{
padding:7px;
font-size:0.8em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > ul > li > a:hover,
.nav li > ul > li > ul > li > span:hover{
background:limegreen;
color:white;
}
/* estiliza o link dentro do item quando está ativo */
.nav li.active > a,
.nav li.active > span{
background:#333;
color:#fff;
}
.nav li.active > span:after{
content:"-";
}
.nav li.active > ul{
max-height:100vh; /* remove a limitação de altura para animar para height:auto.*/
animation:0s 1s delay-overflow forwards; /* pequeno hack para o overflow mudar apenas para o item aberto depois da animação terminada */
}
@keyframes delay-overflow {
to { overflow:visible; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li><span>Consultores</span>
<ul>
<li><a href="#0">sub - 1</a></li>
<li><a href="#0">sub - 2</a></li>
<li><span>sub - 3 (com subs)</span> <!-- como aqui é um botão simples de ordenação, ele não deve ser um link -->
<ul>
<li><a href="#0">sub sub - 1</a></li>
<li><a href="#0">sub sub - 2</a></li>
<li><a href="#0">sub sub - 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#0">Colaboradores</a></li>
<li><a href="#0">Comercial</a></li>
<li><a href="#0">RH</a></li>
</ul>
$(".nav li > span").click(function() {
// confesso que esse código parece pouco otimizado, aceito sugestões
$parent_list_item = $(this).parent("li");
// Remove todas as classes ativas de todos os itens dessa lista, para não ter 2 ativos ao mesmo tempo no mesmo dropdown. Mas ignora o item atual para checarmos depois de precisamos minimizar-lo
$parent_list_item.parent("ul").find(".active").not($parent_list_item).removeClass("active");
// adiciona classe ativa para o <li> (pai) do <a> clicado, se ele não for o item que já está ativo
if (!$parent_list_item.hasClass("active")) {
$parent_list_item.addClass("active");
}else{
// Se for o que já está ativo remove a classe
$parent_list_item.removeClass("active");
}
});
body{
padding:20px;
}
/* apenas para visualização */
.nav{
width:400px;
}
/* reseta as listas em .nav */
.nav, .nav ul{
list-style:none;
margin:0;
padding:0;
}
/* estiliza todos os botões dentro de nav */
.nav a,
.nav span{
display:block;
text-decoration:none;
transition:all .3s ease; /* essa animação é entre a cor de fundo e cor da fonte, sempre muito útil */
}
/* posiciona o item relativo para os subitens (flutuantes) respeitarem sua posição */
.nav li{
position:relative;
}
/* estiliza o primeiro nível */
.nav > li > a,
.nav > li > span{
padding:10px;
background:#eee;
margin-bottom:1px;
color:#333;
}
.nav li > span{
cursor:pointer;
}
.nav li > span:after{
display:inline-block;
content:"+";
font-weight:bold;
font-size:16px;
float:right;
line-height:1em;
}
.nav > li > a:hover,
.nav > li > span:hover{
background:green;
color:white;
}
/* estiliza todos os subitems, ou seja, a lista pode ter vários subdropdowns. Está flutuante pois inseri position:absolute, se você remover o item mostra abaixo;*/
.nav li > ul{
position:absolute; /* comente esta linha para mostrar abaixo*/
top:100%;
z-index:2;
background:#aaa;
max-height:0; /* limita a altura para animarmos (obs este elemento não pode ter padding) */
overflow:hidden;
transition:all 0.5s ease; /* anima os estados do elemento */
/*left: 100%; /* descomente esta linha para mostrar ao lado invés de abaixo */
width:100%; /* deixa o submenu com a largura do pai, depende do caso, ele sobrepõe todos os filhos nesse caso, que não é bom */
margin-left:5px; /* um espaçamento pra ficar visualmente compreensível os níveis */
}
/* 2º nível */
.nav li ul > li > a,
.nav li ul > li > span{
padding:9px;
font-size:0.9em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > a:hover,
.nav li > ul > li > span:hover{
background:tomato;
color:white;
}
/* 3º nível */
.nav li > ul > li > ul > li > a,
.nav li > ul > li > ul > li > span{
padding:7px;
font-size:0.8em;
border-bottom:1px solid white;
color:#666;
}
.nav li > ul > li > ul > li > a:hover,
.nav li > ul > li > ul > li > span:hover{
background:limegreen;
color:white;
}
/* estiliza o link dentro do item quando está ativo */
.nav li.active > a,
.nav li.active > span{
background:#333;
color:#fff;
}
.nav li.active > span:after{
content:"-";
}
.nav li.active > ul{
max-height:100vh; /* remove a limitação de altura para animar para height:auto.*/
animation:0s 1s delay-overflow forwards; /* pequeno hack para o overflow mudar apenas para o item aberto depois da animação terminada */
}
@keyframes delay-overflow {
to { overflow:visible; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li><span>Consultores</span>
<ul>
<li><a href="#0">sub - 1</a></li>
<li><a href="#0">sub - 2</a></li>
<li><span>sub - 3 (com subs)</span> <!-- como aqui é um botão simples de ordenação, ele não deve ser um link -->
<ul>
<li><a href="#0">sub sub - 1</a></li>
<li><a href="#0">sub sub - 2</a></li>
<li><a href="#0">sub sub - 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#0">Colaboradores</a></li>
<li><a href="#0">Comercial</a></li>
<li><a href="#0">RH</a></li>
</ul>
editada 13/03 às 17:13
respondida 12/03 às 20:03
teefarsteefars
1013
1013
comentar |
comentar |
Obrigado por contribuir com o Stack Overflow em Português!
- Certifique-se de responder à pergunta. Entre em detalhes sobre a sua solução e compartilhe o que você descobriu.
Mas evite …
- Pedir esclarecimentos ou detalhes sobre outras respostas.
- Fazer afirmações baseadas apenas na sua opinião; aponte referências ou experiências anteriores.
Para aprender mais, veja nossas dicas sobre como escrever boas respostas.
Registre-se ou faça log-in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Registre-se usando o Google
Registre-se usando o Facebook
Registre-se usando Email e Senha
Publicar como convidado
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fpt.stackoverflow.com%2fquestions%2f367600%2fdropdown-com-clique%23new-answer', 'question_page');
}
);
Publicar como convidado
Required, but never shown
Registre-se ou faça log-in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Registre-se usando o Google
Registre-se usando o Facebook
Registre-se usando Email e Senha
Publicar como convidado
Required, but never shown
Registre-se ou faça log-in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Registre-se usando o Google
Registre-se usando o Facebook
Registre-se usando Email e Senha
Publicar como convidado
Required, but never shown
Registre-se ou faça log-in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Registre-se usando o Google
Registre-se usando o Facebook
Registre-se usando Email e Senha
Registre-se usando o Google
Registre-se usando o Facebook
Registre-se usando Email e Senha
Publicar como convidado
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Está bem difícil de entender. Você consegue editar a pergunta e colocar o seu CSS como código? Adiciona o HTML também.
– DaviAragao
11/03 às 19:31
Você já tentou ao invés de :hover usar um :focus? Acho que funciona ;-)
– Renato Muller Ventura
13/03 às 17:39