Como remover o foco ao redor dos botões ao clicar

225

Todos os meus botões têm um destaque ao redor deles depois que eu clico neles. Isso está no Chrome.

Não selecionado Selecionado

<button class="btn btn-primary btn-block">
    <span class="icon-plus"></span> Add Page
</button>

Estou usando o Bootstrap com um tema, mas tenho certeza de que não é isso: eu estava percebendo isso antes em outro projeto.

Ele desaparece se eu usar uma <a>tag em vez de <button>. Por quê? Se eu quisesse usar <button>como faria isso desaparecer?

Sean Clark Hess
fonte
12
esboço: 0; pode interessar
Wiggler Jtag 27/09/13
Alguma classe está sendo adicionada após o clique?
Kuzgun # 27/13
1
estrutura de tópicos: 0 parece não ajudar, nem aparência de webkit
Sean Clark Hess
7
28 respostas, todas sugerindo métodos diferentes para solucionar esse problema, são uma prova do triste estado do desenvolvimento da web de front-end atualmente.
deltanine
3
As pessoas que consideram esse recurso de acessibilidade um problema são o testemunho do triste estado do desenvolvimento da web de front-end atualmente.
Quentin

Respostas:

292

Encontrei essas perguntas e respostas em outra página e substituir o estilo de foco do botão funcionou para mim. Esse problema pode ser específico ao MacOS com o Chrome.

.btn:focus {
  outline: none;
  box-shadow: none;
}

Observe que isso tem implicações para a acessibilidade e não é recomendado até que você tenha um bom estado de foco consistente para seus botões e entradas. De acordo com os comentários abaixo, existem usuários por aí que não podem usar ratos.

