26 декабря 2007 в 16:06

Как запретить браузеру выделять текст

  • Разработка веб-сайтов

Если Вы веб-разработчик, то у вас наверняка возникала необходимость в том, чтобы запретить пользователю выделение текста. Оговоримся, что я не имею ввиду полный запрет с целью защиты текста, а запрет на выделение всевозможных подписей, надписей и т.п. где выделение мешает работе интерфейса и пользователю (чаще всего при drag&drop, или выделении текста при двойном клике). Это в первую очередь касается веб-приложений и ни в коем случае не касается информационных сайтов.

Что же мы можем сделать? До сих пор думал немногое. Но прежде чем перейти к рассмотрению нового (лично для меня) методу, рассмотрим какие возможности борьбы с выделением текста предлагают нам браузеры.

Internet Explorer

Данный браузер дает нам две возможности:
  1. Для элементов устанавливаем атрибут unselectable со значением on. Но тут есть один нюанс: текст блока с таким атрибутом нельзя выделить (то есть нельзя начать выделение с данного элемента, и клик по такому элементу не будет снимать выделение с текста, если такой выделен), но если он содержит другие элементы (к примеру «безобидные» SPAN, B и т.д.) то текст в них выделить можно. К тому же если выделение текста начато с блока без такого атрибута, то текст внутри блока с атрибутом unselectable так же будет выделен. В такой ситуации решение одно - ставить всем (!) элементам данный атрибут, что неудобно и не практично.
  2. Перехват события selectstart. Другими словами добавив элементу onselectstart=«return false» (к примеру к BODY) запрещает выделение текста внутри него. Опять же нюанс: если начать выделять текст за пределами такого блока, то текст внутри него выделяется без проблем.

FireFox (браузеры на движке gecko), Safari (браузеры на движке KHTML)

Данные браузеры имеют более совершенный механизм, запрещающий выделение текста в любом виде. Делается это через CSS свойство user-select со значение none, которое включили в CSS3. Но до того как это свойство утверждено, браузеры демократично сделали это собственной фишкой движка назвав свойство -moz-user-select и -khtml-user-select соответственно. Получается, чтобы запретить выделять текст внутри блока, достаточно написать:
-moz-user-select: none; -khtml-user-select: none; user-select: none;

И дело в шляпе.

Другие браузеры

А вот что касается других браузеров, то у них таких механизмов замечено не было. Вообще никаких. Конечно же Opera впереди планеты всей, для нее запрет выделения текста равносильно самому злостному преступлению. Но есть, есть один могильничек:)
Изучая вчера , наткнулся на интересные строки:
document.addEventListener("mousemove",function(e){ if(e.target.getAttribute("unselectable")=="on") e.target.ownerDocument.defaultView.getSelection().removeAllRanges(); },false);

