Как отключить подсветку выделения текста?
Для якорей, которые действуют как кнопки (например, " Вопросы", " Теги", " Пользователи" и т. Д. В верхней части страницы "Переполнение стека") или вкладок, существует ли стандартный CSS-способ для отключения эффекта выделения, если пользователь случайно выбрал текст?
Я понимаю, что это можно сделать с помощью JavaScript, и небольшое прибегание к поиску принесло только Mozilla -moz-user-select
вариант.
Существует ли совместимый со стандартами способ сделать это с помощью CSS, и если нет, то каков подход "наилучшей практики"?
53 ответа
ОБНОВЛЕНИЕ Январь 2017 года:
Согласно я могу использовать, user-select
в настоящее время поддерживается во всех браузерах, кроме Internet Explorer 9 и более ранних версий (но, к сожалению, все еще нужен префикс поставщика).
Все правильные варианты CSS:
.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 */
}
<p>
Selectable text.
</p>
<p class="noselect">
Unselectable text.
</p>
Обратите внимание, что это нестандартная функция (т.е. не является частью какой-либо спецификации). Не гарантируется, что он будет работать везде, и в браузерах могут быть различия в реализации, и в будущем браузеры могут отказаться от его поддержки.
Дополнительную информацию можно найти в документации по Mozilla Developer Network.
В большинстве браузеров это может быть достигнуто с помощью собственных изменений CSS user-select
свойство, первоначально предложенное, а затем оставленное в CSS3, а теперь предложенное в CSS UI Level 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;
}
Для IE < 10 и Opera < 15 вам нужно будет использовать unselectable
Атрибут элемента, который вы хотите, чтобы быть недоступным для выбора. Вы можете установить это, используя атрибут в HTML:
<div id="foo" unselectable="on" class="unselectable">...</div>
К сожалению, это свойство не наследуется, то есть вы должны поместить атрибут в начальный тег каждого элемента внутри <div>
, Если это проблема, вы можете вместо этого использовать JavaScript, чтобы сделать это рекурсивно для потомков элемента:
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"));
Обновление от 30 апреля 2014 года. Этот обход дерева необходимо повторять всякий раз, когда в него добавляется новый элемент, но из комментария @Han видно, что этого можно избежать, добавив mousedown
обработчик событий, который устанавливает unselectable
на цель мероприятия. Смотрите http://jsbin.com/yagekiji/1 для деталей.
Это все еще не охватывает все возможности. Хотя невозможно инициировать выборки в невыбираемых элементах, в некоторых браузерах (например, IE и Firefox) все еще невозможно предотвратить выборки, которые начинаются до и заканчиваются после невыбираемого элемента, не делая весь документ недоступным для выбора.
Пока свойство CSS 3 user-select не станет доступным, браузеры на основе Gecko поддерживают -moz-user-select
недвижимость, которую вы уже нашли. Браузеры на базе WebKit и Blink поддерживают -webkit-user-select
имущество.
Это, конечно, не поддерживается в браузерах, которые не используют движок рендеринга Gecko.
Нет никакого простого и простого способа сделать это в соответствии со стандартами; использование JavaScript является опцией.
Реальный вопрос заключается в том, почему вы хотите, чтобы пользователи не могли выделять и предположительно копировать и вставлять определенные элементы? Я ни разу не сталкивался с тем, что хотел бы, чтобы пользователи не выделяли определенную часть моего сайта. Несколько моих друзей, потратив много часов на чтение и написание кода, будут использовать функцию выделения, чтобы запоминать, где на странице они находились, или предоставлять маркер, чтобы их глаза знали, где искать дальше.
Единственное место, где я мог бы убедиться, что это полезно, - это если у вас есть кнопки для форм, которые не следует копировать и вставлять, если пользователь копирует и вставляет веб-сайт.
Если вы хотите отключить выбор текста на все, кроме <p>
элементы, вы можете сделать это в CSS (следите за -moz-none
который позволяет переопределить в подэлементах, что разрешено в других браузерах с 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;
}
В вышеупомянутых решениях выбор остановлен, но пользователь все еще думает, что вы можете выбрать текст, потому что курсор все еще изменяется. Чтобы он оставался статичным, вам нужно установить курсор 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;
}
<p>
Selectable text.
</p>
<p class="noselect">
Unselectable text.
</p>
Это сделает ваш текст абсолютно плоским, как в настольном приложении.
Вы можете сделать это в Firefox и Safari (Chrome также?)
::selection { background: transparent; }
::-moz-selection { background: transparent; }
Обходной путь для WebKit:
/* Disable tap highlighting */
-webkit-tap-highlight-color: rgba(0,0,0,0);
Я нашел это в примере CardFlip.
Мне нравится гибридное решение CSS + jQuery.
Сделать все элементы внутри <div class="draggable"></div>
не выбирается, используйте этот 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;
}
И затем, если вы используете jQuery, добавьте это внутри $(document).ready()
блок:
if (($.browser.msie && $.browser.version < 10) || $.browser.opera) $('.draggable').find(':not(input)').attr('unselectable', 'on');
Я полагаю, что вы все еще хотите, чтобы любые элементы ввода были взаимодействующими, следовательно, :not()
псевдо-селектор. Вы могли бы использовать '*'
вместо этого, если вам все равно.
Предостережение: IE9 может не понадобиться этот дополнительный кусок jQuery, поэтому вы можете добавить туда проверку версии.
Вы можете использовать CSS или JavaScript для этого, способ JavaScript поддерживается в старых браузерах, таких как старые IE, но если это не ваш случай, используйте способ CSS:
HTML / JavaScript:
<html onselectstart='return false;'>
<body>
<h1>This is the Heading!</h1>
<p>And I'm the text, I won't be selected if you select me.</p>
</body>
</html>
HTML / CSS:
.not-selectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<body class="not-selectable">
<h1>This is the Heading!</h1>
<p>And I'm the text, I won't be selected if you select me.</p>
</body>
.hidden:after {
content: attr(data-txt);
}
<p class="hidden" data-txt="Some text you don't want to be selected"></p>
Это не самый лучший способ.
Кроме того, для Internet Explorer необходимо добавить фокус псевдокласса (.ClassName:focus) и стиль контура: нет.
.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*/
}
Попробуйте вставить эти строки в CSS и вызвать "disHighlight" в свойстве класса:
.disHighlight{
user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-webkit-touch-callout: none;
-o-user-select: none;
-moz-user-select: none;
}
Быстрое обновление хака: март 2017 года - от CSS-хитрости
Если вы установите значение "none" для всех атрибутов выбора пользователя CSS, как показано ниже, это может привести к возникновению проблемы.
.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 */
}
Как говорит CSS-Trick, проблема в том,
- WebKit по-прежнему позволяет копировать текст, если вы выбираете элементы вокруг него.
Таким образом, вы также можете использовать приведенный ниже, чтобы обеспечить выбор всего элемента, который является решением проблемы. Все, что вам нужно сделать, это изменить значение "none" на "all", которое будет выглядеть так
.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 */
}
С SASS (синтаксис SCSS)
Вы можете сделать это с помощью миксина:
// Disable selection
@mixin disable-selection {
-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 */
}
// No selectable element
.no-selectable {
@include disable-selection;
}
В теге HTML:
<div class="no-selectable">TRY TO HIGHLIGHT</div>
Попробуйте в этом CodePen.
Если вы используете автопрефиксатор, вы можете удалить другие префиксы.
Совместимость браузеров здесь.
Для тех, у кого проблемы с достижением того же в браузере Android с помощью сенсорного события, используйте:
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;
}
<div id="foo" unselectable="on" class="unselectable">...</div>
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;
}
<div class="draggable"></div>
.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');
За работой
CSS:
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
Это должно работать, но оно не будет работать для старых браузеров. Существует проблема совместимости браузера.
Кроме свойства Mozilla, нет, нет способа отключить выделение текста только стандартным CSS (на данный момент).
Если вы заметили, переполнение стека не отключает выделение текста для их кнопок навигации, и я бы рекомендовал не делать этого в большинстве случаев, так как оно изменяет нормальное поведение выделения и противоречит ожиданиям пользователя.
Это работает в некоторых браузерах:
::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}
Просто добавьте нужные элементы / идентификаторы перед селекторами, разделенными запятыми без пробелов, например:
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;}
Другие ответы лучше; это, вероятно, следует рассматривать как последнее средство / ловушку.
Предположим, есть два div, как это
.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 */
}
<div class="first">
This is my first div
</div>
<div class="second">
This is my second div
</div>
Установите курсор на значение по умолчанию, чтобы пользователь не чувствовал себя недоступным
Необходимо использовать префикс для поддержки его во всех браузерах без префикса, это может не сработать во всех ответах.
Это будет полезно, если выбор цвета также не нужен:
::-moz-selection { background:none; color:none; }
::selection { background:none; color:none; }
... все другие исправления браузера. Это будет работать в Internet Explorer 9 или более поздней версии.
Добавьте это к первому div, в котором вы хотите отключить выделение для текста:
onmousedown='return false;'
onselectstart='return false;'
НОТА:
Правильный ответ верен в том смысле, что он не позволяет вам выбрать текст. Однако это не мешает вам копировать текст, как я покажу на следующей паре снимков экрана (по состоянию на 7 ноября 2014 г.).
Как видите, мы не смогли выбрать номера, но мы смогли скопировать их.
Проверено на: Ubuntu, Google Chrome 38.0.2125.111.
Легко делается с:
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
альтернативно:
Допустим, у вас есть <h1 id="example">Hello, World!</h1>
Что вам нужно сделать, это удалить innerHTML этого h1
: в этом случае Привет, Мир. Затем вам нужно будет перейти к CSS и сделать это:
#example::before //You can ofc use **::after** as well.
{
content: 'Hello, World!'; //Both single-quotes and double-quotes can be used here.
display: block; //To make sure it works fine in every browser.
}
Теперь он просто думает, что это блок-элемент, а не текст.
Чтобы получить нужный мне результат, я обнаружил, что должен использовать оба ::selection
а также 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;
}
Это должно помочь:
.no-select::selection, .no-select *::selection {
background-color: Transparent;
}
.no-select { /* Sometimes I add this too. */
cursor: default;
}
<span>RixTheTyrunt is da best!</span>
<br>
<span class="no-select">RixTheTyrunt is da best!</span>
Фрагмент:
Хотя этот псевдоэлемент находился в черновиках CSS-селекторов 3-го уровня, он был удален на этапе рекомендации кандидата, так как оказалось, что его поведение было недостаточно определенным, особенно с вложенными элементами, и совместимость не была достигнута.
Это обсуждается в How::selection работает с вложенными элементами.
Несмотря на то, что это реализовано в браузере, вы можете создать иллюзию того, что текст не будет выделен, используя тот же цвет и цвет фона при выделении, что и дизайн вкладки (в вашем случае).
Нормальный дизайн CSS
p { color: white; background: black; }
На выбор
p::-moz-selection { color: white; background: black; }
p::selection { color: white; background: black; }
Запрещение пользователям выбирать текст вызовет проблемы с юзабилити.