jerimiah797
fonte
33
Também pensei nisso, mas a remoção do esboço não apresenta problemas de acessibilidade?
silvenon
10
Acho que não temos outra escolha. Você também pode adicionar o .btn:active:focusseletor para removê-lo do estado ativo.
silvenon
45
Remover o contorno de um botão é definitivamente ruim para a acessibilidade. Existem usuários que não podem controlar um mouse e precisam ser capazes de percorrer uma página com o teclado. Remover o contorno torna isso muito difícil. Provavelmente, é melhor evitar que o botão receba foco no clique.
Murphy Randle
Para futuros viajantes, esse código substitui completamente todos os estilos em todos os estados dos botões pelo botão padrão (nem todos os botões):.btn-default, .btn-default:hover, .btn-default:active, .btn-default:active:focus, .btn-default:visited, .btn-default:focus { color: #dcdcdc; background-color: #232323; outline: none; }
Geordie
1
se estiver usando variáveis ​​de autoinicialização incorporadas, é possível conseguir isso configurando esses dois vars como: $ btn-focus-width: 0; $ btn-focus-box-shadow: nenhum;
Bullettrain 14/05/19
109

Você quer algo como:

<button class="btn btn-primary btn-block" onclick="this.blur();">...

O método .blur () remove corretamente o destaque do foco e não atrapalha os estilos do Bootstraps.

Cshotton
fonte
9
Isso exibe o esboço por um breve momento, que ainda o arruina: /
silvenon
2
Não vejo cintilação se eu ativar o evento de foco em vez do evento de clique.
Charles
2
Isso funcionou muito bem! Haveria problemas em potencial se eu tentasse anexar um manipulador de eventos click () diferente (ou seja, o código que é executado quando você clica no botão) ao mesmo botão?
N
4
Se alguém está aqui se perguntando se isso funciona no bootstrap v4, ele funciona. Resposta ainda válida em 2018, felicidades!
Jreed
4
É acessibilidade-OK, em comparação com a pergunta mais votada?
precisa
47

meu entendimento é que o foco é aplicado pela primeira vez após o onMouseDownevento, para chamar e.preventDefault()emonMouseDown pode ser uma solução limpa, dependendo de suas necessidades. Esta é certamente uma solução amigável à acessibilidade, mas obviamente ajusta o comportamento dos cliques do mouse que podem não ser compatíveis com o seu projeto na web.

Atualmente, estou usando esta solução (dentro de um react-bootstrapprojeto) e não recebo uma piscada de foco ou o foco retido dos botões após um clique, mas ainda posso tabular meu foco e visualizar visualmente o foco dos mesmos botões.

pjs
fonte
2
Sim. sua solução funciona. Obrigado pela dica. Aqui está o violino para a solução. Mas requer que um manipulador de javascript seja anexado a cada botão. Seria ótimo se conseguirmos isso por meio da solução somente CSS.
Galeel Bhasha
1
Acho que as pessoas esperam que o foco entre em um elemento quando você clica nele, e essa solução evita isso. Costumo clicar em um elemento e depois me afasto antes de soltar o mouse para dar foco, para que eu possa seguir a partir daí.
Michael Tontchev
7
Para quem procura um trecho, isso deve funcionar e preservar o onClick:onMouseDown={e => e.preventDefault()}
Adam K Dean
1
Isso impede que a barra de espaço e a chave de retorno "cliquem" no botão. Talvez uma solução mais completa é adicionar esta de volta com: onKeyUp={(e) => {if (e.keyCode === 13 || e.keyCode === 32) handleClick()}.
jfbloom22
Você não deve chamar e.preventDefault () dentro do onKeyUpevento. Acontece que, se você fizer isso, o botão permanecerá focado depois de pressionar a tecla de espaço ou a tecla de retorno, e tabular ou clicar em qualquer lugar.
Jfbloom22
30

Não posso acreditar que ninguém postou isso ainda.

Use um rótulo em vez de um botão.

<label type="button" class="btn btn-primary btn-block">
<span class="icon-plus"></span> Add Page
</label>

Violino

Adam McKenna
fonte
11
Isso funciona bem para a maioria dos usuários, mas esse método não é amigável para leitores de tela ou teclados e deixará usuários cegos e usuários com habilidades motoras comprometidas, incapazes de interagir com o botão.
Murphy Randle
8
1. Substitua a etiqueta pela etiqueta <a>. para que seja acessível via teclado. 2. adicione aria-role = "button" para melhorar a acessibilidade do usuário do leitor de tela. atualizado Fiddle
Galeel Bhasha
boa solução, me ajudou, mas de alguma forma não funciona para directiva angular, mesmo com um invólucro, por exemplo<a class="btn"><my-directive/></a>
ya_dimon
2
Os rótulos são totalmente ignorados para usuários não ratos quando tabulações ao redor, ruim para acessibilidade
Felipe junho
1
No Bootstrap 4, parece alterar a aparência do botão.
Jason Kim
30

Embora seja fácil remover apenas o contorno de todos os botões focados (como na resposta do usuário1933897 ), mas essa solução é ruim do ponto de vista da acessibilidade (por exemplo, consulte Parar de mexer com o contorno do foco padrão do navegador )

Por outro lado, provavelmente é impossível convencer seu navegador a parar de estilizar seu botão clicado como focado se ele achar que está focado depois que você clicou nele (estou olhando para você, Chrome no OS X).

Então o que nós podemos fazer? Algumas opções vêm à minha mente.

1) Javascript (jQuery): $('.btn').mouseup(function() { this.blur() })

Você está instruindo seu navegador a remover o foco em qualquer botão imediatamente após o clique. Ao usar em mouseupvez de clickmantermos o comportamento padrão para interações baseadas em teclado ( mouseupnão é acionado pelo teclado).

2) CSS: .btn:hover { outline: 0 !important }

Aqui você desativa o contorno apenas dos botões suspensos . Obviamente, não é o ideal, mas pode ser suficiente em algumas situações.

Alexis
fonte
4
O número 1 é uma dica útil. Desabilitará o foco quando o botão não for pressionado, no entanto, o exibirá enquanto estiver pressionado. Desativei o foco no elemento ativo clicado com :active:focus {outline:none;}.
certainlyakey
As funções de taquigrafia que os ouvintes de eventos de ligação estão obsoletas na jQuery, por isso é melhor se você usar .on('mouseup', function() { ... })em vez de.mouseup()
Louco Redd
16

