Novo recurso experimental: folhas de estilo com escopo

Alex Danilo

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

Exemplo

Confira 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 <div> de vermelho e em <span> de verde:

a div! um período!
a div! um span!
a div! um 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, ele restringe as regras de estilo para que sejam aplicadas ao <div> que é o pai do elemento <style scoped> e a qualquer item dentro apenas desse <div>. Chamamos isso de "escopo", e o resultado é semelhante a este:

um div! um período!
um div! um período!
um div! um espaço!

Isso pode ser feito em qualquer lugar da marcação. Portanto, se você gosta de aventuras, pode aninhar estilos com escopo em outras partes com escopo da marcação o quanto quiser para ter um controle preciso sobre onde os estilos são aplicados.

Casos de uso

Mas para que serve isto?

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

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

Quando quiser criar um 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ê divirta-se com o CSS na demonstração, mas nada mais na página será afetado.

Outro caso de uso é simplesmente o encapsulamento. Por exemplo, se sua 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 terão 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 itens 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 outras pessoas podem usar e combinar em um aplicativo da Web avançado. Planejamos usar muito o <style scoped> com componentes da Web e o shadow DOM, que já pode ser ativado ao definir a flag 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 o estilo inline. Portanto, os 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 "defensivamente" para navegadores que ainda não são compatíveis com <style scoped>, prefixando as 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 penalidade de desempenho no tempo de execução devido ao seletor mais complexo. O bom dessa abordagem é que ela permite uma abordagem de fallback otimizada até o dia em que <style scoped> tiver uma ampla compatibilidade e os seletores de ID possam ser simplesmente descartados.

Status

Como a implementação de folhas de estilo com escopo ainda é nova, elas estão ocultas por uma sinalização de tempo de execução no Chrome. Para ativá-los, você precisa de uma versão do Chrome 19 ou mais recente (no momento, o Chrome Canary), localize a entrada "Ativar <style scoped>" em chrome://flags (no final), clique em "Ativar" e reinicie o navegador.

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

Queremos incentivar todos os interessados no recurso a testá-lo e a nos contar sobre suas experiências, sejam elas boas, ruins e (talvez) os bugs.