Eu criei um carrossel com um botão anterior e um próximo que estão sempre visíveis. Esses botões têm um estado de foco, eles ficam azuis. Em dispositivos sensíveis ao toque, como o iPad, o estado de foco é fixo, portanto o botão permanece azul depois de tocá-lo. Eu não quero isso
Eu poderia adicionar uma
no-hover
classeontouchend
para cada botão e criar meu CSS dessa maneira:button:not(.no-hover):hover { background-color: blue; }
mas isso provavelmente é muito ruim para o desempenho e não lida com dispositivos como o Chromebook Pixel (que possui tela sensível ao toque e mouse) corretamente.Eu poderia adicionar uma
touch
classe aodocumentElement
e fazer meu CSS assim:html:not(.touch) button:hover { background-color: blue; }
Mas isso também não funciona direito em dispositivos com toque e mouse.
O que eu preferiria é remover o estado de foco ontouchend
. Mas não parece que isso seja possível. Focar outro elemento não remove o estado de foco. Tocar em outro elemento manualmente, mas não consigo acioná-lo em JavaScript.
Todas as soluções que encontrei parecem imperfeitas. Existe uma solução perfeita?
fonte
Depois que o nível 4 das consultas de mídia CSS for implementado, você poderá fazer o seguinte:
Ou em inglês: "Se o navegador suportar pairar adequado / verdadeiro / real / não emulado (por exemplo, possui um dispositivo de entrada principal do tipo mouse), aplique esse estilo quando
button
s passar o mouse sobre".Como essa parte do nível 4 de consultas de mídia até agora só foi implementada no Chrome de ponta, escrevi um polyfill para lidar com isso. Com ele, você pode transformar o CSS futurista acima em:
(Uma variação na
.no-touch
técnica) E, em seguida, usando algum JavaScript do cliente do mesmo polyfill que detecta suporte para pairar, é possível alternar a presença damy-true-hover
classe de acordo:fonte
Este é um problema comum, sem solução perfeita. O comportamento de passar o mouse é útil com o mouse e, principalmente, prejudicial ao toque. Para agravar o problema, existem dispositivos compatíveis com toque e mouse (simultaneamente, nada menos!), Como o Chromebook Pixel e o Surface.
A solução mais limpa que encontrei é ativar o comportamento de pairar apenas se o dispositivo não suportar a entrada por toque.
Concedido, você perde o foco em dispositivos que podem suportá-lo. No entanto, algumas vezes o hover afeta mais que o próprio link, por exemplo, talvez você queira mostrar um menu quando um elemento é direcionado. Essa abordagem permite testar a existência do toque e, talvez, anexar condicionalmente um evento diferente.
Eu testei isso no iPhone, iPad, Chromebook Pixel, Surface e em uma variedade de dispositivos Android. Não posso garantir que funcione quando uma entrada de toque USB genérica (como uma caneta) for adicionada à mistura.
fonte
Com o Modernizr, você pode direcionar seus hover especificamente para dispositivos sem toque:
(Nota: isso não é executado no sistema de trechos do StackOverflow, verifique o jsfiddle )
Observe que
:active
não precisa ser segmentado.no-touch
porque funciona conforme o esperado em dispositivos móveis e computadores.fonte
.no-touch
estiver presente nahtml
tag. Caso contrário, esta resposta recebe meu selo de aprovação.Você pode substituir o efeito de focalização para dispositivos que não suportam a focalização. Gostar:
Testado e verificado no iOS 12
Dica para https://stackoverflow.com/a/50285058/178959 para apontar isso.
fonte
fonte
De quatro maneiras de lidar com o foco instantâneo no celular : Aqui está uma maneira de adicionar ou remover dinamicamente uma
can touch
classe " " do documento com base no tipo de entrada atual do usuário. Também funciona com dispositivos híbridos, nos quais o usuário pode alternar entre o toque e um mouse / trackpad:fonte
Eu ia postar minha própria solução, mas, verificando se alguém já a postou, descobri que o @Rodney quase o fez. No entanto, ele perdeu uma última decisão crucial que a tornou sem sentido, pelo menos no meu caso. Quero dizer, eu também fiz a mesma
.fakeHover
adição / remoção de classe viamouseenter
emouseleave
detecção de eventos, mas só isso, por si só , funciona quase exatamente como "genuíno":hover
. Quero dizer: quando você toca em um elemento da sua tabela, ele não detecta que você o "deixou" - mantendo assim o estado "fakehover".O que eu fiz foi simplesmente ouvir
click
também, então, quando "toco" o botão, eu aciono manualmente amouseleave
.Si este é o meu código final:
Dessa forma, você mantém sua
hover
funcionalidade usual ao usar o mouse, simplesmente "pairando" nos botões. Bem, quase tudo: a única desvantagem é que, depois de clicar no botão com o mouse, ele não estará emhover
estado. É como se você clicasse e rapidamente retirasse o ponteiro do botão. Mas no meu caso eu posso viver com isso.fonte
Isso é o que eu venho até agora depois de estudar o restante das respostas. Ele deve ser capaz de oferecer suporte a usuários híbridos, apenas com toque, somente mouse.
Crie uma classe de foco separado para o efeito de foco. Por padrão, adicione essa classe de foco ao nosso botão.
Não queremos detectar a presença de suporte por toque e desativar todos os efeitos de foco instantâneo desde o início. Como mencionado por outros, os dispositivos híbridos estão ganhando popularidade; as pessoas podem ter suporte ao toque, mas desejam usar o mouse e vice-versa. Portanto, remova a classe de foco apenas quando o usuário realmente tocar no botão.
O próximo problema é: e se o usuário quiser voltar a usar o mouse depois de tocar no botão? Para resolver isso, precisamos encontrar um momento oportuno para adicionar de volta a classe hover que removemos.
No entanto, não podemos adicioná-lo de volta imediatamente após removê-lo, porque o estado de foco ainda está ativo. Podemos não querer destruir e recriar o botão inteiro também.
Então, pensei em usar um algoritmo de espera ocupada (usando setInterval) para verificar o estado de foco. Depois que o estado de foco é desativado, podemos adicionar novamente a classe de foco e interromper a espera ocupada, retornando ao estado original em que o usuário pode usar o mouse ou o toque.
Sei que esperar muito ocupado não é tão bom, mas não tenho certeza se há um evento apropriado. Eu considerei adicioná-lo novamente no evento mouseleave, mas não foi muito robusto. Por exemplo, quando um alerta é exibido depois que o botão é tocado, a posição do mouse muda, mas o evento do mouse não é acionado.
Edit: Outra abordagem que tentei é chamar
e.preventDefault()
no ontouchstart ou ontouchend. Parece interromper o efeito de foco quando o botão é tocado, mas também interrompe a animação do clique no botão e evita que a função onclick seja chamada quando o botão é tocado, para que você precise chamá-los manualmente no manipulador ontouchstart ou ontouchend. Não é uma solução muito limpa.fonte
Foi útil para mim: link
fonte
Adicione este código JS à sua página:
agora em seu CSS antes de cada foco, adicione a classe foco assim:
Se o dispositivo for sensível ao toque, a classe do corpo estará vazia; caso contrário, sua classe ficará suspensa e as regras serão aplicadas!
fonte
document.body.className = 'ontouchstart' in window ? '' : 'hover';
Este é o ponto de partida certo. Próxima etapa: aplicar / remover a classe nohover nos seguintes eventos (demo com jQuery)
Aviso: Se você deseja aplicar outras classes ao elemento button, o: not (.nohover) no CSS não funcionará mais conforme o esperado. Em vez disso, é necessário adicionar uma definição separada com valor padrão e uma tag! Important para substituir o estilo de foco: .nohover {background-color: white! Important}
Isso deve até manipular dispositivos como o Chromebook Pixel (que possui tela sensível ao toque e mouse) corretamente! E eu não acho que esse seja um grande assassino de desempenho ...
fonte
Uma solução que funcionou para mim:
Adicione esse código à sua folha de estilo.
Eu queria me livrar do fundo cinza que aparece no iOS Safari quando um link é clicado. Mas parece fazer mais. Agora, clicando em um botão (com um
:hover
pseudoclasse!) É aberto imediatamente! Só testei em um iPad, não sei se funcionará em outros dispositivos.fonte
Acho que encontrei uma solução elegante (js mínima) para um problema semelhante:
Usando o jQuery, você pode ativar o foco no corpo (ou qualquer outro elemento), usando
.mouseover()
Então, simplesmente anexo um manipulador this ao
ontouchend
evento do elemento da seguinte maneira:No entanto, isso remove apenas: pseudoclasse suspenso do elemento depois que algum outro evento de toque foi acionado, como furto ou outro toque
fonte
Eu tenho uma boa solução que eu gostaria de compartilhar. Primeiro, você precisa detectar se o usuário está no celular assim:
Em seguida, basta adicionar:
E em CSS:
fonte
Passei pelo problema semelhante, meu aplicativo era compatível com todos os tamanhos de tela e tinha muitos efeitos de foco nos dispositivos baseados no tamanho da tela da área de trabalho / mouse, e mais tarde percebi que os dispositivos baseados em toque estavam causando uma condição conhecida como pegajosa -hover e foi um obstáculo para o aplicativo funcionar corretamente para usuários de dispositivos baseados em toque.
Estávamos fazendo uso do SCSS em nosso aplicativo. e eu defini um mixin para cuidar do dispositivo baseado em toque.
e, em seguida, coloquei todas as minhas aulas de css no snippet mencionado abaixo.
Por exemplo, tínhamos uma classe para animar um ícone, que costumava ser acionada quando passamos o mouse sobre o ícone, como você pode vê-lo no CSS, mas no dispositivo baseado em toque, ele era afetado pelo efeito de foco pegajoso e o colocava dentro de @ inclua hover-support () para garantir que o hover se aplique apenas aos dispositivos que suportam o hover.
fonte
Aqui está um código JavaScript simples que não requer que o desenvolvedor edite CSS ou escreva novas regras CSS. Eu escrevi isso para os botões do Bootstrap com
class="btn"
, mas funcionará com qualquer botão que tenha um nome de classe específico.Os passos são:
document.styleSheets
.btn
e:hover
A eliminação de todas as
.btn :hover
regras de CSS garante que não haverá efeito de foco visual em um botão.Etapa 1: detectar o dispositivo de toque
Verifique a consulta de mídia quanto à presença de
(hover: none)
:Etapa 2: Excluir regras CSS contendo `btn` e`: hover`
O código completo está no GitHub e npm .
Demonstração ao vivo em terrymorse.com .
fonte
@media (hover:none)
ou quando o usuário tocar pela primeira vez na tela. Você pode experimentá-lo na página de demonstração ao vivo para ter certeza.Você pode definir a cor de fundo no
:active
estado e fornecer:focus
o plano de fundo padrão.se você definir a cor de fundo como
onfocus/ontouch
, o estilo de cor permanecerá assim que o:focus
estado acabar.Você precisa redefinir
onblur
também para restaurar a defaut bg quando o foco for perdido.fonte
Isso funcionou para mim: coloque o estilo de foco instantâneo em uma nova classe
Em seguida, adicione / remova a classe como e quando necessário
Repita para os eventos touchstart e touchend. Ou os eventos que você deseja obter o resultado desejado, por exemplo, eu queria que o efeito de foco fosse alternado em uma tela de toque.
fonte
Com base na resposta de Darren Cooks, que também funciona se você mover o dedo sobre outro elemento.
Consulte O elemento Localizar dedo está ativado durante um evento de toque final
Codepen Demo
fonte
Você pode tentar assim.
javascript:
css:
fonte
O que fiz até agora em meus projetos foi reverter as
:hover
alterações nos dispositivos de toque:Todos os nomes de classe e cores nomeadas apenas para fins de demonstração ;-)
fonte
Isso funciona perfeitamente em 2 etapas.
Defina sua etiqueta corporal para ser assim
<body ontouchstart="">
. Não sou fã desse "hack", mas permite que o Safari no iOS reaja aos toques instantaneamente. Não sei como, mas funciona.Configure sua classe palpável assim:
Você também pode remover qualquer animação da sua classe tocável. O Android Chrome parece um pouco mais lento que o iOS.
Isso também resultará na aplicação do estado ativo se o usuário rolar a página enquanto toca na sua turma.
fonte
Alguns dos
:hover
:focus
:active
problemas persistentes em dispositivos móveis podem ser causados por falta de ação,<meta name="viewport" content="width=device-width">
pois os navegadores tentam manipular a tela.fonte
A solução para mim foi depois que o touchend foi clonar e substituir o nó ... eu odeio fazer isso, mas até tentando repintar o elemento com offsetHeight não estava funcionando
fonte
Isso pode ser feito trocando uma classe HTML. Deve ser menos propenso a falhas do que remover todo o elemento, especialmente com links de imagens grandes etc.
Também podemos decidir se queremos que os estados de foco sejam acionados ao rolar com toque (touchmove) ou até mesmo adicionar um tempo limite para atrasá-los.
A única mudança significativa em nosso código será usar classe HTML adicional, como
<a class='hover'></a>
nos elementos que implementam o novo comportamento.HTML
CSS
JS (com jQuery)
Exemplo
https://codepen.io/mattrcouk/pen/VweajZv
-
Não tenho nenhum dispositivo com o mouse e o toque para testá-lo corretamente.
fonte
A partir de 2020, você pode adicionar estilos de foco dentro da consulta de mídia
Essa consulta de mídia indica que os estilos funcionarão em navegadores que não emulam: passe o mouse para que NÃO funcione em navegadores de toque.
fonte