Изменения наследования для стиля выбора CSS

Опубликовано: 8 октября 2024 г.

Начиная с Chrome 131, наследование подсветки CSS меняется для псевдоклассов ::selection и ::target-text . Это делается для того, чтобы создать более интуитивную модель наследования и согласовать ее с недавно добавленными псевдоклассами ::highlight , ::spelling-error и ::grammar-error . В этом посте объясняется изменение, которое не должно оказать заметного влияния на большинство сайтов.

Стиль выделения

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

CSS поддерживает стиль выбора с помощью псевдоэлемента ::selection , одного из набора псевдоэлементов, известных как псевдоэлементы выделения . Эти псевдоэлементы управляют тем, как текст отображается при различных действиях пользователя, браузера или сценария. Помимо выделения, вы можете стилизовать орфографические ошибки ( ::spelling-error ), грамматические ошибки ( ::grammar-error ), текстовые целевые объекты, встроенные в URL-адрес ( ::target-text ), а также выделенные фрагменты, созданные скриптом ( ::highlight ).

Как и в случае с любым набором свойств CSS, поведение наследования является важным фактором при проектировании сайта. В общем, разработчики ожидают, что свойства CSS будут либо наследоваться через дерево элементов DOM (например, font ), либо вообще не наследоваться (например, background ).

Изменения в поведении выбора в Chrome 131

Рассмотрим этот фрагмент документа:

p {
  color: red;
}

.blue::selection {
  color: blue;
}
<p class="blue">Some <em>emphasized</em> text that one would expect to be blue</p>

Объявления стиля фрагмента изменяют цвет выделенного текста, при этом одно правило соответствует всем элементам, а другое — элементам класса "blue" . При выборе в Chrome 130 или более ранней версии результат будет следующим:

Текст, который, как вы могли ожидать, будет синим, является красным.

При выборе в Chrome 131 результат меняется на следующий:

Текст теперь выделен синим цветом.

Что изменилось? Поведение наследования свойств выбора исторически реализовывалось посредством наследования исходного элемента , где выбор использует свойства из ::selection , соответствующего выбираемому элементу. Версия Chrome 130 и более ранние используют эту модель, в которой выделенный текст не имеет соответствия ::selection , поскольку .blue::selection соответствует только элементам с классом "blue" , которого нет в элементе <em> .

В Chrome 131 реализовано новое поведение, при котором элементы наследуют поведение выбора от своего родителя. В предыдущем примере элемент <em> не имеет соответствия самому ::selection , поэтому он наследует цвета выделения элемента <p> . Это называется наследованием подсветки CSS , и вы можете попробовать его в более ранних версиях Chrome, включив функции экспериментальной веб-платформы в chrome://flags .

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

Пользовательские свойства CSS для выбора все еще работают

Многие сайты имитируют наследование подсветки CSS с помощью пользовательских свойств CSS. Пользовательские свойства наследуются через дерево элементов, что дает результат «наследовать от родителя» с помощью такого фрагмента кода:

:root {
   --selection-color: lightgreen;
}

::selection {
  color: var(--selection-color);
}

.blue {
  --selection-color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text that is blue</p>

Вот результат при выборе в Chrome 130 и 131:

Первая линия зеленая, вторая синяя.

Здесь каждый элемент наследует некоторое значение свойства --selection-color через дерево элементов, и этот цвет используется при выборе текста. Элементы с классом .blue и их потомки при выборе имеют синий цвет, а другие элементы — светло-зеленый. Многие сайты используют этот метод, и этот метод рекомендуется при переполнении стека.

Для обеспечения совместимости модель наследования выделения CSS определяет, что ::selection (и другие псевдоэлементы выделения CSS) наследуют значения пользовательских свойств от исходного элемента (элемента, к которому они применяются). На сайты, использующие этот метод, изменения в Chrome 131 не должны повлиять.

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

Универсальные селекторы для ::selection отключают наследование выделения

Сайты, не использующие пользовательские свойства CSS, возможно, использовали универсальный селектор для установки выбранного цвета текста. Например, как следующий CSS:

::selection /* = *::selection (universal) */ {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

Вот результат при выборе как в Chrome 130 (и более ранних версиях), так и в Chrome 131 (и более поздних версиях):

Первая строка текста имеет зеленый цвет. Второй — синий, но выделенное слово — зеленое.

Наследование выделения CSS не приводит к тому, что второй выделенный текст наследует синий цвет от своего родителя, поскольку универсальный селектор соответствует элементу <em> и применяет универсальный цвет выделения, светло-зеленый.

Чтобы воспользоваться преимуществами наследования выделения CSS, измените универсальный селектор так, чтобы он соответствовал только корню, который затем будет унаследован его потомками:

:root::selection {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

Результат в Chrome 131 выглядит так:

Первая строка текста имеет зеленый цвет. Вторая линия синяя.

Если ваш сайт изменяет цвета выделения, но не использует пользовательские свойства, вполне вероятно, что у вас есть универсальный селектор для псевдо- ::selection . Хорошей новостью является то, что ваш сайт не изменится из-за этого изменения в Chrome, но вы упустите любые эргономические преимущества от наследования выделенных фрагментов.

::target-text также меняется

Все описанные здесь варианты поведения и изменения применяются к псевдоэлементу ::target-text так же, как и к ::selection . Варианты использования нескольких стилей целевого текста на одном сайте ограничены, а эта функция довольно новая, поэтому маловероятно, что ваш сайт изменится в поведении ::target-text .

Почему это изменение?

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

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

Попробуйте это

Следующий CodePen демонстрирует изменения. Попробуйте это в Chrome 131.