CSS

16 abr, 2014

Modularização CSS com seletores multi-classe

Publicidade

As recomendações do W3C para seletores CSS, desde sua versão 1, prevêem o seletor classe destinado a casar com elementos da marcação HTML para os quais tenha sido definido o atributo class e respectivo valor. A sintaxe para esse seletor é composta de um ponto (.) imediatamente seguido pelo valor definido para o atributo class.

Sintaxe: .valor

No exemplo a seguir, a regra CSS mostrada usa o seletor classe para criar uma borda sólida de 1px na cor verde em todos os elementos da página que tenham sido marcados com o par atributo/valor class = "borda".
.borda { border: 1px solid green; }

OK, até aqui nenhuma novidade e alguém já afirmou que seletores é um dos primeiros assuntos que os iniciantes em CSS aprendem. E vou além, afirmando que o seletor classe é um dos primeiros seletores que os novatos em CSS aprendem e usam.

Seletores multi-classe

As recomendações do W3C para seletores CSS em qualquer uma de suas versões não denominam formalmente um seletor chamado multi-classe, mas eles existem, e estes sim, não são tão conhecidos como o seletor classe (não só pelos iniciantes como também por desenvolvedores com algum conhecimento e prática com as CSS). E, em vários casos, apesar de conhecidos, são usados de forma simplista sem que se explore todo seu potencial.

Valores atribuídos ao seletor classe não precisam ser únicos. A especificação para as CSS, no item dedicado ao seletor classe, prevê que um conjunto de valores separados por espaço pode ser usado como valor do atributo classe, como mostrado na marcação HTML a seguir:

<span style="line-height: 1.5em;">&lt;p class="box borda"&gt;Parágrafo 1 com classes box e borda&lt;/p&gt;
</span>&lt;p class="box borda cor"&gt;Parágrafo 2 com classes box, borda e cor&lt;/p&gt;
&lt;p class="borda cor"&gt;Parágrafo 3 com classe borda&lt;/p&gt;

Elementos marcados com o atributo classe, cujo valor é uma lista de valores – como mostrado no exemplo de marcação anterior -, podem ser casados com um seletor multi-classe. Mas esteja ciente de que esta (multi-classe) é uma denominação informal, e portanto não oficial, para o seletor.

A sintaxe para esse seletor é formada pelo encadeamento da sintaxe para seletor classe sem uso de espaços.

Sintaxe: .valor1.valor2

No exemplo a seguir, a regra CSS mostrada usa o seletor multi-classe para criar uma borda sólida de 1px na cor verde em todos os elementos da página que tenham sido marcados com o atributo classe, cujo valor seja uma lista de valores contendo ambos os valores box e borda.

.box.borda { border: 1px solid green; }

O seletor mostrado casa com os parágrafos 1 e 2 da marcação anterior.

Seletores multi-classe não estão limitados a dois valores de classe. Pode-se usar tantos valores da lista, quantos forem necessários para criar o seletor. Por exemplo:

.box.borda.cor { border: 1px solid green; }

O seletor mostrado casa com o parágrafo 2 da marcação anterior.

Atenção: Cuidado com a sintaxe. Os seletores .box, .borda, e .box.borda são completamente diferentes. O primeiro é um seletor descendente que casa com elementos aos quais foi atribuída a classe borda e que sejam elementos descendentes do elemento ao qual foi atribuída a classe box. O segundo é um seletor multi-classe que casa com o elemento ao qual foi atribuído um valor para o atributo classe, constituído por uma lista de nomes na qual conste os nomes box e borda.

A seguir, citamos algumas dicas práticas sobre os seletores multi-classe:

  • A ordem em que se declara uma lista de valores de classe na marcação HTML é irrelevante;
  • A ordem em que se escreve o seletor na regra CSS é irrelevante;
  • A especificidade de um seletor seletor multi-classe é igual à soma da especificidade de dois seletores classe simples;
  • Dúvida com especificidade? Consulte: A especificidade e o efeito cascata;
  • Não há limite para os valores de classe a serem declarados na marcação HTML;
  • É valido usar tantos valores de classe quanto se queira ao criar um seletor multi-classe;
  • Exemplos de uso do seletor multi-classe.