Вспомним про атрибут unselectable у Internet Explorer"а, и становится ясным что в даном случае мы боремся с выделением текста. Развив идею, получилось некоторое кроссбраузерное решение:
function preventSelection(element){ var preventSelection = false; function addHandler(element, event, handler){ if (element.attachEvent) element.attachEvent("on" + event, handler); else if (element.addEventListener) element.addEventListener(event, handler, false); } function removeSelection(){ if (window.getSelection) { window.getSelection().removeAllRanges(); } else if (document.selection && document.selection.clear) document.selection.clear(); } function killCtrlA(event){ var event = event || window.event; var sender = event.target || event.srcElement; if (sender.tagName.match(/INPUT|TEXTAREA/i)) return; var key = event.keyCode || event.which; if (event.ctrlKey && key == "A".charCodeAt(0)) // "A".charCodeAt(0) можно заменить на 65 { removeSelection(); if (event.preventDefault) event.preventDefault(); else event.returnValue = false; } } // не даем выделять текст мышкой addHandler(element, "mousemove", function(){ if(preventSelection) removeSelection(); }); addHandler(element, "mousedown", function(event){ var event = event || window.event; var sender = event.target || event.srcElement; preventSelection = !sender.tagName.match(/INPUT|TEXTAREA/i); }); // борем dblclick // если вешать функцию не на событие dblclick, можно избежать // временное выделение текста в некоторых браузерах addHandler(element, "mouseup", function(){ if (preventSelection) removeSelection(); preventSelection = false; }); // борем ctrl+A // скорей всего это и не надо, к тому же есть подозрение // что в случае все же такой необходимости функцию нужно // вешать один раз и на document, а не на элемент addHandler(element, "keydown", killCtrlA); addHandler(element, "keyup", killCtrlA); }

Вызвав данную функцию, например:

вы запретите выделение во всем документе, кроме элементов INPUT и TEXTAREA.
Комментарии:
  1. Opera не дает обрабатывать событие dblclick, так что в этом браузере все равно возможно выделить текст двойным кликом.
  2. Ctrl+A:
    1. В Opera длительное (2-3 секунды) удержание данной комбинации вызывает выделение текста до ее отпускания. Причем если первым отжать клавишу А а потом Ctrl, то выделение пропадает. Иначе остается.
    2. Safari не обрабатывает keydown для клавиш при зажатом Ctrl. Потому выделение текста пропадает только после отпускания клавиш. Причем для этого браузера характерно поведение Opera, в плане порядка отпускания клавиш (если первым отжать Ctrl, то выделение останется).
  3. Выделении текста двойным кликом:
    1. Safari & FireFox выделяют слово, и сразу снимают выделение. То есть присутствует эффект кратковременного выделения текста.
    2. Opera не дает запретить поведение по умолчанию. Она выделяет слово и вызывает контекстное меню.
Других особенностей не выявлено.
Тестировалось на FireFox 2.0.11, IE 6.0, Opera 9.24, Safari 3.0.3 (Win).
Конечно решение не идеальное, и требует JavaScript (с другой стороны это и нужно в веб-приложениях, которые и так используют JS). Но это лучше чем ничего, и довольно кроссбраузерно (конечно может потребоваться дополнительный код для некоторых браузеров и их версий).
Буду рад замечаниям, комментариям, дополнениям.
UPDATE Ввиду того, что многие к концу статьи видимо забывают начало, или не внимательно читают, повторяю первый суть первого абзаца. В данной статье я не решал задачу полного запрета выделения текста с целью его защиты от копирования, а имел ввиду запрет на выделение всевозможных подписей, надписей и т.п. там где выделение мешает работе интерфейса и пользователю (чаще всего при drag&drop, или выделении текста при двойном клике). Это в первую очередь касается веб-приложений и ни в коем случае не касается обычных информационных сайтов.

Вероятно, вы обращали внимание, что цвет выделения на некоторых веб-сайтах отличается от цвета выделения по умолчанию и подходит к другим цветам, используемым на сайте. Этого можно добиться с помощью CSS, и задать эти цвета так же, как и другие цвета на веб-сайте. Таким образом можно создать сайт, цветовая схема которого будет использоваться абсолютно везде на этом сайте, и для этого нужно небольшое количество несложного кода CSS.

Поддержка браузерами

Этот способ работает в браузерах Firefox, Chrome, Safari и Internet Explorer, начиная от 9-ой версии, но не работает в современных версиях браузеров Chrome и Safari для iOS, Opera Mini и UC Browser для Android. Воспринимайте этот эффект как декоративное дополнение. Те пользователи, которые смогут его увидеть, восхитятся безупречным стилем Вашего сайта, а те, кто не сможет - не почувствуют себя обделенными.

Пример использования

Вот скриншот того, как может выглядеть уникальный цвет выделения для пользователей браузеров, поддерживающих этот псевдоэлемент:

Можете сами опробовать, как это работает, открыв страницу с исходником этого урока в подходящем браузере и выделив любой текст в уроке. Выделенный текст будет белым на малиновом фоне.

Код CSS

Чтобы создать уникальный цвет выделения текста, нужно добавить следующий код в таблицу стилей:

::-moz-selection { background-color : #BA9EB0 ; color : #ffffff ; } ::selection { background-color : #BA9EB0 ; color : #ffffff ; }

Этот код создаст белый цвет текста на сиреневом фоне при выделении. Вы можете выбрать любые другие цвета, подходящие к цветовой схеме Вашего сайта.

Свойство цвета фона задает цвет фона выделенного текста, а цвет - цвет шрифта.

Не забывайте поменять цвета для обоих псевдоэлементов. Псевдоэлемент -moz-selection работает в браузере Firefox, а псевдоэлемент selection (выделение) - во всех остальных поддерживающих это свойство браузерах.

Выбирайте сочетания цветов с хорошей контрастностью и не забудьте проверить, насколько выделенный текст остается читабельным. Цель в подборе подходящих цветов, а не в создании трудностей при чтении.

Вот и все, что нужно сделать, чтобы на Вашем сайте появился сочетающийся с общей цветовой схемой цвет выделения текста. Просто добавьте код CSS, приведенный выше, в файл стилей, выберете подходящие цвета и замените на них цвета в этом отрывке кода, и у Вас на сайте будет уникальный цвет выделения текста.

Подбор цветов

Для подбора цветов можно использовать, например, сайт Colorpicker.com или добавление к браузеру Colorzilla . Ну и, конечно, можно выбрать цвета в редактирующих изображения программах, например, в Photoshop. Во всех этих источниках будут указаны цвета в шестнадцатеричной записи, и Вы можете просто скопировать их и вставить в код выше.

Если Вы веб-разработчик, то у вас наверняка возникала необходимость в том, чтобы запретить пользователю выделение текста. Оговоримся, что я не имею ввиду полный запрет с целью защиты текста, а запрет на выделение всевозможных подписей, надписей и т.п. где выделение мешает работе интерфейса и пользователю (чаще всего при drag&drop, или выделении текста при двойном клике). Это в первую очередь касается веб-приложений и ни в коем случае не касается информационных сайтов.

Что же мы можем сделать? До сих пор думал немногое. Но прежде чем перейти к рассмотрению нового (лично для меня) методу, рассмотрим какие возможности борьбы с выделением текста предлагают нам браузеры.

Internet Explorer

Данный браузер дает нам две возможности:
  1. Для элементов устанавливаем атрибут unselectable со значением on. Но тут есть один нюанс: текст блока с таким атрибутом нельзя выделить (то есть нельзя начать выделение с данного элемента, и клик по такому элементу не будет снимать выделение с текста, если такой выделен), но если он содержит другие элементы (к примеру «безобидные» SPAN, B и т.д.) то текст в них выделить можно. К тому же если выделение текста начато с блока без такого атрибута, то текст внутри блока с атрибутом unselectable так же будет выделен. В такой ситуации решение одно - ставить всем (!) элементам данный атрибут, что неудобно и не практично.
  2. Перехват события selectstart. Другими словами добавив элементу onselectstart=«return false» (к примеру к BODY) запрещает выделение текста внутри него. Опять же нюанс: если начать выделять текст за пределами такого блока, то текст внутри него выделяется без проблем.

FireFox (браузеры на движке gecko), Safari (браузеры на движке KHTML)

Данные браузеры имеют более совершенный механизм, запрещающий выделение текста в любом виде. Делается это через CSS свойство user-select со значение none, которое включили в CSS3. Но до того как это свойство утверждено, браузеры демократично сделали это собственной фишкой движка назвав свойство -moz-user-select и -khtml-user-select соответственно. Получается, чтобы запретить выделять текст внутри блока, достаточно написать:
-moz-user-select: none; -khtml-user-select: none; user-select: none;

И дело в шляпе.

Другие браузеры

А вот что касается других браузеров, то у них таких механизмов замечено не было. Вообще никаких. Конечно же Opera впереди планеты всей, для нее запрет выделения текста равносильно самому злостному преступлению. Но есть, есть один могильничек:)
Изучая вчера файл Оперы с хаками для сайтов , наткнулся на интересные строки:
document.addEventListener("mousemove",function(e){ if(e.target.getAttribute("unselectable")=="on") e.target.ownerDocument.defaultView.getSelection().removeAllRanges(); },false);

Вспомним про атрибут unselectable у Internet Explorer"а, и становится ясным что в даном случае мы боремся с выделением текста. Развив идею, получилось некоторое кроссбраузерное решение:
function preventSelection(element){ var preventSelection = false; function addHandler(element, event, handler){ if (element.attachEvent) element.attachEvent("on" + event, handler); else if (element.addEventListener) element.addEventListener(event, handler, false); } function removeSelection(){ if (window.getSelection) { window.getSelection().removeAllRanges(); } else if (document.selection && document.selection.clear) document.selection.clear(); } function killCtrlA(event){ var event = event || window.event; var sender = event.target || event.srcElement; if (sender.tagName.match(/INPUT|TEXTAREA/i)) return; var key = event.keyCode || event.which; if (event.ctrlKey && key == "A".charCodeAt(0)) // "A".charCodeAt(0) можно заменить на 65 { removeSelection(); if (event.preventDefault) event.preventDefault(); else event.returnValue = false; } } // не даем выделять текст мышкой addHandler(element, "mousemove", function(){ if(preventSelection) removeSelection(); }); addHandler(element, "mousedown", function(event){ var event = event || window.event; var sender = event.target || event.srcElement; preventSelection = !sender.tagName.match(/INPUT|TEXTAREA/i); }); // борем dblclick // если вешать функцию не на событие dblclick, можно избежать // временное выделение текста в некоторых браузерах addHandler(element, "mouseup", function(){ if (preventSelection) removeSelection(); preventSelection = false; }); // борем ctrl+A // скорей всего это и не надо, к тому же есть подозрение // что в случае все же такой необходимости функцию нужно // вешать один раз и на document, а не на элемент addHandler(element, "keydown", killCtrlA); addHandler(element, "keyup", killCtrlA); }

Вызвав данную функцию, например:

вы запретите выделение во всем документе, кроме элементов INPUT и TEXTAREA.
Комментарии:
  1. Opera не дает обрабатывать событие dblclick, так что в этом браузере все равно возможно выделить текст двойным кликом.
  2. Ctrl+A:
    1. В Opera длительное (2-3 секунды) удержание данной комбинации вызывает выделение текста до ее отпускания. Причем если первым отжать клавишу А а потом Ctrl, то выделение пропадает. Иначе остается.
    2. Safari не обрабатывает keydown для клавиш при зажатом Ctrl. Потому выделение текста пропадает только после отпускания клавиш. Причем для этого браузера характерно поведение Opera, в плане порядка отпускания клавиш (если первым отжать Ctrl, то выделение останется).
  3. Выделении текста двойным кликом:
    1. Safari & FireFox выделяют слово, и сразу снимают выделение. То есть присутствует эффект кратковременного выделения текста.
    2. Opera не дает запретить поведение по умолчанию. Она выделяет слово и вызывает контекстное меню.
Других особенностей не выявлено.
Тестировалось на FireFox 2.0.11, IE 6.0, Opera 9.24, Safari 3.0.3 (Win).
Конечно решение не идеальное, и требует JavaScript (с другой стороны это и нужно в веб-приложениях, которые и так используют JS). Но это лучше чем ничего, и довольно кроссбраузерно (конечно может потребоваться дополнительный код для некоторых браузеров и их версий).
Буду рад замечаниям, комментариям, дополнениям.
UPDATE Ввиду того, что многие к концу статьи видимо забывают начало, или не внимательно читают, повторяю первый суть первого абзаца. В данной статье я не решал задачу полного запрета выделения текста с целью его защиты от копирования, а имел ввиду запрет на выделение всевозможных подписей, надписей и т.п. там где выделение мешает работе интерфейса и пользователю (чаще всего при drag&drop, или выделении текста при двойном клике). Это в первую очередь касается веб-приложений и ни в коем случае не касается обычных информационных сайтов.

Управляет поведением выделения текста и других элементов на странице, в частности, позволяет запретить выделение текста. Обычно применяется для интерактивных элементов, на которые можно щёлкать, например, вкладки, и для которых выделение текста нежелательно.

Краткая информация

Обозначения

Описание Пример
<тип> Указывает тип значения. <размер>
A && B Значения должны выводиться в указанном порядке. <размер> && <цвет>
A | B Указывает, что надо выбрать только одно значение из предложенных (A или B). normal | small-caps
A || B Каждое значение может использоваться самостоятельно или совместно с другими в произвольном порядке. width || count
Группирует значения. [ crop || cross ]
* Повторять ноль или больше раз. [,<время>]*
+ Повторять один или больше раз. <число>+
? Указанный тип, слово или группа не является обязательным. inset?
{A, B} Повторять не менее A, но не более B раз. <радиус>{1,4}
# Повторять один или больше раз через запятую. <время>#
×

Значения

auto Для редактируемых элементов значение принимается contain . Если у родителя значение user-select установлено как all , то для элемента оно тоже будет all . Если у родителя значение user-select установлено как none , то для элемента оно тоже будет none . Во всех остальных случаях принимается значение text . none Пользователю запрещено выделять элемент. text Пользователь может выделить текст в элементе. all Позволяет выделить текст внутри элемента, включая дочерние элементы. contain Позволяет выделять текст, но только внутри границ элемента.

Пример

user-select

Этот текст нельзя выделить

Этот текст тоже можно выделить

Примечание

Internet Explorer и Edge поддерживают свойство -ms-user-select .

Chrome до версии 54, Opera до версии 41, Safari и Android поддерживают свойство -webkit-user-select .

Firefox поддерживает свойство -moz-user-select .

Значение contain поддерживается только в IE.

Спецификация

Каждая спецификация проходит несколько стадий одобрения.

  • Recommendation (Рекомендация ) - спецификация одобрена W3C и рекомендована как стандарт.
  • Candidate Recommendation (Возможная рекомендация ) - группа, отвечающая за стандарт, удовлетворена, как он соответствует своим целям, но требуется помощь сообщества разработчиков по реализации стандарта.
  • Proposed Recommendation (Предлагаемая рекомендация ) - на этом этапе документ представлен на рассмотрение Консультативного совета W3C для окончательного утверждения.
  • Working Draft (Рабочий проект ) - более зрелая версия черновика после обсуждения и внесения поправок для рассмотрения сообществом.
  • Editor"s draft (Редакторский черновик ) - черновая версия стандарта после внесения правок редакторами проекта.
  • Draft (Черновик спецификации ) - первая черновая версия стандарта.
×

Приветствую, Друзья.

После очередного долгого перерыва вспомнил, что давно уже не писал ни строчки. Конечно, на это есть свои причины, ведь какая-нибудь причина придумать себе оправдание всегда найдется, правда? На самом деле, каждый день занимаюсь ВидеоКурсом, о котором уже упоминал пару раз, но пока больше об этом ничего говорить не буду, скоро все узнаете.

Так вот, так как в голову ничего не приходило, о чем можно написать. Решил посмотреть статистику, что же интересует пользователей Рунета по вопросам HTML, WordPress, DLE и тому подобных тем. И знаете что? Есть еще о чем писать. На все вопросы, что я нашел, вроде бы и есть ответы, однако не всегда в понятной форме. Да и вообще стало интересно написать что-нибудь этакое.

Сегодня поговорим об HTML. А именно о том, как выделить текст жирным и курсивным начертанием, а также поговорим о выделении цветом.

Выделение текста жирным начертанием.

Чтобы выделить текст жирным начертанием не нужно ничего мудрить со стилями CSS или придумывать еще какие-либо сложности. В HTML уже есть такая возможность. При этом, мы можем не просто выделить текст жирным, но и сделать на нем некий акцент с помощью выделения. Акцент может делаться для поисковых систем или каких-либо специальных браузеров или программ. Главное это не переборщить с акцентированием текста в статье или на странице с как-то информацией, так как это может губительно сказаться как минимум на продвижении данной HTML-страницы.

Итак, чтобы просто выделить текст жирным, мы можем воспользоваться тегом . Данный тег относится к элементам физической разметки, при этом устанавливая жирное начертание текста, не делая на нем какого-либо акцента. Этот тег является парным, что говорит о том, что он имеет, как открывающий тег, так и закрывающий. Кроме того, так как элемент встроенный, он должен находиться в каком-либо блочном элементе, например

Пример кода:

жирный текст

Результат:

жирный текст

В этом случае мы просто выделили текст жирным начертанием и все.

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

В этом случае все абсолютно также как и в случае, с простым выделением жирным, только мы делаем акцент, а не просто выделение.

Пример кода:

Результат:

Все довольно просто, не правда ли?

Выделение текста курсивом.

В этом случае все не сложнее, чем в первом. И ситуация у нас абсолютно та же. Мы можем выделить текст двумя вариантами в HTML. Опять же, используя либо тег физической разметки или же тег логической, с помощью которого мы опять же делаем акцент на выделенный текст.

Чтобы выделить текст курсивом мы воспользуемся тегом . Этот элемент является парным и строчным, что говорит нам о том, что мы должны использовать, как открывающий тег так и закрывающий. А также должны использовать его внутри блочного элемента. И в данном случае наиболее подходящий блочный элемент — тег параграфа

Пример кода:

текст курсивом

Результат:

текст курсивом

И конечно же мы можем сделать акцент на тексте одновременно выделив его курсивом с помощью тега . Данный элемент такой же как , за исключением того что выделяется текст курсивом а не жирным.

Пример кода:

текст, на котором мы сделали акцент

Результат:

текст, на котором мы сделали акцент

И последнее о чем я хотел бы сегодня поговорить — это выделение текста цветом.

К сожалению тега, для выделения текста цветом в HTML мы не имеем. Но все же и в этом способе нет ничего сложного.

Итак, чтобы выделить определенную часть текста цветом, мы можем обернуть нужную часть текста тегом , который является универсальным тегом, и используется внутри блочного элемента. В нашем случае блочным элементом является тег

Но добавить недостаточно. Также необходимо указать параметр style , что позволит добавить CSS свойства необходимому тексту, указать само свойство (color), которое поможет задать определенный цвет. И наконец, указать значение для свойства color . Но может возникнуть вопрос: «Что указывать-то?» Указать необходимо HTML-код того цвета в который мы хотим «покрасить» текст. HTML-коды цветов можно найти .

Теперь чтобы было понятней рассмотрим пример.

Пример кода.

текст, который нужно выделить цветом

В этом случае мы выделяем одно слово: цветом. Также хочу отметить, что тег является парным, и мы должны его закрыть там, где свойство должно закончиться.

Результат:

текст, который нужно выделить цветом

Такими нехитрыми способами мы можем манипулировать текстом на нашей странице. Хочу также отметить, что все то, о чем мы только что говорили, работает и на WordPress и на DLE, ибо любой движок для вывода страниц использует HTML. Именно поэтому HTML можно назвать основой основ любого сайта, не важно, какая у Вас CMS.

Надеюсь, я все понятно объяснил.

Удачи, Друзья. Скоро… Будут интересные новости…