Isso funcionou para mim. Criei uma classe personalizada que substitui o CSS necessário.

.custom-button:focus {
    outline: none !important;
    border: none !important;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
}

insira a descrição da imagem aqui

O -webkit-box-shadow funcionará nos navegadores Chrome e Safari.

men_aka
fonte
trabalha para mim, mas eu tinha que remover border: none !important;para o botão para manter mesmas dimensões
Emeka Mbah
1
Eu estava procurando remover o foco do onClick acima das respostas que não funcionaram, mas "box-shadow: none! Important;" seu trabalho para mim graças @Menaka
Zaif Aqueça
11

Isso funciona para mim, outra solução não mencionada. Basta jogá-lo no evento click ...

$(this).trigger("blur");

Ou chame-o de outro evento / método ...

$(".btn_name").trigger("blur");
Roubar
fonte
O problema é que, quando um usuário do teclado "clica" no botão (concentrando-o e pressionando espaço), ele perde o foco. Você então tem que tabular todo o caminho de volta para onde quer que estivesse. Tam
Tamlyn
8

Se você usar a regra :focus { outline: none; }para remover contornos, o link ou controle poderá ser focado, mas sem indicação de foco para os usuários do teclado. Os métodos para removê-lo com JS onfocus="blur()"são ainda piores e resultam em usuários de teclado incapazes de interagir com o controle.

Os hacks que você pode usar, que estão bem , incluem adicionar :focus { outline: none; }regras quando os usuários interagem com o mouse e removê-los novamente se a interação do teclado for detectada. Lindsay Evans fez uma lib para isso: https://github.com/lindsayevans/outline.js

Mas eu preferiria definir uma classe na tag html ou body. E tenha controle no arquivo CSS de quando usar isso.

Por exemplo (os manipuladores de eventos em linha são apenas para fins de demonstração):

<html>
<head>
<style>
  a:focus, button:focus {
    outline: 3px solid #000;
  }
  .no-focus a, .no-focus button {
    outline: none;
  } 
</style>
</head>
<body id="thebody" 
onmousedown="document.getElementById('thebody').classList.add('no-focus');"
onkeydown="document.getElementById('thebody').classList.remove('no-focus');">
    <p>This her is <a href="#">a link</a></p>   
    <button>Click me</button>
</body>
</html>

Coloquei uma caneta junto: http://codepen.io/snobojohan/pen/RWXXmp

Mas cuidado, existem problemas de desempenho. Isso força a repintura sempre que o usuário alterna entre o mouse e o teclado. Mais sobre como evitar tintas desnecessárias http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/

snobojohan
fonte
6

Percebi o mesmo e, mesmo que isso realmente me irrite, acredito que não há uma maneira adequada de lidar com isso.

Eu recomendaria contra todas as outras soluções fornecidas, porque elas eliminam completamente a acessibilidade do botão. Agora, quando você guia o botão, não obtém o foco esperado.

Isso deve ser evitado!

.btn:focus {
  outline: none;
}
Oscar Bolaños
fonte
Eu não acho que isso esteja errado, porque você ainda possui um raio ligeiramente diferente quando focado, para que mesmo os usuários de teclado possam reconhecê-lo. Mas isso enought aint, porque você ainda vai receber frame da beira quando você pressionar e segurar o botão esquerdo do mouse
apocalypz
6