Apresentamos a seguir alguns exemplos de uso destinados a ilustrar o funcionamento dos seletores multi-classe:

Exemplo 1

Necessidade: Os cabeçalhos nível 1 do site serão apresentados em duas cores: #039 (azul) ou #f60 (laranja).

Solução: Definir dois valores de classe, por exemplo: h1cor-a e h1cor-b, aplicá-las aos cabeçalhos na marcação HTML e criar duas regras CSS como mostrado a seguir:

CSS

<span style="line-height: 1.5em;">.h1cor-a { color: #039; } /* azul */</span>
.h1cor-b { color: #f60; } /* laranja */

HTML

<h1 class="h1cor-a>Cabeçalho cor azul</h1>
<h1 class="h1cor-b>Cabeçalho cor laranja</h1>

Para usar seletor multi-classe e obter o mesmo efeito as CSS e a marcação HTML deverão ser como mostradas a seguir:

CSS

<span style="line-height: 1.5em;">.h1cor-a { color: #039; } /* azul */</span>
.h1cor-b.h1cor-b { color: #f60; } /* laranja */

HTML

<span style="line-height: 1.5em;">&lt;h1 class="h1cor-a&gt;Cabeçalho cor azul&lt;/h1&gt;</span>
&lt;h1 class="h1cor-a h1cor-b&gt;Cabeçalho cor laranja&lt;/h1&gt;

Cabem duas perguntas sobre este exemplo:

  • Pergunta 1: Por que não definir os valores de classe como sendo azul e laranja em lugar de h1cor-a e h1cor-b? Isso não serias mais natural?Resposta: NÃO! A “regra de ouro” ao se definir um valor de classe (ou id) é escolher um nome em acordo com a finalidade estrutural, não se devendo considerar na escolha a finalidade de apresentação ou estilização. Suponha que no futuro um redesign do site altere as cores dos cabeçalhos para vermelho e verde. Conclua você mesmo.
  • Pergunta 2: Seria esse exemplo 1 um contra-exemplo, uma vez que demonstra claramente que o uso de seletor multi-classe é uma “furada”?Resposta: SIM! Aplicar seletor multi-classe da forma simplista como foi ilustrado no exemplo não é aconselhável. O exemplo foi mostrado com a finalidade única de demonstar como usar e como funciona o seletor. A seguir mostraremos um exemplo mais convincente.

OOCSS — Modularização e outras buzzwords

O campo de atuação em que os seletores multi-classe mostram toda sua força e utilidade é quando desenvolvemos CSS para grandes sites ou aplicações que requerem extensas folhas de estilos mantidas e manipuladas por vários membros do time.

Necessidade: o site usará, em áreas diferentes, boxes responsivos para apresentação de conteúdos. Os boxes serão estilizados em três diferentes maneiras para serem servidos às três diferentes áreas existentes no site, conforme mostrado na figura a seguir:

seletor-multi-classe

A estilização dos boxes deverá ser modularizada, permitindo qualquer combinação de cores entre os elementos visuais do box, quer seja alterando as cores de estilização das diferentes áreas (manipulando as CSS globalmente — redesign do site) ou criando novos boxes a serem usados em novas áreas do site (criando marcação HTML — expansão do site).

Solução: Desenvolver marcação única (modular) para o box e nela criar condições de se estilizar diferenciadamente, com uso de seletores multi-classe conforme mostrado a seguir:

CSS

html, body {
 margin: 0;
 padding: 0;
 font: 62.5%/1.3 sans-serif;
 }
 *, *:before, *:after {
 -webkit-box-sizing: border-box;
 -moz-box-sizing: border-box;
 box-sizing: border-box;
 }
 .box {
 width: 20%;
 float:left;
 min-height:20rem;
 margin:2% 1%;
 padding: 0.5% 2%;
 line-height:1.2;
 border-radius: 1rem;
 }
 .borda1 { border: 0.5rem solid #900; } /* marrom */
 .borda2 { border: 0.5rem solid #060; } /* verde */
 .borda3 { border: 0.5rem solid #f00; } /* vermelho */
 .cor1 { color: #0b0ce8; } /* azul */
 .cor2 { color: #000000; } /* preto */
 .cor3 { color: #cc3300; } /* vermelho */
 .fundo1 { background: #ffffc3; } /* amarelo */
 .fundo2 { background: #87c2e8; } /* azul */
 .fundo3 { background: #a2ff94; } /* verde */
 .box h2 {
 margin:0;
 font-size:2rem;
 }
 .box p {
 margin:3% 0;
 font-size:1.4rem;
 }

Nota: Por se tratar de um exemplo, algumas regras CSS para estilização geral (tais como as declarações CSS para o elemento body, a largura e altura mínima dos boxes, tamanhos de fontes, textos no boxes), foram arbitradas e poderão ser adaptadas às exigências de cada caso sem prejuízo da explicação teórica nesta matéria.

HTML

<div class="box borda1 cor1 fundo1">
 <h2 class="h2 cor1h2">Lorem ipsum</h2>
 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi eleifend, purus quis laoreet faucibus, ante augue malesuada mi, id rhoncus augue lorem eget elit.</p>
 <p>Ut sollicitudin sodales purus.</p>
 </div>
 <div class="box borda2 cor2 fundo2">
 <h2 class="h2 cor2h2">Lorem ipsum</h2>
 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi eleifend, purus quis laoreet faucibus, ante augue malesuada mi, id rhoncus augue lorem eget elit.</p>
 <p>Ut sollicitudin sodales purus.</p>
 </div>
 <div class="box borda3 cor3 fundo3">
 <h2 class="h2 cor3h2">Lorem ipsum</h2>
 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi eleifend, purus quis laoreet faucibus, ante augue malesuada mi, id rhoncus augue lorem eget elit.</p>
 <p>Ut sollicitudin sodales purus.</p>
 </div>

Nota: Observe que além de termos definido multi-classes para os containers dos boxes, na marcação do cabeçalho h2, definimos as classes h2 e corh2. Isso dará ao autor maior flexibilidade na estilização dos cabeçalhos, pois terá a sua disposição o seletor multi-classe .h2.cor*h2, que permitirá estilizar o cabeçalho em cor diferente do parágrafo, sobrescrevendo a declaração de cor com uso do seletor .cor*. Se necessário, pode-se adotar a mesma solução para os parágrafos com a inserção das classes p e cor*p (* neste parágrafo significa 1, 2 ou 3).

É muito provável que você tenha percebido que para redefinir a cor do cabeçalho bastaria a classe cor*h2 sem necessidade da classe h2. É verdade, contudo estaríamos criando um conflito entre as regras que definem a cor declaradas com o seletor .cor* e o seletor cor*h2, já que ambos têm a mesma especificidade. Como consequência, a (nova) regra que usa o seletor cor*h2 teria que ser inserida nas CSS depois da regra que usa o seletor .cor*, sob pena de não funcionar. Assim, é melhor não correr riscos e optar por um seletor mais específico, .h2.cor*h2, acrescentando o valor h2 na lista de valores da classe paras o elemento h2.

Para alterar globalmente a estilização dos boxes (redesign do site), basta alterar valores na folha de estilos. Para alterar um dos itens de estilização de boxes existentes basta criar seletores multi-classe para sobrescrever declarações do seletor classe para aquele item. Por exemplo: A regra CSS .box.fundo1 { color: #fff } altera a cor de fundo amarela de todos os boxes existentes para a cor branca.

Para criar novos boxes (expansão do site), basta declarar convenientemente a lista de valores de classe na marcação HTML do novo box.

Que tal praticar com os boxes constantes deste tutorial? Use o iframe do JSFiddle que acrescentei a seguir. Divirta-se estudando ou estude divertindo-se, mas não deixe de estudar, nunca!

Você poderá combinar cores e elementos de estilização dos boxes de modo a obter uma infinidade de boxes diferentes em apresentação com o mínimo de manipulação da folha de estilos e/ou da marcação HTML.

Veja os resultados em: http://jsfiddle.net/6tP2N/light/

Desafio: Na interface do JSFiddle alterando somente regras CSS, obtenha o visual mostrado na figura a seguir para os três boxes. Não altere a marcação HTML e não acrescente novas regras CSS, pois é exatamente assim que funciona a modularização CSS.

seletor-multi-classe-desafio