Как отключить подсветку выделения текста? - PullRequest
4773 голосов
/ 06 мая 2009

Для якорей, которые действуют как кнопки (например, Вопросы , Теги , Пользователи и т. Д. В верхней части страницы переполнения стека) или вкладок , есть ли в CSS стандартный способ отключить эффект выделения, если пользователь случайно выделил текст?

Я понимаю, что это можно сделать с помощью JavaScript, и немного прибегнув к поиску, можно было получить только Mozilla -moz-user-select.

Существует ли совместимый со стандартами способ сделать это с помощью CSS, и если нет, то каков подход "наилучшей практики"?

Ответы [ 40 ]

6859 голосов
/ 10 декабря 2010

ОБНОВЛЕНИЕ Январь 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 .

794 голосов
/ 05 декабря 2010

В большинстве браузеров это может быть достигнуто с помощью собственных изменений свойства 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 вам нужно будет использовать атрибут <code>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) все еще невозможно предотвратить выборки, которые начинаются до и заканчиваются после невыбираемого элемента, не делая весь документ недоступным для выбора.

181 голосов
/ 13 ноября 2009

Решение JavaScript для IE -

onselectstart="return false;"
176 голосов
/ 06 мая 2009

Пока свойство CSS 3 user-select не станет доступным, браузеры на основе Gecko поддерживают свойство -moz-user-select, которое вы уже нашли. WebKit и браузеры на основе Blink поддерживают свойство -webkit-user-select.

Это, конечно, не поддерживается в браузерах, которые не используют движок рендеринга Gecko.

Нет простого и удобного способа сделать это в соответствии со стандартами; использование JavaScript является опцией.

Реальный вопрос в том, почему вы не хотите, чтобы пользователи не могли выделять и предположительно копировать и вставлять определенные элементы? Я ни разу не сталкивался с тем, что хотел бы, чтобы пользователи не выделяли определенную часть моего сайта. Несколько моих друзей, потратив много часов на чтение и написание кода, будут использовать функцию выделения, чтобы помнить, где на странице они находились, или предоставлять маркер, чтобы их глаза знали, где искать дальше.

Единственное место, где я мог бы убедиться, что это полезно, - это если у вас есть кнопки для форм, которые не следует копировать и вставлять, если пользователь копирует и вставляет сайт.

128 голосов
/ 25 мая 2011

Если вы хотите отключить выделение текста на всех элементах, кроме элементов <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;
}
117 голосов
/ 30 августа 2015

В вышеупомянутых решениях выбор остановлен, но пользователь все еще думает, что вы можете выбрать текст, потому что курсор все еще изменяется. Чтобы он оставался статичным, вам нужно установить курсор 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>

Это сделает ваш текст абсолютно плоским, как в настольном приложении.

103 голосов
/ 06 мая 2009

Вы можете сделать это в Firefox и Safari (также Chrome?)

::selection { background: transparent; }
::-moz-selection { background: transparent; }
76 голосов
/ 21 сентября 2011

Обходной путь для WebKit :

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

Я нашел это в примере CardFlip.

68 голосов
/ 11 ноября 2011

Мне нравится гибридное решение 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, поэтому вы можете добавить туда проверку версии.

66 голосов
/ 01 мая 2013

.hidden:after {
    content: attr(data-txt);
}
<p class="hidden" data-txt="Some text you don't want to be selected"></p>

Хотя это не самый лучший способ.

...