Mudanças de herança para o estilo de seleção de CSS

Publicado em 8 de outubro de 2024

A partir do Chrome 131, a herança de destaque do CSS vai mudar para as pseudoclasses ::selection e ::target-text. Isso é para criar um modelo mais intuitivo para herança e se alinhar com as pseudoclasses ::highlight, ::spelling-error e ::grammar-error adicionadas recentemente. Esta postagem explica a mudança, que não deve causar um impacto visível na maioria dos sites.

Estilo da seleção

Dar estilo à aparência do texto selecionado pode transmitir significado aos usuários, como o propósito do conteúdo selecionado ou a incapacidade de selecionar o texto. O GitHub, por exemplo, colore o código selecionado de maneira diferente da estrutura do diretório selecionado.

O CSS oferece suporte a estilos de seleção com o pseudoelemento ::selection, um de um conjunto de pseudoelementos conhecidos como pseudoelementos de destaque. Esses pseudoelementos controlam como o texto aparece em várias ações do usuário, do navegador ou do script. Além da seleção, você pode estilizar erros de ortografia (::spelling-error), erros de gramática (::grammar-error), destinos de texto incorporados a URLs (::target-text) e destaques gerados por script (::highlight).

Como acontece com qualquer coleção de propriedades CSS, o comportamento de herança é uma consideração importante ao projetar um site. Em geral, os desenvolvedores esperam que as propriedades CSS sejam herdadas pela árvore de elementos DOM (por exemplo, font) ou que não sejam herdadas (por exemplo, background).

Mudanças no comportamento de seleção no Chrome 131

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

As declarações de estilo do fragmento modificam a cor do texto selecionado, com uma regra que corresponde a todos os elementos e outra que corresponde aos elementos com a classe "blue". Quando selecionado no Chrome 130 ou versões anteriores, o resultado é este:

O texto que deveria ser azul é vermelho.

Quando selecionado no Chrome 131, o resultado muda para:

O texto agora está em destaque em azul.

O que mudou? O comportamento de herança das propriedades de seleção foi implementado historicamente pela herança do elemento de origem, em que a seleção usa as propriedades de um ::selection que corresponde ao elemento que está sendo selecionado. As versões 130 do Chrome e anteriores usam esse modelo, em que o texto destacado não tem ::selection correspondente porque o .blue::selection corresponde apenas a elementos com a classe "blue", que não tem o elemento <em>.

O Chrome 131 ativa um novo comportamento em que os elementos herdam o comportamento de seleção do elemento pai. No exemplo anterior, o elemento <em> não tem um ::selection que corresponda a ele mesmo. Portanto, ele herda as cores de seleção do elemento <p>. Isso é chamado de herança de destaque do CSS, e você pode testá-lo em versões anteriores do Chrome ativando os recursos experimentais da plataforma da Web em chrome://flags.

Sites que dependem de propriedades de seleção que não são herdadas provavelmente vão notar mudanças na aparência do texto selecionado, mas evidências de relatórios de bugs sugerem que há poucos casos de uso para esse comportamento.

As propriedades personalizadas de CSS para seleção ainda funcionam

Muitos sites simulam a herança de destaque do CSS usando propriedades personalizadas do CSS. As propriedades personalizadas são herdadas pela árvore de elementos, fornecendo o resultado "herdar do pai" com um snippet de código como este:

: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 é o resultado quando selecionado no Chrome 130 e 131:

A primeira linha é verde, a segunda é azul.

Aqui, cada elemento herda algum valor para a propriedade --selection-color pela árvore de elementos, e essa cor é usada quando o texto é selecionado. Os elementos com a classe .blue e os descendentes deles ficam azuis quando selecionados, e os outros elementos ficam verdes claros. Muitos sites usam essa técnica, que é o método recomendado no Stack Overflow.

Para manter a compatibilidade, o modelo de herança de destaque do CSS especifica que ::selection (e outros pseudoelementos de destaque do CSS) herdam valores de propriedade personalizados do elemento de origem (aquele em que estão sendo aplicados). Os sites que usam esse método não serão afetados pelas mudanças no Chrome 131.

As propriedades personalizadas definidas no pseudoelemento ::selection são ignoradas para evitar comportamentos de herança concorrentes. É necessário definir as propriedades no elemento e, em seguida, fazer referência a elas no pseudoelemento.

Os seletores universais para ::selection desativam a herança de destaque

Os sites que não usam propriedades personalizadas do CSS podem ter usado um seletor universal para definir a cor do texto selecionado. Por exemplo, o CSS a seguir:

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

Esse é o resultado quando selecionado no Chrome 130 (e versões anteriores) e no Chrome 131 (e versões mais recentes):

A primeira linha de texto é verde. O segundo é azul, mas a palavra enfatizada é verde.

A herança de destaque do CSS não faz com que o segundo texto em negrito herde a cor azul do elemento pai porque o seletor universal corresponde ao elemento <em> e aplica a cor de destaque universal, verde claro.

Para aproveitar os benefícios da herança de destaque do CSS, altere o seletor universal para corresponder apenas à raiz, que será herdada por seus descendentes:

:root::selection {
  color: lightgreen;
}

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

O resultado no Chrome 131 é semelhante a este:

A primeira linha de texto é verde. A segunda linha é azul.

Se o site modificar as cores de seleção, mas não usar propriedades personalizadas, é provável que você tenha um seletor universal para o pseudoelemento ::selection. A boa notícia é que seu site não será corrompido com essa mudança no Chrome, mas você deixará de aproveitar os benefícios ergonômicos da herança de destaque.

O estilo do ::target-text também está mudando

Todos os comportamentos e mudanças descritos aqui se aplicam ao pseudoelemento ::target-text assim como a ::selection. Os casos de uso para mais de um estilo de texto de destino em um único site são limitados, e o recurso é bastante novo, portanto, é muito improvável que o comportamento do ::target-text mude no seu site.

Qual é o motivo da mudança?

Quando os outros pseudoelementos de destaque estavam em desenvolvimento, o grupo de trabalho de CSS resolveu implementar a herança com o modelo de herança de destaque. Esse já era o método na especificação do pseudoelemento ::selection, mas os navegadores não o implementaram. Os pseudoelementos não de seleção usam a herança de destaque, em que o pseudoelemento é herdado como se fosse uma propriedade. Ou seja, os elementos herdam os pseudoelementos de destaque do documento pai.

Para manter a consistência em todos os pseudos de destaque, o grupo de trabalho do CSS reiterou o suporte à herança de destaque para ::selection, e os navegadores estão trabalhando para lançar o novo comportamento, tentando não quebrar os sites existentes.

Faça um teste

O CodePen a seguir demonstra as mudanças. Faça um teste no Chrome 131.