Cómo eliminar el foco alrededor de los botones al hacer clic

226

Todos mis botones se resaltan después de hacer clic en ellos. Esto está en Chrome.

No seleccionado Seleccionado

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

Estoy usando Bootstrap con un tema, pero estoy bastante seguro de que no es así: me di cuenta de esto antes en otro proyecto.

Desaparece si uso una <a>etiqueta en lugar de <button>. ¿Por qué? Si quisiera usar, <button>¿cómo lo haría desaparecer?

Sean Clark Hess
fuente
12
esquema: 0; puede interesarle
Wiggler Jtag
¿Se agrega alguna clase después de hacer clic?
Kuzgun
1
esquema: 0 no parece ayudar, ni la apariencia del webkit
Sean Clark Hess
77
28 respuestas que sugieren diferentes métodos para solucionar este problema es un testimonio del lamentable estado actual del desarrollo web front-end.
deltanine
3
Las personas que consideran que esta característica de accesibilidad es un problema es el testimonio del lamentable estado actual del desarrollo web front-end.
Quentin

Respuestas:

293

Encontré estas preguntas y respuestas en otra página, y reemplazar el estilo de enfoque del botón funcionó para mí. Este problema puede ser específico de MacOS con Chrome.

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

Sin embargo, tenga en cuenta que esto tiene implicaciones para la accesibilidad y no se recomienda hasta que tenga un buen estado de enfoque consistente para sus botones y entradas. Según los comentarios a continuación, hay usuarios que no pueden usar ratones.

jerimiah797
fuente
33
También pensé en esto, pero ¿eliminar el esquema no tiene problemas de accesibilidad?
silvenon
10
Supongo que no tenemos otra opción. También puede agregar el .btn:active:focusselector para eliminarlo también del estado activo.
silvenon
45
Eliminar el contorno de un botón definitivamente es malo para la accesibilidad. Hay usuarios que no pueden controlar un mouse y deben poder pasar una página con el teclado. Eliminar el contorno hace que sea muy difícil. Probablemente sea mejor evitar que el botón reciba el foco al hacer clic.
Murphy Randle
Para futuros viajeros, este código reemplaza completamente todos los estilos en todos los estados de botón para el botón predeterminado (no todos los botones):.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
si se utilizan variables de arranque incorporadas, se puede lograr esto estableciendo estos dos vars en: $ btn-focus-width: 0; $ btn-focus-box-shadow: ninguno;
Bullettrain
109

Quieres algo como:

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

El método .blur () elimina correctamente el resaltado del foco y no estropea los estilos de Bootstraps.

cshotton
fuente
99
Esto muestra el esquema por un breve momento, que todavía lo arruina: /
silvenon
2
No veo ningún parpadeo si desencado el evento de enfoque en lugar del evento de clic.
Charles
2
¡Esto funcionó muy bien! ¿Habría problemas potenciales si intentara adjuntar un controlador de eventos click () diferente (es decir, el código que se ejecuta cuando hace clic en dicho botón) al mismo botón?
Nils_e
44
Si alguien se pregunta si esto funciona en Bootstrap v4, lo hace. La respuesta sigue siendo válida en 2018, ¡salud!
Jreed
44
¿Es accesibilidad-OK, en comparación con la pregunta más votada?
CharlesM
47

mi opinión es que el enfoque se aplicó por primera vez tras el onMouseDownevento, así que llamar e.preventDefault()en onMouseDownpuede ser una solución limpia en función de sus necesidades. Esta es ciertamente una solución amigable para la accesibilidad, pero obviamente ajusta el comportamiento de los clics del mouse que pueden no ser compatibles con su proyecto web.

Actualmente estoy usando esta solución (dentro de un react-bootstrapproyecto) y no recibo un parpadeo de foco o foco retenido de botones después de un clic, pero todavía puedo tabular mi foco y visualizar visualmente el foco de los mismos botones.

