Como desativar o realce de seleção de texto?

Para âncoras que agem como botões (por exemplo, Perguntas , Marcas , Usuários , etc. na parte superior da página Estouro de pilha) ou guias, existe uma maneira padrão CSS de desabilitar o efeito de destaque se o usuário acidentalmente seleciona o texto?

Eu percebo que isso poderia ser feito com JavaScript, e um pouco de googling rendeu a opção Mozilla-only -moz-user-select .

Existe uma maneira padrão de realizar isso com CSS, e se não, qual é a abordagem de “melhor prática”?

    ATUALIZAÇÃO Janeiro de 2017:

    De acordo com Posso usar , a user-select é atualmente suportada em todos os navegadores, exceto o Internet Explorer 9 e versões anteriores (mas, infelizmente, ainda precisa de um prefixo de fornecedor).


    Todas as variações CSS corretas são:

     .noselect { -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */ } 
     

    Selectable text.

    Unselectable text.

    Na maioria dos navegadores, isso pode ser obtido usando variações proprietárias na propriedade de user-select do CSS, originalmente proposta e, em seguida, abandonada no CSS3 e agora proposta no nível de interface de usuário do CSS 4 :

     *.unselectable { -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; /* Introduced in IE 10. See http://ie.microsoft.com/testdrive/HTML5/msUserSelect/ */ -ms-user-select: none; user-select: none; } 

    Para IE <10 e Opera <15, você precisará usar o atributo unselectable do elemento que você deseja não ser selecionável. Você pode definir isso usando um atributo em HTML:

     
    ...

    Infelizmente essa propriedade não é herdada, o que significa que você precisa colocar um atributo na tag de início de cada elemento dentro do

    . Se isso for um problema, você poderia usar o JavaScript para fazer isso recursivamente para os descendentes de um elemento:

     function makeUnselectable(node) { if (node.nodeType == 1) { node.setAttribute("unselectable", "on"); } var child = node.firstChild; while (child) { makeUnselectable(child); child = child.nextSibling; } } makeUnselectable(document.getElementById("foo")); 

    Atualização de 30 de abril de 2014 : Esta passagem de tree precisa ser reexecutada sempre que um novo elemento é adicionado à tree, mas parece que a partir de um comentário de @Han é possível evitar isso adicionando um manipulador de events mousedown que define unselectableunselectable em o alvo do evento. Veja http://jsbin.com/yagekiji/1 para detalhes.


    Isso ainda não cobre todas as possibilidades. Embora seja impossível iniciar seleções em elementos não selecionados, em alguns navegadores (IE e Firefox, por exemplo), ainda é impossível impedir que as seleções sejam iniciadas antes e depois do elemento não selecionável, sem tornar todo o documento não selecionável.

    Uma solução JavaScript para o IE é

     onselectstart="return false;" 

    Até que a propriedade de seleção de usuário do CSS 3 seja disponibilizada, os navegadores baseados no Gecko suportam a -moz-user-select você já encontrou. Os navegadores baseados em WebKit e Blink suportam a propriedade -webkit-user-select .

    Isso obviamente não é suportado em navegadores que não usam o mecanismo de renderização Gecko.

    Não existe uma maneira rápida e fácil de cumprir os “padrões”; usar JavaScript é uma opção.

    A verdadeira questão é, por que você quer que os usuários não sejam capazes de destacar e, presumivelmente, copiar e colar certos elementos? Não me deparei com uma única vez que eu quisesse não permitir que os usuários destacassem uma determinada parte do meu site. Vários dos meus amigos, depois de passarem muitas horas lendo e escrevendo código, usam o recurso de destaque como uma maneira de lembrar onde estavam na página, ou fornecer um marcador para que seus olhos saibam onde procurar em seguida.

    O único lugar que eu poderia ver isso sendo útil é se você tiver botões para formulários que não devem ser copiados e colados se um usuário copiar e colar o site.

    Se você quiser desabilitar a seleção de texto em tudo, exceto nos elementos

    , você pode fazer isso em CSS (cuidado com o -moz-none que permite replace em subelementos, o que é permitido em outros navegadores sem none ):

     * { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: -moz-none; -o-user-select: none; user-select: none; } p { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -o-user-select: text; user-select: text; } 

    Nas soluções acima, a seleção é interrompida, mas o usuário ainda acha que você pode selecionar o texto porque o cursor ainda muda. Para mantê-lo estático, você terá que definir o seu cursor CSS:

     .noselect { cursor: default; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } 
     

    Selectable text.

    Unselectable text.

    Você pode fazer isso no Firefox e no Safari (o Chrome também?)

     ::selection { background: transparent; } ::-moz-selection { background: transparent; } 

    Solução alternativa para o WebKit :

     /* Disable tap highlighting */ -webkit-tap-highlight-color: rgba(0,0,0,0); 

    Eu encontrei em um exemplo CardFlip.

    Eu gosto da solução híbrida CSS + jQuery.

    Para tornar todos os elementos dentro

    não selecionável, use este CSS:

     .draggable { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -o-user-select: none; -ms-user-select: none; user-select: none; } .draggable input { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -o-user-select: text; user-select: text; } 

    E então, se você estiver usando jQuery, adicione isso dentro de um bloco $(document).ready() :

     if (($.browser.msie && $.browser.version < 10) || $.browser.opera) $('.draggable').find(':not(input)').attr('unselectable', 'on'); 

    Eu acho que você ainda quer que qualquer elemento de input seja interativo, daí o pseudo-seletor :not() . Você poderia usar '*' se não se importasse.

    Ressalva: o IE9 pode não precisar dessa peça extra do jQuery, portanto, você pode querer adicionar uma verificação de versão lá.

     .hidden:after { content: attr(data-txt); } 
      

    Para o Internet Explorer, além disso, você precisa adicionar um foco de pseudo-class (.ClassName: focus) e um estilo de estrutura de tópicos: none .

     .ClassName, .ClassName:focus { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; outline-style:none;/*IE*/ } 

    Trabalhando

    CSS:

      -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-user-select: none; 

    Isso deve estar funcionando, mas não funcionará para os navegadores antigos. Existe um problema de compatibilidade do navegador.

    Para aqueles que têm dificuldade em alcançar o mesmo no navegador Android com o evento de toque, use:

     html,body{ -webkit-touch-callout: none; -webkit-user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; } 
     -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -o-user-select: none; user-select: none; *.unselectable { -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none; user-select: none; } 
     
    ...
     function makeUnselectable(node) { if (node.nodeType == 1) { node.unselectable = true; } var child = node.firstChild; while (child) { makeUnselectable(child); child = child.nextSibling; } } makeUnselectable(document.getElementById("foo")); 
     -webkit-user-select:none; -moz-user-select:none; 
     onselectstart="return false;" 
     ::selection { background: transparent; } ::-moz-selection { background: transparent; } * { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: -moz-none; -o-user-select: none; user-select: none; } p { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -o-user-select: text; user-select: text; } 
     
     .draggable { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -o-user-select: none; user-select: none; } .draggable input { -webkit-user-select: text; -khtml-user-select: text; -moz-user-select: text; -o-user-select: text; user-select: text; } 
     if ($.browser.msie) $('.draggable').find(':not(input)').attr('unselectable', 'on'); 

    Você pode usar CSS ou JavaScript para isso, a forma JavaScript é suportada em navegadores mais antigos, como o Old IEs também, mas se não for o seu caso, use o modo CSS então:

    HTML / JavaScript:

       

    This is the Heading!

    And I'm the text, I won't be selected if you select me.

    Se você estiver usando menos e Bootstrap você pode escrever:

     .user-select(none); 

    Além da propriedade somente do Mozilla, não, não há como desativar a seleção de texto com apenas CSS padrão (a partir de agora).

    Se você perceber, o Stack Overflow não desativa a seleção de texto para seus botões de navegação, e eu recomendaria contra fazê-lo na maioria dos casos, uma vez que modifica o comportamento de seleção normal e o faz conflitar com as expectativas do usuário.

    Isso funciona em alguns navegadores:

     ::selection{ background-color: transparent;} ::moz-selection{ background-color: transparent;} ::webkit-selection{ background-color: transparent;} 

    Simplesmente adicione seus elementos / ids desejados na frente dos seletores separados por vírgulas sem espaços, assim:

     h1::selection,h2::selection,h3::selection,p::selection{ background-color: transparent;} h1::moz-selection,h2::moz-selection,h3::moz-selection,p::moz-selection{ background-color: transparent;} h1::webkit-selection,h2::webkit-selection,h3::webkit-selection,p::webkit-selection{ background-color: transparent;} 

    As outras respostas são melhores; isso provavelmente deve ser visto como um último recurso / catchall.

    Suponha que existam dois div assim

     .second { cursor: default; user-select: none; -webkit-user-select: none; /* Chrome/Safari/Opera */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* IE/Edge */ -webkit-touch-callout: none; /* iOS Safari */ } 
     
    This is my first div
    This is my second div

    NOTA:

    A resposta correta está correta, pois impede que você possa selecionar o texto. No entanto, isso não impede que você possa copiar o texto, como mostrarei nas próximas capturas de canvas (a partir de 7 de novembro de 2014).

    Antes de termos selecionado alguma coisa

    Depois de termos selecionado

    Os números foram copiados

    Como você pode ver, não conseguimos selecionar os números, mas conseguimos copiá-los.

    Testado em: Ubuntu , Google Chrome 38.0.2125.111.

    Adicione isto ao primeiro div no qual você deseja desabilitar a seleção para o texto:

     onmousedown='return false;' onselectstart='return false;' 

    Isso será útil se a seleção de colors também não for necessária:

     ::-moz-selection { background:none; color:none; } ::selection { background:none; color:none; } 

    … todas as outras correções do navegador. Ele funcionará no Internet Explorer 9 ou posterior.

    Para obter o resultado necessário, descobri que precisava usar os dois ::selection e user-select

     input.no-select:focus { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } input.no-select::selection { background: transparent; } input.no-select::-moz-selection { background: transparent; } 

    Isto não é CSS, mas vale a pena mencionar:

    jQuery UI Desativar seleção :

     $("your.selector").disableSelection(); 

    Embora esse pseudoelemento estivesse em rascunhos de Seletores de CSS de Nível 3, ele foi removido durante a fase de Recomendação de Candidato, pois parecia que seu comportamento estava abaixo do especificado, especialmente com elementos nesteds, e a interoperabilidade não foi alcançada.

    Está sendo discutido em How :: selection funciona em elementos nesteds .

    Apesar de estar sendo implementado no navegador, você pode criar uma ilusão de que o texto não está sendo selecionado usando a mesma cor e cor de fundo na seleção do design da guia (no seu caso).

    Design normal de CSS

     p { color: white; background: black; } 

    Na seleção

     p::-moz-selection { color: white; background: black; } p::selection { color: white; background: black; } 

    Não permitir que os usuários selecionem o texto aumentará os problemas de usabilidade.

    Verifique minha solução sem JavaScript:

    jsFiddle

     li:hover { background-color: silver; } #id1:before { content: "File"; } #id2:before { content: "Edit"; } #id3:before { content: "View"; } 
     

    Eu aprendi no site CSS-Tricks .

     user-select: none; 

    E isso também:

     ::selection{ background-color: transparent;} ::moz-selection{ background-color: transparent;} ::webkit-selection{ background-color: transparent;} 

    Atualização rápida de hack: março de 2017 – a partir de CSS-Tricks

    Se você colocar o valor ‘none’ para todos os atributos de seleção de usuário do CSS, conforme mostrado abaixo, há um problema que ainda pode ocorrer com isso.

     .div{ -webkit-user-select: none; /* Chrome all / Safari all */ -moz-user-select: none; /* Firefox all */ -ms-user-select: none; /* IE 10+ */ user-select: none; /* Likely future */ } 

    Como o CSS-Trick diz que os problemas são

    • O WebKit ainda permite que o texto seja copiado se você selecionar elementos em torno dele.

    Então você também pode usar o abaixo para reforçar que um elemento inteiro seja selecionado, que é a solução para o problema. Tudo o que você precisa fazer é alterar o valor ‘none’ para ‘all’, o que seria semelhante a este

     .force-select { -webkit-user-select: all; /* Chrome 49+ */ -moz-user-select: all; /* Firefox 43+ */ -ms-user-select: all; /* No support yet */ user-select: all; /* Likely future */ } 
      -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; 

    Tente usar este:

     ::selection { background: transparent; } 

    E se você deseja especificar não selecionar dentro de um elemento específico, basta colocar a class ou id do elemento antes da regra de seleção, como:

     .ClassNAME::selection { background: transparent; } #IdNAME::selection { background: transparent; }