- Выбор пользователя: все наследование не работает в Chrome 62
- 4 ответа
- Выделение и CSS
- Основы
- Свойства, поддерживаемые ::selection
- Настройка собственных эффектов выделения
- Анимирование выделения
- Многострочный текст
- Креативный подход к использованию ::selection и text-shadow
- ▍Выделение с длинными тенями
- ▍Эффект контурного текста
- ▍Эффект размытия
- ▍Тени текстов и производительность
- Выделяются ли элементы форм?
- Исследование свойства user-select
- Сценарии использования user-select
- ▍Текст и иконка
- ▍Флажки
- ▍Выделение всего текста
- Веб-приложения
- ▍Slack
- ▍Notion
- Не используйте глобальное отключение выделения
- Нехороший паттерн
- Выделение на мобильных устройствах
- Итоги
Выбор пользователя: все наследование не работает в Chrome 62
Я только что обновил Google Chrome на своем ПК и Mac до версии 62, и свойство CSS user-select: all перестало работать, правильно.
Если у вас есть родительский элемент с user-select , установленным на none, и дочерний элемент с user-select , установленным на all, свойство parent не будет корректно перезаписано.
Кто-нибудь еще сталкивался с этим и знает, является ли это ошибкой в новой версии Google Chrome или существует ли верный способ реализовать это?
Вот код, демонстрирующий проблему (используйте Chrome 62, чтобы увидеть проблему) — JSFiddle:
4 ответа
Это проблема браузера Chrome. Об ошибке уже сообщалось. Вы можете найти более подробную информацию об ошибке с другим (неработающим примером) на этот отчет об ошибке.
Пока ошибка не устранена, у вас есть возможность использовать JavaScript для определения поведения. См. этот ответ в StackOverflow.
Другое решение, отличное от JavaScript, будет следующим:
Убедитесь, что никто из ваших детей не имеет: all: none , который сбрасывает все свойства, как я сделал. Если дело обстоит так ниже all: none , просто добавьте user-select: none (Chrome).
Я только что нашел простое решение этой проблемы, которое заключается в следующем:
В вашем файле CSS есть следующее:
В вашем HTML-файле теперь вы можете иметь следующее (например):
Обертывание div с идентификатором «myTextToBeSelectedByOneClick» (имеющего класс «allowSelectOneClick») в div с идентификатором «myTextContainer» (имеющим класс «allowSelect») — это прием, который делает эту работу.
Без div с идентификатором «myTextContainer» он не работает.
Выше тестируется в Chrome версии 65.0.3325.181
Попробуйте изменить user-select:all на user-select:text
Источник
Выделение и CSS
Навык выделения текста и других объектов сформировался у пользователей компьютеров много лет назад. Мы выделяем содержимое веб-страниц по разным причинам. Возможно, нужно скопировать текст и где-то его процитировать, возможно — кому-то просто легче читать текст, выделяя его фрагменты. На мобильных устройствах, правда, выделять что-либо сложнее. Меня, например, это раздражает. Мне не нравится выделять содержимое веб-страниц на телефоне. Эта операция кажется какой-то «неправильной».
В этом материале я расскажу обо всём, что нужно знать о стилизации выделений средствами CSS. В частности, речь пойдёт о псевдоэлементе ::selection и о свойстве user-select . Эта статья направлена на то, чтобы показать всем желающим возможности CSS по работе с выделениями, и на то, чтобы рассказать о том, когда и как использовать разные методы работы с выделениями.
Основы
На MDN можно узнать о том, что псевдоэлемент ::selection позволяет применить стили к части документа, который был выделен пользователем (например, с помощью мыши).
Для использования ::selection достаточно воспользоваться следующей конструкцией:
Вот пример, с которым можно поэкспериментировать.
Свойства, поддерживаемые ::selection
Стоить отметить, что псевдоэлемент ::selection поддерживает только свойства color , background и text-shadow .
Настройка собственных эффектов выделения
Что если нам нужно, чтобы выделение выглядело бы по-особенному? Например, чтобы выделение имело бы определённую высоту или некий интересный фон? Взгляните на следующий рисунок.
Пример особой настройки выделения
Это возможно, хотя и потребует приложения некоторых усилий. Вот как сделано выделение, показанное выше:
- Добавлен псевдоэлемент, с тем же текстом, который мы выделяем. Затем псевдоэлементу задано свойство height: 50% и белый фоновый цвет.
- Псевдоэлемент расположен над исходным текстом.
Если теперь выделить текст, то псевдоэлемент перекроет 50% текста по вертикали. Это позволяет сымитировать нужный нам эффект.
Об этой методике я узнал здесь.
Ещё один вариант подобного выделения представлен ниже. Здесь я, вместо сплошного выделения, реализовал выделение в виде CSS-градиента. Смысл тут заключается в использовании белого градиента с высотой в 50% и в однократном заполнении элемента фоновым рисунком благодаря использованию значения no-repeat при настройке свойства background .
На следующем рисунке показано разъяснение этой методики.
Реализация градиентного выделения
Надеюсь, я смог понятно объяснить эту идею. Вот рабочий пример.
Анимирование выделения
Работая над предыдущим примером, я задался следующим вопросом: «Реально ли анимировать выделение?». Например, в процессе выделения текста высота выделения составляет 50%. А когда указатель мыши уводят в сторону, высота выделения увеличивается до 80%. Как это сделать? А вот так:
Текст в процессе выделения
Текст после завершения выделения
Вот видео, в котором демонстрируется анимированное выделение.
Многострочный текст
Представленная выше методика настройки выделения, к сожалению, не подходит для многострочного текста. Для того чтобы, всё же, реализовать нечто подобное и для такого текста, нужно прибегнуть к возможностям JavaScript и поместить каждое слово во встроенный (строчный) элемент, например — в . После того, как каждое слово окажется в собственном элементе , к каждому из таких элементов надо добавить псевдоэлемент. А уже после этого к многострочному тексту можно применить вышеописанный эффект.
Вот скрипт, позволяющий поместить каждое слово в -контейнер:
После этого элементы надо стилизовать. Затем к каждому из них надо добавить псевдоэлемент:
Если посмотреть на эту конструкцию в деле, то окажется, что она работает, но не совсем так, как можно ожидать. Ниже показан пример выделения многострочного текста. Можно заметить, что выделение выглядит неоднородным.
Я бы сказал, что подобное многострочное выделение получается не очень хорошим, и что его не стоит использовать в глобальном масштабе. Возможно, его стоит применять лишь, скажем, для организации выделения какого-то отдельного абзаца.
Тут с таким выделением можно поэкспериментировать.
Креативный подход к использованию ::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 . В результате всё, что не должно выделяться, скорее всего, не должно быть видимым и для средств чтения с экрана.
▍Флажки
Меня раздражает такое поведение флажков, когда, устанавливая или снимая флажок, я случайно выделяю текст его описания. Вот как это выглядит.
Текст описания флажка выделен случайно
Решить эту проблему можно, стилизовав элемент следующим образом:
▍Выделение всего текста
Значение 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. Возможно, вам интересно будет взглянуть и на этот материал.
Уважаемые читатели! Как вы настраиваете выделение текстов в своих проектах?
Источник