Novo recurso experimental: folhas de estilo com escopo

Alex Danilo

Recentemente, o Chromium implementou um novo recurso do HTML5: folhas de estilo com escopo, também conhecido como <style scoped>. Um autor da Web pode limitar as regras de estilo para que sejam aplicadas somente a uma parte da página. Para isso, defina o atributo "escopo" em um elemento <style> que seja filho direto do elemento raiz da subárvore em que você quer aplicar os estilos. Isso limita os estilos a afetar apenas o elemento pai do elemento <style> e todos os descendentes dele.

Exemplo

Este é um documento simples que usa o estilo padrão:

<html>
<body>
    <div>a div! <span>a span!</span></div>
    <div>
        <style>
        div { color: red; }
        span { color: green; }
        </style>
        a div! <span>a span!</span></div>
    <div>a div! <span>a span!</span></div>
</body>
</html>

As regras de estilo especificadas vão colorir o texto em qualquer <div> de vermelho e dentro de qualquer <span> de verde:

a div! a span!
a div! a span!
a div! a span!

No entanto, se definirmos scoped no elemento <style>:

<html>
<body>
    <div>a div! <span>a span!</span></div>
    <div>
        <style scoped>
        div { color: red; }
        span { color: green; }
        </style>
        a div! <span>a span!</span></div>
    <div>a div! <span>a span!</span></div>
</body>
</html>

Em seguida, ela restringe as regras de estilo para que sejam aplicadas ao <div> incluído, que é o pai do elemento <style scoped> e a qualquer item dentro desse <div>. Chamamos isso de "escopo", e o resultado tem esta aparência:

um div! um span!
um div! um span!
um div! um span!

Isso pode ser feito em qualquer lugar da marcação. Então, se você for aventureiro, poderá aninhar estilos com escopo em outras partes do escopo da marcação o quanto quiser para ter um controle refinado sobre onde os estilos são aplicados.

Casos de uso

Para que serve isso?

Um caso de uso comum é o conteúdo distribuído: quando você, como autor da Web, gostaria de incorporar conteúdo de um terceiro, incluindo todos os seus estilos, mas não quer arriscar que esses estilos "poluam" outras partes não relacionadas da página. Uma grande vantagem aqui é a capacidade de combinar o conteúdo de outros sites, como Yelp, Twitter, ebay, etc. em uma única página, sem a necessidade de isolá-los usando um <iframe> ou editar instantaneamente o conteúdo externo.

Se estiver usando um sistema de gerenciamento de conteúdo (CMS) que envia snippets de marcação que são todos misturados em uma exibição final da página, esse é um ótimo recurso para garantir que cada snippet seja estilizado de forma isolada de qualquer outro elemento na página. Isso também pode ser útil para uma wiki.

Quando você quer criar um bom código de demonstração em uma página, é fácil limitar os estilos apenas ao conteúdo de demonstração. Isso permite que você aproveite o CSS na demonstração, mas nada mais na página será afetado.

Outro caso de uso é o encapsulamento. Por exemplo, se a página da Web tiver um menu lateral, faz sentido colocar estilos específicos desse menu em uma seção <style scoped> nessa parte da marcação. Essas regras de estilo não têm efeito na renderização de outras partes da página, o que as mantém bem separadas do conteúdo principal.

Possivelmente, um dos casos de uso mais interessantes é para o modelo de componentes da Web. Os componentes da Web serão uma ótima maneira de criar coisas como controles deslizantes, menus, seletores de data, widgets de guia etc. Ao fornecer os estilos com escopo, um designer pode criar um widget e empacotá-lo com seus estilos como uma unidade independente que outros podem usar e combinar em um aplicativo da Web avançado. Planejamos usar <style scoped> intensamente com os Componentes da Web e o shadow DOM. Essa opção já pode ser ativada configurando a sinalização experimental "shadow DOM" em chrome://flags. No momento, não há uma boa maneira de garantir que os estilos sejam limitados aos Web Components sem recorrer a práticas inadequadas, como estilo inline, de modo que estilos com escopo são perfeitos para isso.

Por que incluir o elemento pai?

A maneira mais natural é incluir o elemento pai para que as regras <style scoped> possam, por exemplo, definir uma cor de plano de fundo comum para todo o escopo. Ele também permite que folhas de estilo com escopo sejam escritas "de forma defensiva" para navegadores que ainda não oferecem suporte a <style scoped>, prefixando regras com um ID ou seletor de classe como substituto:

<div id="menu">
    <style scoped>
    #menu .main { … }
    #menu .sub { … }
    …

Isso imita o efeito do uso de estilos quando "escopo" é implementado, mas com alguma queda de desempenho no tempo de execução devido ao seletor mais complexo. O bom dessa abordagem é que ela permite uma abordagem substituta otimizada até o dia em que o <style scoped> tiver ampla compatibilidade e os seletores de ID puderem ser simplesmente descartados.

Status

Como a implementação de folhas de estilo com escopo ainda é nova, elas estão ocultas por uma flag de tempo de execução no Chrome. Para ativá-las, faça o download de uma versão do Chrome com o número 19 ou superior (Chrome Canary atualmente), localize a entrada "Ativar <style scoped>" em chrome://flags (perto do fim), clique em "Ativar" e reinicie o navegador.

No momento, não há bugs conhecidos, mas @global e as versões com escopo de @keyframes e @-webkit-region ainda estão em processo de implementação. Além disso, o @font-face é ignorado por enquanto, já que há uma boa chance de a especificação mudar.

Incentivamos todos os interessados no recurso a testá-lo e a nos contar sobre suas experiências: as boas, as ruins e (talvez) as dificuldades.