pjs
fuente
2
Si. Su solución funciona. Gracias por el consejo. Aquí está el violín para la solución. Pero requiere que se adjunte un controlador de JavaScript a cada botón. Sería genial si pudiéramos lograr esto a través de la única solución CSS.
Galeel Bhasha
1
Creo que la gente espera que el foco se centre en un elemento cuando haces clic en él, y esta solución lo impide. A menudo hago clic en un elemento y luego me alejo antes de soltar el mouse para enfocarlo y así poder tabular a partir de ahí.
Michael Tontchev
77
Para cualquiera que esté buscando un fragmento, esto debería funcionar y preservar onClick:onMouseDown={e => e.preventDefault()}
Adam K Dean el
1
Esto evita que la barra espaciadora y la tecla de retorno "hagan clic" en el botón. Tal vez una solución más completa es añadir esta de vuelta con: onKeyUp={(e) => {if (e.keyCode === 13 || e.keyCode === 32) handleClick()}.
jfbloom22
No debe llamar a e.preventDefault () dentro del onKeyUpevento. Resulta que si haces eso, entonces el botón permanece enfocado después de presionar la tecla de espacio o la tecla de retorno y presionar o hacer clic en cualquier lugar.
jfbloom22
30

No puedo creer que nadie haya publicado esto todavía.

Use una etiqueta en lugar de un botón.

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

Violín

Adam McKenna
fuente
11
Esto funciona bien para la mayoría de los usuarios, pero este método no es amigable para los lectores de pantalla o los teclados y dejará a los usuarios ciegos y a los usuarios con habilidades motoras comprometidas, incapaces de interactuar con el botón.
Murphy Randle
8
1. Reemplace la etiqueta con la etiqueta <a>. para que sea accesible a través del teclado. 2. agregue aria-role = "button" para mejorar la accesibilidad del usuario del lector de pantalla. Fiddle actualizado
Galeel Bhasha
buena solución, me ayudó, pero de alguna manera no funciona para directivas angulares, incluso con un envoltorio, por ejemplo<a class="btn"><my-directive/></a>
ya_dimon
2
Las etiquetas se omiten por completo para los usuarios que no usan ratones cuando se registran, lo que es malo para la accesibilidad
Felipe Jun
1
En Bootstrap 4 parece alterar el aspecto del botón.
Jason Kim
30

Aunque es fácil eliminar el contorno de todos los botones enfocados (como en la respuesta del usuario 1933897 ), esa solución es mala desde el punto de vista de la accesibilidad (por ejemplo, vea Detener el juego con el contorno de enfoque predeterminado del navegador )

Por otro lado, es probable que sea imposible convencer a su navegador para que deje de diseñar su botón de clic como enfocado si cree que está enfocado después de hacer clic en él (lo estoy mirando, Chrome en OS X).

¿Entonces, qué podemos hacer? Un par de opciones me vienen a la mente.

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

Le indica a su navegador que elimine el foco alrededor de cualquier botón inmediatamente después de hacer clic en el botón. Al usar en mouseuplugar de clickmantener el comportamiento predeterminado para las interacciones basadas en el teclado ( mouseupno se activa por el teclado).

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

Aquí se apaga esquema para cernió únicos botones. Obviamente no es ideal, pero puede ser suficiente en algunas situaciones.

Alexis
fuente
44
El número 1 es un consejo útil. Desactivará el enfoque cuando no se presione el botón, sin embargo, lo dejará visualizado mientras se presiona. He deshabilitado el foco en el elemento activo con clic :active:focus {outline:none;}.
Ciertamente, el
Las funciones abreviadas que unen a los oyentes de eventos están en desuso en jQuery, por lo que es mejor si lo usa en .on('mouseup', function() { ... })lugar de.mouseup()
Crazy Redd el
16

Esto funcionó para mí. Creé una clase personalizada que anula el CSS necesario.

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

ingrese la descripción de la imagen aquí

El -webkit-box-shadow funcionará para los navegadores Chrome y safari.

men_aka
fuente
funciona para mí pero tuve que quitar el border: none !important;botón para mantener las mismas dimensiones
Emeka Mbah
1
Estaba buscando eliminar onClick focus, las respuestas anteriores no funcionaron pero "box-shadow: none! Important;" su trabajo para mí gracias @Menaka
Zaif Warm
11

Esto funciona para mí, otra solución no mencionada. Solo tíralo en el evento de clic ...

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

O llámalo desde otro evento / método ...

$(".btn_name").trigger("blur");
Robar
fuente
El problema con esto es que cuando un usuario del teclado "hace clic" en el botón (al enfocarlo y luego presionar la barra espaciadora) pierde el foco. Luego debes volver a pestañas dondequiera que estuvieras. 😡
Tamlyn
8

Si usa la regla :focus { outline: none; }para eliminar contornos, el enlace o el control serán enfocables pero sin indicación de enfoque para los usuarios del teclado. Los métodos para eliminarlo con JS como onfocus="blur()"son aún peores y provocarán que los usuarios del teclado no puedan interactuar con el control.

Los hacks que puedes usar, que están bastante bien , incluyen agregar :focus { outline: none; }reglas cuando los usuarios interactúan con el mouse y eliminarlas nuevamente si se detecta interacción con el teclado. Lindsay Evans ha creado una biblioteca para esto: https://github.com/lindsayevans/outline.js

Pero preferiría configurar una clase en la etiqueta html o body. Y tenga control en el archivo CSS de cuándo usar esto.

Por ejemplo (los controladores de eventos en línea son solo para fines de demostración):

<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>

Puse juntos una pluma: http://codepen.io/snobojohan/pen/RWXXmp

Pero cuidado, hay problemas de rendimiento. Esto obliga a volver a pintar cada vez que el usuario cambia entre el mouse y el teclado. Más información sobre cómo evitar pinturas innecesarias http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/

snobojohan
fuente
6

He notado lo mismo y, aunque realmente me molesta, creo que no hay una forma adecuada de manejar esto.

Recomendaría contra todas las otras soluciones dadas porque eliminan la accesibilidad del botón por completo, por lo que ahora, cuando presionas el botón, no obtendrás el enfoque esperado.

Esto debe ser evitado!

.btn:focus {
  outline: none;
}
Oscar Bolaños
fuente
No creo que esto esté mal, porque todavía tienes un botón de relámpago ligeramente diferente cuando estás enfocado, por lo que incluso los usuarios de teclados pueden reconocerlo. Pero esto no es suficiente, porque todavía obtendrá un marco de borde cuando presione y mantenga presionado el botón izquierdo del mouse
apocalypz
6

Encuentro una solución. cuando nos enfocamos, bootstrap usa box-shadow, así que simplemente lo deshabilitamos (no hay suficiente reputación, no se puede cargar la imagen :().

añado

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

funciona.

caramelo
fuente
6

OPCIÓN 1: usar la :focus-visiblepseudoclase

La :focus-visiblepseudoclase se puede usar para eliminar los contornos antiestéticos y los anillos de enfoque en los botones y diversos elementos para los usuarios que NO navegan a través del teclado (es decir, mediante el toque o el clic del 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;
}

Advertencia: a partir de 2020, la :focus-visiblepseudoclase no es ampliamente compatible en todos los navegadores . Sin embargo, el polyfill es muy fácil de usar; Vea las instrucciones a continuación.


OPCIÓN 2: usar el .focus-visiblepolyfill

Esta solución utiliza una clase CSS normal en lugar de la pseudoclase mencionada anteriormente, y tiene un amplio soporte de navegador porque es un polyfill oficial basado en Javascript .

Paso 1: Agregue las dependencias de Javascript a su página HTML

Nota: el polyfill visible al foco requiere un polyfill adicional para varios navegadores antiguos que no admiten 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>

Paso 2: agrega el siguiente CSS a tu hoja de estilo

La siguiente es una versión modificada de la solución CSS documentada más detalladamente arriba.

/**
 * 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;
}

Paso 3 (opcional): use la clase 'focus-visible' cuando sea necesario

Si tiene algún elemento en el que realmente desea mostrar el anillo de enfoque cuando alguien hace clic o usa el tacto, simplemente agregue la focus-visibleclase al 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:

Manifestación:

JamesWilson
fuente
Pero si incluso Chrome aún no lo admite, probablemente no sea la mejor solución (por ahora)
Elijah Mock
¿Qué sugieres en su lugar?
JamesWilson
Oculte el esquema como dicen las otras respuestas hasta que esta solución esté más estandarizada
Elijah Mock
Según mi lectura de las cosas, si la accesibilidad es una preocupación, ocultar el esquema con carta blanca <whatever>:focus { outline: none }es una idea peor que esta solución. En realidad, hay personas en la comunidad de accesibilidad que preferirían que NUNCA elimine el contorno y, en cambio, haga que todo tenga un estilo de enfoque (ya sea contorno o recuadro), y no quiera admitir: visible-foco hasta que los navegadores implementen una forma de permitir los usuarios especifican una preferencia del usuario sobre si todos los elementos deben ser enfocables o no. Me gusta pensar: focus-visible es un medio feliz entre las preocupaciones de diseño y todas las preguntas.
JamesWilson
5

Si lo anterior no funciona para usted, intente esto:

.btn: focus {outline: none; box-shadow: none; border: 2px solid transparent;}

Como señaló user1933897, esto podría ser específico para MacOS con Chrome.

alns
fuente
Aún así, esto es válido cuando se usa bootstrap 4.0- en Windows
3gwebtrain
5

Tarde, pero quién sabe puede ayudar a alguien. El CSS se vería así:

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

El HTML se vería así:

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

De esta manera puede mantener btn y sus comportamientos asociados.

Stephanie Wyche
fuente
1
element:focus { box-shadow: none; }Se eliminó el contorno azul / sombra.
user435421
3

Mencioné esto en un comentario anterior, pero vale la pena incluirlo como una respuesta separada para mayor claridad. Mientras no necesite enfocarse en el botón, puede usar el evento de foco para eliminarlo antes de que pueda aplicar cualquier efecto CSS:

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

Esto evita el parpadeo que se puede ver al usar el evento click. Esto restringe la interfaz y no podrá presionar el botón, pero eso no es un problema en todas las aplicaciones.

Charles
fuente
Esto hizo la mitad del truco para mí. Estoy usando React y React-Bootstrap. Después de hacer clic, el botón permanecía resaltado con un brillo alrededor de esto. Agregando e.target.blur (); elimina el brillo, pero el botón mantiene un color diferente.
pixelwiz
3

Estilo

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

Utilizando

<button class="btn btn-primary not-focusable">My Button</button>
Bogdan Kanteruk
fuente
¿Cómo es esta solución diferente de las otras respuestas?
apaul
2
Sólo hay una diferencia un poco - se puede quitar el foco de los elementos que necesita con la especificación de la clase "no-enfocable" sin anular el comportamiento de todos los botones, enlaces, etc.
Bogdan Kanteruk
3

Pruebe esta solución para eliminar el borde alrededor del botón. Agregue este código en css.

Tratar

button:focus{
outline:0px;
}

Si no funciona, use a continuación.

button:focus{
 outline:none !important;
 }
Rana Aalamgeer
fuente
El segundo funciona incluso con el botón React Material UI
Geek Guy
3

Para las personas que desean una forma css pura de hacer eso:

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

Esto también podría funcionar para el enlace, etc., y además, mantiene las accesibilidades del teclado. Por último, es ignorado por los navegadores que no admiten: foco visible

Martin pedros
fuente
44
Esto solo funcionará en Chrome con características experimentales habilitadas, según developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
Justin Kahn
focus-visibleahora tiene un polyfill oficial. Mi respuesta stackoverflow.com/a/60219624/413538 sobre esta pregunta explica cómo entender realmente todo esto.
JamesWilson
2

Estábamos sufriendo un problema similar y notamos que Bootstrap 3 no tiene el problema en sus pestañas (en Chrome). Parece que están usando un estilo de esquema que permite al navegador decidir qué hacer mejor y Chrome parece hacer lo que desea: mostrar el esquema cuando está enfocado a menos que haga clic en el elemento.

El soporte para outline-stylees difícil de precisar ya que el navegador decide qué significa eso. Lo mejor es revisar algunos navegadores y tener una regla alternativa.

TeknoFiend
fuente
2

Otra posible solución es agregar una clase usando un escucha de Javascript cuando el usuario hace clic en el botón y luego eliminar esa clase en foco con otro escucha. Esto mantiene la accesibilidad (tabulación visible) al tiempo que evita el comportamiento peculiar de Chrome de considerar un botón enfocado al hacer clic.

JS:

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

CSS:

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

Ejemplo completo aquí: https://jsfiddle.net/4bbb37fh/

Seb Woolford
fuente
Use mouseDown en lugar de hacer clic. Al hacer clic, el contorno aparece mientras se presiona el mouse (sin soltarlo) inicial.
Vincent Hoch-Drei
2

Es trabajo, espero ayudarte

.btn:focus, .btn:focus:active {
    outline: none;
}
Дмитрий Будницкий
fuente
.btn: el foco debe tener el esquema de accesibilidad (al tabular)
yennefer
2
.btn:focus:active {
  outline: none;
}

esto elimina el contorno al hacer clic, pero mantiene el foco al tabular (por un año)

Yennefer
fuente
Esto solo elimina el contorno del mouse hacia abajo. Después de mover el mouse, aparece el contorno.
Wellspring
2

Esto funciona mejor

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

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

este esquema: ninguno funcionará tanto para el botón como para una etiqueta

Milan Panigrahi
fuente
¿Cómo responde esto a la pregunta? Por favor agregue algo de explicación.
André Kool
1

Agregue esto en CSS:

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

Encontré una solución, simplemente agregue la siguiente línea en su código CSS.

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

Acabo de tener este mismo problema en MacOS y Chrome mientras usaba un botón para activar un evento de "transición". Si alguien que lee esto ya está utilizando un detector de eventos, puede resolverlo llamando .blur()después de sus acciones.

Ejemplo:

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

Aunque si aún no está utilizando un detector de eventos, agregar uno solo para resolver esto podría agregar una sobrecarga innecesaria y una solución de estilo como las respuestas anteriores proporcionan es mejor.

jospablos
fuente
0

Puedes configurar tabIndex="-1". Hará que el navegador omita este botón cuando presione TAB a través de controles enfocables.

Otras "soluciones" sugeridas aquí, solo eliminan el contorno del foco, pero aún dejan los botones tabulables. Sin embargo, desde el punto de vista de la usabilidad, ya eliminó el brillo, por lo que su usuario no sabrá qué es el botón enfocado actualmente, de ninguna manera.

Por otro lado, hacer que el botón no se pueda tabular tiene implicaciones de accesibilidad.

Lo estoy usando para eliminar el contorno del foco del botón X bootstrap modal, que tiene el botón duplicado "Cerrar" en la parte inferior de cualquier manera, por lo que mi solución no tiene ningún impacto en la accesibilidad.

zmechanic
fuente
0

Si está utilizando un navegador webkit (y potencialmente un navegador compatible con el prefijo del proveedor de webkit), ese esquema pertenece a la -webkit-focus-ringpseudoclase del botón . Simplemente configúrelo outlinepara none:

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

Chrome es un navegador webkit, y este efecto también ocurre en Linux (no solo en MacOS, aunque algunos estilos de Chrome son solo macOS)

Nate Symer
fuente
0

Estaba teniendo el mismo problema al usar la <a>función de botón y descubrí que me faltaba una solución alternativa al agregar attr type="button"hace que se comporte normalmente al menos para mí.

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

spcsLrg
fuente
El typeatributo no debería tener ningún efecto sobre esto y buttones un valor no válido para él. El atributo acepta un tipo MIME y le dice al cliente qué tipo de datos debería esperar obtener si sigue el enlace (por ejemplo <a type="application/pdf" ...>.
Quentin
@Quentin Gracias. Sí, soy consciente de ello. Comencé con role="button"pero simplemente no funcionó (después de usar un en <button>lugar de <a>). Mi implementación exigió específicamente un <a>y no <button>. Entonces, después de jugar mucho, ¡descubrí esta solución (probablemente un error BS)!
spcsLrg
0

directamente en la etiqueta html (en un escenario en el que es posible que desee dejar el tema bootstrap en otro lugar de su diseño).

ejemplos para probar ..

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

..ect. dependiendo del efecto deseado.

Ninguno
fuente