Selection in CSS
Selection is a habit formed by computer users many years ago. On the web, we select content for different reasons. Maybe we want to copy a text and quote it somewhere, or maybe coping is just a habit that some users do to make reading easier. For mobile, selecting content is harder and for me, it’s annoying. I don’t like to select content on mobile. It just doesn’t feel right!
In this article, I will go through everything about selection in CSS, which includes the pseudo-element ::selection , and user-select . The goal of the article is to get you aligned with all those techniques and to let you know when and where to use them.
The ::selection CSS pseudo-element applies styles to the part of a document that has been highlighted by the user (such as clicking and dragging the mouse across text).
To use the ::selection pseudo-element, all you need to do is the following:
Supported Properties For ::selection
It’s worth noting that only color , background , and text-shadow properties are supported with ::selection .
Custom Selection
What if we want a custom selection effect? For example, controlling the height of selection, and having a custom background? See the below figure:
It’s possible, but a bit tricky. Here is an explanation of how it’s done:
- We add a pseudo-element with the same text content. Then, we give it a 50% height with a white background color.
- The pseudo-element is positioned above the original text.
Now, when the text is selected, the pseudo-element will cover 50% of the text vertically. This mimics the effect we needed.
Credits goes to this question on StackOverflow.
As another option, I tweaked the above and used CSS gradients instead. The point here is using a white gradient that has a 50% height and doesn’t repeat the background.
See the below figure for a visual explanation.
I hope it’s more clear now! See the demo on CodePen.
Animating Selection
While working on the previous demo, I asked myself a question: is it possible to animate the selection? For example, while the text is selected and the mouse is not hovering, the height is 50% and When the mouse is hovering, the height can be increased to 80%.
Multi Line Text
Unfortunately, the solution above won’t work with multi-line text. To make it work, we should use JavaScript to wrap each word in an inline element, a <span> , for example. Once each word is in a <span> element, a pseudo-element should be added to each one, and the same technique can be used.
See the below script for wrapping each word in a <span> element.
Now, you need to style each <span> element, and then add a pseudo-element for each one.
This solution works, but not with all text. For example, the text below has a comma, number, full capital words. Notice that the selection is not consistent in all words.
I would say that having a multi-line selection style is hacky, and shouldn’t be used globally on a website. Maybe it’s totally fine if it’s were used for one paragraph only.
Getting Creative With ::selection and text-shadow
Since text-shadow is one of the supported properties for a custom selection, we can get creative with some interesting effects by using multiple text shadows. Let’s explore some:
Long Shadow Selection
Outline Text Selection
As per this article on CSS tricks, we can simulate a text outline by using text-shadow .
Blur Selection
Another interesting effect is to blur the text on selection. By making the color transparent , the text-shadow will still be there and mimics a blur effect.
And I’m sure you can come up with more and more examples. The possibilities are endless with text-shadow .
Text Shadow and Performance
It’s recommended not to use a heavy text-shadow style as they will cause performance issues. I tried to cause a performance issue for you 😀 See below:
That neon effect is very heavy. Notice that while selecting the text, there is a lag between the time I select and the time that the selected style appears. Also, notice those glitches at the top and left sides. Please use text-shadow carefully.
Do Form Elements Got Selected?
The short answer is yes. For me, I found it weird to selected a page and found that the content inside an input is selected. See the figure below:
For example, the button text can be selected. We will come to discuss whether or not to allow selecting form elements in the user-select section.
However, things don’t stop there. Selection is more than just selecting text. In the next section, I will explain the user-select CSS property and how we can get the benefit of it.
Digging user-select Property
The user-select property gives us the ability to wether the user can select a specific text or not. It can be useful to disable text selection in some use-cases, which will be useful for the user to avoid selecting any unwanted neighboring content. (I borrowed the word neighboring from the CSS spec).
The possible values for the property are:
Use Cases
Text and Icon
If an element has an icon as a symbol or a font icon, then it will be selected within the text. This is not practical and not useful at all. Consider the following:
When selected, it looks like this.
That’s not necessary at all. Notice that it has the aria-hidden attribute to avoid exposing it to screen readers. We can use this:
That way, we prevented the icon from being selected, and at the same time, this ties it to the aria-hidden attribute. So anything that shouldn’t be selected, is most likely shouldn’t be exposed to screen readers.
Checkbox Input
A common thing that I consider annoying is accidentally selecting the checkbox’s label while clicking on it. See the below figure:
This can be solved by adding the following to the <label> element:
Select All Text
An interesting value for user-select is all . If applied to a parent element, all text contained within it will be selected with one click only. This could be useful for content that is related and should be selected all together. For example, selecting a code snippet.
Web Apps
A web application should feel like a real application. Can you select the button’s text for a computer application? No, you can’t. On the web, it’s important to reflect that something feels like a real app, even if it’s made via HTML and CSS.
Let’s take some examples from the wild.
Slack
Slack allows selecting labels and inputs. However, the button’s content is not selectable.
And here is me selecting a modal title.
The interesting thing is that the chat date is not selectable.
It feels weird to select text in an app. Slack does have places where user-select: none is used, but it’s less than expected. As a user, I find no benefit at all from copying a modal title.
Notion
I like Notion better. It feels more like a real app, not a website that I can select its text.
For the figure above, none of the text is selectable, which is expected.
Don’t Disable Selection Globally
It’s a bad practise to disable text selection globally. When used, make sure to apply it to certain elements where selection is not useful. You can make a utility class for it, like the one below:
A Common Dark Pattern
There is a UX pattern that annoys me which shows a warning when a user tries to select content from an article. This is annoying, and makes the user feel that he is controlled. It looks like the figure below:
Please, don’t do this..
Selection For Mobile
- There is a property « for iOS Safari that disables a callout which appears when the user select a text. I tried it, but it didn’t do anything.
- ::selection styles doesn’t work.
- The user-select: none works as expected.
I tried to include a real example which shows an issue from Wikipedia. I copied text, and the icon (listen) was copied with it. This is annoying. See the figure below:
Instead of coping “listen”, it’s better to add user-select: none to it so when selected, it won’t be copied with the text.
Related Reads
The End
That’s a wrap. Do you have a comment or a suggestion? Please feel free to ping me on @shadeed9.
Выделение и CSS
Навык выделения текста и других объектов сформировался у пользователей компьютеров много лет назад. Мы выделяем содержимое веб-страниц по разным причинам. Возможно, нужно скопировать текст и где-то его процитировать, возможно — кому-то просто легче читать текст, выделяя его фрагменты. На мобильных устройствах, правда, выделять что-либо сложнее. Меня, например, это раздражает. Мне не нравится выделять содержимое веб-страниц на телефоне. Эта операция кажется какой-то «неправильной».
В этом материале я расскажу обо всём, что нужно знать о стилизации выделений средствами CSS. В частности, речь пойдёт о псевдоэлементе ::selection и о свойстве user-select . Эта статья направлена на то, чтобы показать всем желающим возможности CSS по работе с выделениями, и на то, чтобы рассказать о том, когда и как использовать разные методы работы с выделениями.
Основы
На MDN можно узнать о том, что псевдоэлемент ::selection позволяет применить стили к части документа, который был выделен пользователем (например, с помощью мыши).
Для использования ::selection достаточно воспользоваться следующей конструкцией:
Выделенный текст
Вот пример, с которым можно поэкспериментировать.
Свойства, поддерживаемые ::selection
Стоить отметить, что псевдоэлемент ::selection поддерживает только свойства color , background и text-shadow .
Настройка собственных эффектов выделения
Что если нам нужно, чтобы выделение выглядело бы по-особенному? Например, чтобы выделение имело бы определённую высоту или некий интересный фон? Взгляните на следующий рисунок.
Пример особой настройки выделения
Это возможно, хотя и потребует приложения некоторых усилий. Вот как сделано выделение, показанное выше:
- Добавлен псевдоэлемент, с тем же текстом, который мы выделяем. Затем псевдоэлементу задано свойство height: 50% и белый фоновый цвет.
- Псевдоэлемент расположен над исходным текстом.
Об этой методике я узнал здесь.
Ещё один вариант подобного выделения представлен ниже. Здесь я, вместо сплошного выделения, реализовал выделение в виде CSS-градиента. Смысл тут заключается в использовании белого градиента с высотой в 50% и в однократном заполнении элемента фоновым рисунком благодаря использованию значения no-repeat при настройке свойства background .
На следующем рисунке показано разъяснение этой методики.
Реализация градиентного выделения
Надеюсь, я смог понятно объяснить эту идею. Вот рабочий пример.
Анимирование выделения
Работая над предыдущим примером, я задался следующим вопросом: «Реально ли анимировать выделение?». Например, в процессе выделения текста высота выделения составляет 50%. А когда указатель мыши уводят в сторону, высота выделения увеличивается до 80%. Как это сделать? А вот так:
Текст в процессе выделения
Текст после завершения выделения
Вот видео, в котором демонстрируется анимированное выделение.
Многострочный текст
Представленная выше методика настройки выделения, к сожалению, не подходит для многострочного текста. Для того чтобы, всё же, реализовать нечто подобное и для такого текста, нужно прибегнуть к возможностям JavaScript и поместить каждое слово во встроенный (строчный) элемент, например — в <span> . После того, как каждое слово окажется в собственном элементе <span> , к каждому из таких элементов надо добавить псевдоэлемент. А уже после этого к многострочному тексту можно применить вышеописанный эффект.
Вот скрипт, позволяющий поместить каждое слово в <span> -контейнер:
После этого элементы <span> надо стилизовать. Затем к каждому из них надо добавить псевдоэлемент:
Если посмотреть на эту конструкцию в деле, то окажется, что она работает, но не совсем так, как можно ожидать. Ниже показан пример выделения многострочного текста. Можно заметить, что выделение выглядит неоднородным.
Неоднородное выделение
Я бы сказал, что подобное многострочное выделение получается не очень хорошим, и что его не стоит использовать в глобальном масштабе. Возможно, его стоит применять лишь, скажем, для организации выделения какого-то отдельного абзаца.
Тут с таким выделением можно поэкспериментировать.
Креативный подход к использованию ::selection и text-shadow
Так как одним из свойств, которые поддерживает псевдоэлемент ::selection , является text-shadow , мы можем попытаться достичь каких-нибудь интересных эффектов, используя несколько теней текста. Исследуем возможности, которые открывает перед нами эта идея.
▍Выделение с длинными тенями
Выделенный текст отбрасывает длинные тени
Вот как реализовать этот эффект:
▍Эффект контурного текста
Выделенный текст становится контурным
Эту идею я нашёл в данной статье. Речь идёт о том, что с помощью свойства text-shadow можно сымитировать эффект контурного текста.
▍Эффект размытия
Выделенный текст выглядит размытым
Ещё один интересный эффект, который можно применить к выделенному тексту, заключается в размытии этого текста. Суть тут в том, чтобы использовать при настройке цвета текста свойство color: transparent . Тени, задаваемые с помощью text-shadow , при этом никуда не исчезнут, что и даст нужный эффект.
Уверен, что вы сами сможете придумать ещё очень много примеров применения text-shadow для стилизации выделений. Это свойство даёт нам безграничные возможности.
▍Тени текстов и производительность
Не рекомендуется использовать слишком сложные стили при настройке text-shadow . Дело в том, что чрезмерное увлечение этим свойством приводит к проблемам с производительностью. Вот видео, демонстрирующее один из примеров таких проблем.
Использование очень сложных стилей при настройке выделения текста
Представленный здесь неоновый эффект очень сложен. Обратите внимание на то, что при выделении этого текста заметна задержка между моментом выделения текста и моментом применения стилизации. Кроме того, обратите внимание на то, что сверху и слева появляется то, что появляться не должно. Поэтому прошу вас использовать text-shadow осмотрительно.
Выделяются ли элементы форм?
Краткий ответ на вопрос, вынесенный в заголовок этого раздела, будет звучать как «да». Мне кажется, что это неправильно: выделяешь страницу, а оказывается, что содержимое внутри полей ввода тоже выделяется. Вот как это выглядит.
Содержимое внутри полей ввода выделяется
Тут может быть выделен и текст внутри кнопки. В разделе, посвящённом user-select , мы поговорим о том, стоит или нет позволять пользователям выделять формы элементов.
Исследование свойства user-select
Свойство user-select даёт нам возможность задавать возможность выделения конкретного текста пользователем. Это свойство может оказаться полезным для отключения возможности выделения текста, что может пригодиться для ограничения возможностей пользователя по выделению материалов, расположенных рядом друг с другом. Вот стандарт, описывающий user-select .
Это свойство может принимать следующие значения: none, auto, text, contain, all .
Сценарии использования user-select
▍Текст и иконка
Если в элементе есть текст и иконка — в виде символа или значка, взятого из какого-нибудь шрифта, то при выделении текста будет выделяться и эта иконка. Рассмотрим пример, представленный на следующем рисунке.
Кнопка с текстом и иконкой
Вот код этой кнопки:
При выделении этого элемента он выглядит так, как показано ниже.
Выделенная кнопка
В подобном совершенно нет необходимости. Обратите внимание на то, что в разметке используется атрибут aria-hidden , скрывающий иконку от средств чтения с экрана. Для того чтобы решить проблему с выделение того, что выделять не нужно, мы можем воспользоваться следующим стилем:
Это позволяет запретить выделение иконки. И, в то же время, мы привязываем запрет выделения к атрибуту aria-hidden . В результате всё, что не должно выделяться, скорее всего, не должно быть видимым и для средств чтения с экрана.
▍Флажки
Меня раздражает такое поведение флажков, когда, устанавливая или снимая флажок, я случайно выделяю текст его описания. Вот как это выглядит.
Текст описания флажка выделен случайно
Решить эту проблему можно, стилизовав элемент <label> следующим образом:
▍Выделение всего текста
Значение all , которое может принимать свойство user-select , позволяет добиваться интересного эффекта. Если это свойство с таким значением есть у родительского элемента, то весь текст, содержащийся в таком элементе, можно выделить одним щелчком мыши. Это может оказаться полезным для работы с текстовым содержимым, которое должно выделяться целиком. Например — для выделения фрагментов кода, имеющихся на странице:
Фрагмент текста, оформленный таким стилем, можно выделить одним щелчком мыши по нему.
Веб-приложения
Веб-приложение должно восприниматься пользователем как настоящее приложение. Можно ли выделять текст кнопок в обычных приложениях? Нет, нельзя. Важно, чтобы веб-приложения отражали привычные черты обычных приложений, делая это даже с учётом того, что они созданы с использованием HTML и CSS.
Рассмотрим несколько примеров из жизни.
▍Slack
В Slack можно выделять метки и поля ввода. Однако тексты кнопок не выделяются.
Подписи кнопок не выделяются
Вот ещё один пример.
Подпись в заголовке модального окна выделяется
А дату чата выделить нельзя.
Дату выделить нельзя
В целом — мне кажется странным то, что в приложении можно выделять некоторые тексты, которые, вроде бы, не должны поддерживать выделение. В интерфейсе Slack есть места, где используется user-select: none , но таких мест меньше, чем можно ожидать. Например мне, как пользователю, нет никакой выгоды от выделения заголовка модального окна.
▍Notion
Подход к выделению элементов, реализованный в Notion, мне нравится больше. Это веб-приложение больше похоже на реальное приложение, а не на веб-сайт, любую часть интерфейса которого можно выделить.
То, что не должно выделяться, не выделяется
Ни один фрагмент текста с этого рисунка не выделяется. Это — именно то, чего можно ожидать от приложения.
Не используйте глобальное отключение выделения
Не рекомендуется отключать выделение глобально. Когда вы пользуетесь отключением выделения — постарайтесь, чтобы оно отключалось бы лишь у элементов, для которых оно не имеет смысла. Для этого можно создать вспомогательный класс. Например — такой:
Нехороший паттерн
Есть один UX-паттерн, который мне крайне не нравится. Он заключается в показе предупреждения при попытке выделения текста. Это раздражает и создаёт у пользователя такое ощущение, будто его взаимодействием с сайтом пытаются управлять. Пример этого паттерна показан ниже.
Запрет выделения с показом уведомления
Пожалуйста, не делайте так.
Выделение на мобильных устройствах
Существует свойство -webkit-touch-callout для iOS Safari, которое должно отключать показ стандартной подсказки, выводимой при выделении текста. Я попытался воспользоваться этим свойством, но оно не работает.
Стили ::selection тоже не работают.
А свойство user-select: none работает так, как ожидается.
Я постарался найти реальный пример, иллюстрирующий эту проблему. Я скопировал фрагмент текста из Википедии. При этом был скопирован и совершенно ненужный мне текст (listen) . Это раздражает.
Вместе с полезным текстом скопировано и (listen)
Вместо того чтобы позволять пользователю копировать это вот «listen», лучше было бы добавить к этому элементу стиль user-select: none . В результате при копировании текста, содержащего этот элемент, он копироваться не будет.
Итоги
Здесь мы рассмотрели методы настройки выделения элементов веб-страниц с использованием средств CSS. Возможно, вам интересно будет взглянуть и на этот материал.
Уважаемые читатели! Как вы настраиваете выделение текстов в своих проектах?
HTML выделение: Выделение текста жирным, курсивом и цветом.
После очередного долгого перерыва вспомнил, что давно уже не писал ни строчки. Конечно, на это есть свои причины, ведь какая-нибудь причина придумать себе оправдание всегда найдется, правда? На самом деле, каждый день занимаюсь ВидеоКурсом, о котором уже упоминал пару раз, но пока больше об этом ничего говорить не буду, скоро все узнаете.
Так вот, так как в голову ничего не приходило, о чем можно написать. Решил посмотреть статистику, что же интересует пользователей Рунета по вопросам HTML, WordPress, DLE и тому подобных тем. И знаете что? Есть еще о чем писать. На все вопросы, что я нашел, вроде бы и есть ответы, однако не всегда в понятной форме. Да и вообще стало интересно написать что-нибудь этакое.
Сегодня поговорим об HTML. А именно о том, как выделить текст жирным и курсивным начертанием, а также поговорим о выделении цветом.
Выделение текста жирным начертанием.
Чтобы выделить текст жирным начертанием не нужно ничего мудрить со стилями CSS или придумывать еще какие-либо сложности. В HTML уже есть такая возможность. При этом, мы можем не просто выделить текст жирным, но и сделать на нем некий акцент с помощью выделения. Акцент может делаться для поисковых систем или каких-либо специальных браузеров или программ. Главное это не переборщить с акцентированием текста в статье или на странице с как-то информацией, так как это может губительно сказаться как минимум на продвижении данной HTML-страницы.
Итак, чтобы просто выделить текст жирным, мы можем воспользоваться тегом <b> . Данный тег относится к элементам физической разметки, при этом устанавливая жирное начертание текста, не делая на нем какого-либо акцента. Этот тег является парным, что говорит о том, что он имеет, как открывающий тег, так и закрывающий. Кроме того, так как элемент встроенный, он должен находиться в каком-либо блочном элементе, например <p>
Пример кода:
жирный текст
В этом случае мы просто выделили текст жирным начертанием и все.
Но бывает, так что нам нужно не просто выделить текст, а сделать на нем акцент. Для этого мы можем использовать тег логической разметки <strong> . Мало того, что текст, выделенный, этим тегом имеет больший вес для поисковых систем. Но и по идее он должен отличаться от тега <b> в речевых браузерах, например интонацией. Однако не могу ни подтвердить, ни опровергнуть данную информацию, так ли это?
В этом случае все абсолютно также как и в случае, с простым выделением жирным, только мы делаем акцент, а не просто выделение.
Пример кода:
текст, на котором мы сделали акцент
Все довольно просто, не правда ли?
Выделение текста курсивом.
В этом случае все не сложнее, чем в первом. И ситуация у нас абсолютно та же. Мы можем выделить текст двумя вариантами в HTML. Опять же, используя либо тег физической разметки или же тег логической, с помощью которого мы опять же делаем акцент на выделенный текст.
Чтобы выделить текст курсивом мы воспользуемся тегом <i> . Этот элемент является парным и строчным, что говорит нам о том, что мы должны использовать, как открывающий тег так и закрывающий. А также должны использовать его внутри блочного элемента. И в данном случае наиболее подходящий блочный элемент — тег параграфа <p> .
Пример кода:
текст курсивом
И конечно же мы можем сделать акцент на тексте одновременно выделив его курсивом с помощью тега <em> . Данный элемент такой же как <strong> , за исключением того что выделяется текст курсивом а не жирным.
Пример кода:
текст, на котором мы сделали акцент
И последнее о чем я хотел бы сегодня поговорить — это выделение текста цветом.
HTML выделение цветом.
К сожалению тега, для выделения текста цветом в HTML мы не имеем. Но все же и в этом способе нет ничего сложного.
Итак, чтобы выделить определенную часть текста цветом, мы можем обернуть нужную часть текста тегом <span> , который является универсальным тегом, и используется внутри блочного элемента. В нашем случае блочным элементом является тег <p> . Но добавить <span> недостаточно. Также необходимо указать параметр style , что позволит добавить CSS свойства необходимому тексту, указать само свойство ( color ), которое поможет задать определенный цвет. И наконец, указать значение для свойства color . Но может возникнуть вопрос: «Что указывать-то?» Указать необходимо HTML-код того цвета в который мы хотим «покрасить» текст. HTML-коды цветов можно найти здесь.
Теперь чтобы было понятней рассмотрим пример.
Пример кода.
В этом случае мы выделяем одно слово: цветом. Также хочу отметить, что тег <span> является парным, и мы должны его закрыть там, где свойство должно закончиться.
текст, который нужно выделить цветом
Такими нехитрыми способами мы можем манипулировать текстом на нашей странице. Хочу также отметить, что все то, о чем мы только что говорили, работает и на WordPress и на DLE, ибо любой движок для вывода страниц использует HTML. Именно поэтому HTML можно назвать основой основ любого сайта, не важно, какая у Вас CMS.