Cambios de herencia para el diseño de selección de CSS

Fecha de publicación: 8 de octubre de 2024

A partir de Chrome 131, la herencia de elementos destacados de CSS cambiará para ::selection y Pseudoclases ::target-text. Esto sirve para crear un modelo más intuitivo para heredar y alinearse con el ::highlight, ::spelling-error que se agregó recientemente y Seudoclases ::grammar-error. En esta publicación, se explica el cambio, que no debería causar un impacto visible para la mayoría de los sitios.

Estilos de selección

Aplicar diseño al aspecto del texto seleccionado puede transmitir significado a los usuarios, como el propósito del contenido seleccionado o la imposibilidad de seleccionar el texto. GitHub, por ejemplo, cuando se selecciona el código de manera diferente al directorio seleccionado en la nube.

CSS admite estilos de selección con la ::selection pseudoelemento, uno de un conjunto de pseudoelementos conocidos como destacar seudoelementos. Estos pseudoelementos controlan cómo aparece el texto en varias acciones del usuario, del navegador o de la secuencia de comandos. Además de la selección, puedes darle estilo a la ortografía errores (::spelling-error), errores gramaticales (::grammar-error), texto incorporado en una URL objetivos (::target-text) y elementos destacados generados por secuencias de comandos (::highlight).

Al igual que con cualquier colección de propiedades CSS, el comportamiento de herencia es una consideración importante cuando se diseña un sitio. En general, los desarrolladores esperan que las propiedades de CSS se hereden a través del árbol de elementos del DOM (por ejemplo, font) o que no se hereden en absoluto (por ejemplo, background).

Cambios en el comportamiento de selección en Chrome 131

Considera este fragmento de documento:

p {
  color: red;
}

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

Las declaraciones de estilo del fragmento modifican el color del texto seleccionado, con una regla que coincide con todos los elementos y una que coincide con los que tienen la clase "blue". Cuando se selecciona en Chrome 130 o versiones anteriores, este es el resultado:

El texto que debería ser azul es rojo.

Cuando se selecciona en Chrome 131, el resultado cambia a lo siguiente:

El texto ahora se destaca en azul.

¿Qué cambió? El comportamiento de herencia de las propiedades de selección se implementaron históricamente a través de la herencia de elementos de origen, donde la selección usa las propiedades de un ::selection que coincide con el elemento que se está seleccionando. Las versiones 130 y anteriores de Chrome usan este modelo, en el que el texto destacado no tiene ::selection coincidente porque .blue::selection solo coincide con elementos de la clase "blue", que no tiene el elemento <em>.

Chrome 131 habilita un nuevo comportamiento, mediante el cual los elementos heredan el comportamiento de selección de de sus padres. En el ejemplo anterior, el elemento <em> no tiene ::selection. coincide con sí mismo, por lo que hereda los colores de selección del elemento <p>. Esto se conoce como herencia de elementos destacados de CSS y puedes probarlo en versiones anteriores de Chrome habilitando las funciones experimentales de la plataforma web en chrome://flags.

Es probable que los sitios que dependen de propiedades de selección no heredadas vean cambios, en la apariencia del texto seleccionado, pero la evidencia de los informes de errores sugiere que hay hay pocos casos de uso para este comportamiento.

Las propiedades personalizadas de CSS para la selección siguen funcionando

Muchos sitios simulan la herencia de los elementos destacados de CSS a través del uso de propiedades personalizadas de CSS. Las propiedades personalizadas se heredan a través del árbol de elementos, lo que genera el resultado "heredar de elemento superior" con un fragmento de código como el siguiente:

: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>

Este es el resultado cuando se selecciona en Chrome 130 y 131:

La primera línea es verde y la segunda es azul.

Aquí, cada elemento hereda algún valor de la propiedad --selection-color. a través del árbol de elementos. Este color se usa cuando se selecciona el texto. Los elementos con la clase .blue y sus descendientes son azules cuando se seleccionan, y los demás elementos son de color verde claro. Muchos sitios usan esta técnica, y es el método que se recomienda en Stack Overflow.

Para mantener la compatibilidad, el modelo de herencia de CSS Highlight especifica que ::selection (y otros seudoelementos de CSS Highlight) heredan valores de propiedades personalizadas de su elemento de origen (el elemento al que se aplican). Los sitios que usen este método no deberían verse afectados por los cambios en Chrome 131.

Se ignoran las propiedades personalizadas definidas en el pseudoelemento ::selection para evitar comportamientos de herencia en competencia. Debes definir las propiedades en el elemento en sí y, luego, hacer referencia a ellas en el elemento pseudo.

Los selectores universales para ::selection inhabilitan la herencia de resaltado

Es posible que los sitios que no usan propiedades personalizadas de CSS hayan utilizado un selector universal para establecer el color de texto seleccionado. Como el siguiente CSS, por ejemplo:

::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>

Este es el resultado cuando se selecciona en Chrome 130 (y versiones anteriores) y Chrome 131 (y versiones posteriores):

La primera línea de texto es verde. El segundo es azul, pero la palabra enfatizada, verde.

La herencia de CSS Highlight no hace que el segundo texto destacado herede el color azul de su elemento superior porque el selector universal coincide con el elemento <em> y aplica el color de resaltado universal, verde claro.

Para obtener los beneficios de la herencia de resaltado de CSS, cambia el selector universal para que coincida solo con la raíz, que luego heredarán sus elementos subordinados:

:root::selection {
  color: lightgreen;
}

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

El resultado en Chrome 131 se ve de la siguiente manera:

La primera línea de texto es verde. La segunda línea es azul.

Si tu sitio modifica los colores de la selección, pero no usa propiedades personalizadas, es lo más probable es que tengas un selector universal para el seudo ::selection. Lo bueno es que tu sitio no romperá con este cambio en Chrome, pero perderse todos los beneficios ergonómicos de la herencia de atributos.

También cambiará el diseño de ::target-text.

Todos los comportamientos y cambios que se describen aquí se aplican a ::target-text. seudoelemento, como lo hacen con ::selection. Los casos de uso de más de un el estilo de texto de destino en un solo sitio son limitados y la función es bastante nueva, por lo que es muy poco probable que cambie el comportamiento de ::target-text en tu sitio.

¿Por qué se realizó este cambio?

Cuando los otros seudoelementos destacados estaban en desarrollo, el CSS en funcionamiento El grupo resolvió implementar la herencia con el modelo de herencia de resaltado. Este ya era el método en la especificación de ::selection seudoelemento, pero los navegadores no lo implementaron. Los pseudoelementos que no son de selección usan la herencia de resaltado, en la que el pseudoelemento se hereda como si fuera una propiedad. Es decir, los elementos heredan el elemento destacado seudoelementos del elemento superior del documento.

Para mantener la coherencia en todos los seudos destacados, el CSS funciona El grupo reiteró su apoyo a la herencia de contenido destacado para ::selection. los navegadores están trabajando para iniciar el nuevo comportamiento, al tiempo que intentan no romper de los sitios existentes.

Probar

En el siguiente CodePen, se muestran los cambios. Pruébala en Chrome 131.