Eu encontro uma solução. quando nos concentramos, o bootstrap usa box-shadow, então apenas o desabilitamos (reputação insuficiente, não é possível carregar a imagem :().

Eu adiciono

.btn:focus{
    box-shadow:none !important;
}

funciona.

caramelo
fonte
6

OPÇÃO 1: Use o :focus-visible pseudo classe

A :focus-visiblepseudo-classe pode ser usada para eliminar os contornos desagradáveis ​​e focar os anéis nos botões e em vários elementos para os usuários que NÃO estão navegando pelo teclado (por exemplo, via toque ou clique do mouse).

/** 
 * The default focus style is likely provided by Bootstrap or the browser
 * but here we override everything else with a visually appealing cross-
 * browser solution that works well on all focusable page elements
 * including buttons, links, inputs, textareas, and selects.
 */
*:focus { 
  outline: 0 !important;
  box-shadow:
    0 0 0 .2rem #fff, /* use site bg color to create whitespace for faux focus ring */
    0 0 0 .35rem #069 !important; /* faux focus ring color */
}

/**
 * Undo the above focused button styles when the element received focus
 * via mouse click or touch, but not keyboard navigation.
 */
*:focus:not(:focus-visible) {
  outline: 0 !important;
  box-shadow: none !important;
}

Aviso: a partir de 2020, a :focus-visiblepseudo classe não é amplamente suportada nos navegadores . No entanto, o polyfill é muito fácil de usar; veja as instruções abaixo.


OPÇÃO 2: use o .focus-visiblepolyfill

Esta solução usa uma classe CSS normal em vez da pseudo-classe mencionada acima e possui amplo suporte ao navegador porque é um polyfill oficial baseado em Javascript .

Etapa 1: adicione as dependências Javascript à sua página HTML

Nota: o polyfill visível ao foco requer um polyfill adicional para vários navegadores mais antigos que não suportam classList :

<!-- place this code just before the closing </html> tag -->
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=Element.prototype.classList"></script>
<script src="https://unpkg.com/focus-visible"></script>

Etapa 2: adicione o seguinte CSS à sua folha de estilo

A seguir está uma versão modificada da solução CSS documentada mais detalhadamente acima.

/**
 * Custom cross-browser styles for keyboard :focus overrides defaults.
 */
*:focus { 
  outline: 0 !important;
  box-shadow:
    0 0 0 .2rem #fff,
    0 0 0 .35rem #069 !important;
}

/**
 * Remove focus styles for non-keyboard :focus.
 */
*:focus:not(.focus-visible) {
  outline: 0 !important;
  box-shadow: none !important;
}

Etapa 3 (opcional): use a classe 'focus-visible' sempre que necessário

Se você possui algum item em que realmente deseja mostrar o anel de foco quando alguém clica ou usa o toque, basta adicionar a focus-visibleclasse ao elemento DOM.

<!-- This example uses Bootstrap classes to theme a button to appear like
     a regular link, and then add a focus ring when the link is clicked --->
<button type="button" class="btn btn-text focus-visible">
  Clicking me shows a focus box
</button>

Recurso:

Demo:

JamesWilson
fonte
Mas se o Chrome ainda não o suporta, provavelmente não é a melhor solução (por enquanto)
Elijah Mock
O que você sugere em vez disso?
JamesWilson
Esconda o esboço como as outras respostas dizem até que esta solução seja mais padronizada
Elijah Mock
Pela minha leitura das coisas, se a acessibilidade é uma preocupação, esconder a carta branca básica <whatever>:focus { outline: none }é uma ideia pior do que esta solução. Na verdade, existem pessoas na comunidade de acessibilidade que preferem que você NUNCA remova o contorno e faça com que tudo tenha um estilo: focus (contorno ou box-shadow) e não queira oferecer suporte: focus-visible até que os navegadores implementem uma maneira de permitir os usuários especificam uma preferência do usuário para saber se todos os itens devem ser focados ou não. Eu gosto de pensar: o foco visível é um meio termo entre as preocupações com o design e todos os dias.
JamesWilson
5

Se o acima não funcionar, tente o seguinte:

.btn: focus {estrutura de tópicos: nenhuma; caixa-sombra: nenhuma; borda: 2px sólido transparente;}

Como user1933897 apontou, isso pode ser específico para o MacOS com Chrome.

alns
fonte
Ainda este é válida quando o uso bootstrap 4.0- nas janelas
3gwebtrain
5

Tarde, mas quem sabe isso pode ajudar alguém. O CSS ficaria assim:

.rhighlight{
   outline: none !important;
   box-shadow:none
}

O HTML seria semelhante a:

<button type="button" class="btn btn-primary rHighlight">Text</button> 

Dessa forma, você pode manter o btn e seus comportamentos associados.

Stephanie Wyche
fonte
1
element:focus { box-shadow: none; }removido contorno / sombra azul.
user435421
3

Mencionei isso em um comentário acima, mas vale a pena listar como uma resposta separada para maior clareza. Contanto que você não precise realmente se concentrar no botão, você pode usar o evento focus para removê-lo antes que ele possa aplicar efeitos CSS:

$('buttonSelector').focus(function(event) {
    event.target.blur();
});

Isso evita a oscilação que pode ser vista ao usar o evento click. Isso restringe a interface e você não poderá tabular para o botão, mas isso não é um problema em todos os aplicativos.

Charles
fonte
Isso fez metade do truque para mim. Estou usando React e React-Bootstrap. Após o clique, o botão ficava destacado com um brilho em torno disso. Adicionando e.target.blur (); remove o brilho, mas o botão permanece com uma cor diferente.
precisa saber é o seguinte
3

Estilo

.not-focusable:focus {
    outline: none;
    box-shadow: none;
}

Usando

<button class="btn btn-primary not-focusable">My Button</button>
Bogdan Kanteruk
fonte
Como esta solução difere das outras respostas?
apaul 11/08/2015
2
Há apenas uma uma pequena diferença - você pode remover o foco para os elementos que você precisa com a especificação de classe "não-focalizável" sem substituir o comportamento de todos os botões, links etc.
Bogdan Kanteruk
3

Experimente esta solução para remover a borda ao redor do botão. Adicione este código em css.

Experimentar

button:focus{
outline:0px;
}

Se não funcionar, use abaixo.

button:focus{
 outline:none !important;
 }
Rana Aalamgeer
fonte
Segundo um funciona mesmo com Reagir botão material UI
Geek Guy
3

Para pessoas que desejam uma maneira css pura de fazer isso:

:focus:not(:focus-visible) { outline: none }

Isso também pode funcionar para link e assim por diante, além de bônus, mantém as acessibilidades do teclado. Por fim, é ignorado por navegadores que não suportam: foco visível

Martin Pedros
fonte
4
Isto só irá funcionar no Chrome com recursos experimentais habilitado, conforme developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
Justin Kahn
focus-visibleagora tem um polyfill oficial. Minha resposta stackoverflow.com/a/60219624/413538 sobre esta questão explica como realmente entender tudo isso.
JamesWilson 15/04
2

Estávamos com um problema semelhante e percebemos que o Bootstrap 3 não tem o problema em suas guias (no Chrome). Parece que eles estão usando o estilo de estrutura de tópicos, o que permite que o navegador decida o que é melhor fazer e o Chrome parece fazer o que você deseja: mostre a estrutura de tópicos quando focada, a menos que você tenha clicado no elemento.

outline-styleÉ difícil definir o suporte , pois o navegador decide o que isso significa. É melhor fazer check-in em alguns navegadores e ter uma regra de reserva.

TeknoFiend
fonte
2

Outra solução possível é adicionar uma classe usando um ouvinte Javascript quando o usuário clicar no botão e remover essa classe em foco com outro ouvinte. Isso mantém a acessibilidade (guias visíveis) e também impede o comportamento peculiar do Chrome de considerar um botão focado quando clicado.

JS:

$('button').click(function(){
    $(this).addClass('clicked');
});
$('button').focus(function(){
    $(this).removeClass('clicked');
});

CSS:

button:focus {
    outline: 1px dotted #000;
}
button.clicked {
    outline: none;
}

Exemplo completo aqui: https://jsfiddle.net/4bbb37fh/

Seb Woolford
fonte
Use mouseDown em vez de clicar. Ao clicar, o contorno aparece enquanto o mouse é pressionado (sem soltá-lo) inicial.
Vincent Hoch-Drei
2

É trabalho, espero te ajudar

.btn:focus, .btn:focus:active {
    outline: none;
}
Дмитрий Будницкий
fonte
.btn: o foco deve ter o esboço para acessibilidade (quando tabulações)
yennefer
2
.btn:focus:active {
  outline: none;
}

isso remove o contorno ao clicar, mas mantém o foco ao tabular (para a11y)

yennefer
fonte
Isso remove apenas o contorno no mouse para baixo. Após o mouse, o contorno aparece.
Wellspring 24/01
2

Isso funciona melhor

.btn-primary.focus, .btn-primary:focus {
-webkit-box-shadow: none!important;
box-shadow: none!important;
}

fonte
1
  .btn:focus,.btn:active, a{
        outline: none !important;
        box-shadow: none;
     }

este esquema: nenhum funcionará tanto para o botão quanto para uma tag

Milan Panigrahi
fonte
Como isso responde à pergunta? Por favor, adicione algumas explicações.
André Kool
1

Adicione isso no CSS:

*, ::after, ::before {
    box-sizing: border-box;
    outline: none !important;
    border: none !important;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
}
Gabriel Reis
fonte
1

Eu encontrei uma solução basta adicionar abaixo da linha no seu código css.

button:focus { outline: none }
Manish Kumar Srivastava
fonte
0

Eu apenas tive esse mesmo problema no MacOS e no Chrome enquanto usava um botão para acionar um evento de "transição". Se alguém que estiver lendo isso já estiver usando um ouvinte de evento, poderá resolvê-lo chamando .blur()suas ações.

Exemplo:

 nextQuestionButtonEl.click(function(){
    if (isQuestionAnswered()) {
        currentQuestion++;
        changeQuestion();
    } else {
        toggleNotification("invalidForm");
    }
    this.blur();
});

Embora se você ainda não estiver usando um ouvinte de evento, a adição de um apenas para resolver isso pode adicionar sobrecarga desnecessária e uma solução de estilo, como as respostas anteriores fornecem, é melhor.

jospablos
fonte
0

Você pode definir tabIndex="-1". Isso fará com que o navegador pule esse botão ao percorrer os controles de foco.

Outras "correções" sugeridas aqui, apenas removem o contorno do foco, mas ainda deixam os botões com tabulação. No entanto, do ponto de vista da usabilidade, você já removeu o brilho, para que o usuário não saiba de nenhuma maneira o que está focado no momento.

Por outro lado, tornar o botão não tabulável tem implicações de acessibilidade.

Estou usando-o para remover o contorno do foco do botão X bootstrap modal, que possui o botão "Fechar" na parte inferior de qualquer maneira, para que minha solução não tenha impacto na acessibilidade.

zmecânico
fonte
0

Se você estiver usando um navegador de webkit (e potencialmente um navegador compatível com a prefixação de fornecedor de webkit), esse esquema pertence à -webkit-focus-ringpseudoclasse do botão . Basta definir que é outlinea none:

*:-webkit-focus-ring {
  outline: none;
}

O Chrome é um navegador da Webkit e esse efeito também acontece no Linux (não apenas no macOS, embora alguns estilos do Chrome sejam apenas para macOS)

Nate Symer
fonte
0

Eu estava tendo o mesmo problema usando o <a>botão atuando como e descobri que estava faltando uma solução alternativa ao adicionar attr para type="button"que ela se comportasse normalmente pelo menos para mim.

<a type="button" class="btn btn-primary">Release Me!</a>

spcsLrg
fonte
O typeatributo não deve ter efeito sobre isso e buttoné um valor inválido para ele. O atributo aceita um tipo MIME e diz ao cliente que tipo de dados que ele deve esperar para obter se ele segue o link (ex <a type="application/pdf" ...>.
Quentin
@ Quentin Obrigado. Sim, eu estou ciente disso. Comecei com role="button"mas não funcionou (depois de usar um em <button>vez de <a>). Minha implementação exigiu especificamente um <a>e não <button>. Então, depois de mexer muito, descobri essa solução alternativa (provavelmente um bug do BS)!
precisa saber é o seguinte
0

diretamente na tag html (em um cenário em que você pode querer deixar o tema de auto-inicialização no lugar em outro lugar no seu design) ..

exemplos para tentar ..

<button style="border: transparent;">
<button style="border: 1px solid black;">

..ect ,. dependendo do efeito desejado.

Ninguém
fonte