Примусове виділення блоку з текстом

323

Від автора: ви коли-небудь стикалися з такою ситуацією, коли текст розміщують в полях форми textarea або input для спрощення виділення всього блока? У таких полів форми є свої межі виділення, тобто можна клікнути всередині цієї межі і виділити весь текст поля. Є CSS властивість, що дозволяє робити те ж саме без необхідності задіяти несемантические поля форми.

Властивість називається user-select, і працює він так:

.force-select all {
user-select: all;
}

Autoprefixer додасть потрібні префікси, але якщо робити все руками, тоді запис повинна бути такою:

.force-select all {
-webkit-user-select: all; /* Для браузерів на движку Blink і Firefox */
user-select: all; /* Коли-небудь буде вистачати тільки цього рядка */
}

Вам потрібен приклад?

Я знайшов найпоширеніший приклад використання цієї властивості. Ситуація з розряду «у нас є згенерований на сервері код для вставки на наш сайт. Уявіть код вставки Youtube або Vimeo відео:

Примусове виділення блоку з текстом

Підходить для сайтів на зразок мого старого HTML-Ipsum, який вже давно потрібно оновити.

Демо

Розглянемо інший приклад. Шпаргалка з невеликими шматками коду, які необхідно скопіювати в буфер:

З приводу префіксів

Насправді, Autoprefixer перетворює запис властивості до наступного вигляду:

.force-select all {
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
user-select: all;
}

Що можна зрозуміти:

нерозумно використовувати тільки префікс –webkit – для Firefox, навіть якщо браузер з ним працює;

браузер не підтримує Edge значення all, однак він підтримує значення none з префіксом.

Приміром, вам не подобається примусовий вибір, вам подобаються рамки

Тут нам допоможе значення contain. Значення змушує текст вести себе так, ніби він розташований всередині поля форми:

.select-text-like-you-would-within-a-textarea {
/* Поки ніде не підтримується */
user-select: contain;
}

На жаль, дане значення поки ніде не підтримується. В IE/Edge є своя версія даного значення:

.ie-version-of-contain {
-ms-user-select: element;
}

Тепер ми знаємо про три значення: none, all і contain. Також є значення text, текст з яким виділяється по-звичайному. Якщо вам знадобиться скинути значення, для цього є значення auto. Дане значення повертає елемент до нормального стану (тобто для тега p встановиться значення text, для textarea — contain).

Стилізація виділеного тексту

Виділений текст можна стилізувати:

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

Але… я б не рекомендував використовувати ці два селектора в парі. Автоматично копіює виділений текст вже поводиться трохи дивно, а разом з зовсім іншими стилями виходить повна плутанина. Користувач може не зрозуміти, що діється на екрані. На крайній випадок можна задати ::selection на весь сайт, а не тільки для окремих областей.

Класичний спосіб через JavaScript

Вам може бути дуже важлива підтримка Edge. Якщо вам кров з носу потрібно реалізувати автоматичне виділення тексту, можна зробити це через поле форми і JS. Самий базовий приклад:

Можна було б зробити і краще. Можна було б по-іншому прив’язати обробник події, а не прописувати його в тегу. Також можна було б врахувати ситуацію, коли після автоматичного виділення всього тексту слід виділити його частину.

Псевдоелементи

Не знаю, погано це чи добре, але з допомогою user-select: text; можна виділяти текст в псевдоэлементах типи ::before ::after, які на даний момент не володіють такою властивістю ні в одному браузері. З одного боку добре, що ми не можемо виділити текст псевдоэлемента, так як він не розроблявся для зчитування технологіями для людей з обмеженими можливостями (псевдоелементи не контент). З іншого боку дивно бачити текст на екрані і не мати можливості його виділити. Так що не дивно, що браузери знаходять обхідні шляхи.

Мобільні пристрої

На iOS є ще один спосіб:

.prevent-touch-callout {
-webkit-touch-callout: none;
}

Не зовсім виділення тексту, але якщо запобігти виділення тексту, ви вимкніть будь-які взаємодії з елементом. З MDN: «На iPhone OS при натисканні і утриманні пальці на елементі в браузері Safari з’являється спливаюча виноску з інформацією. Дана властивість дозволяє відключити цю виноску.»

Примусове копіювання?

Чи можна включити примусове копіювання тексту в буфер обміну? Можна. Раніше був спосіб на Flash. Однак всі ми знаємо, що Flash вже мертвий. Chrome оголосив про черговий цвях у кришці труни даної технології. В IE 10 з’явилася підтримка execCommand, і, здається, ця технологія буде і в інших браузерах. Витягнув демо з статті Метта Гонта з Google:

Демо працює в браузерах на движку Blink, Firefox і Edge… круто.