Modularização CSS com seletores multi-classe

visualizações Publicado em: 14/04/2014 — Atualizado em: ➠ 27/01/2017

Introdução

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, conforme mostrada a seguir.

Sintaxe para o seletor classe: .valor

No exemplo mostrado a seguir a regra CSS usa um seletor classe para definir 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 iniciantes 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 não são tão conhecidos como o seletor classe simples, não só pelos iniciantes mas 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 uma lista de valores separados por espaço pode ser usada como valor do atributo classe, conforme mostrado no exemplo da marcação HTML a seguir.

<p class="box borda">Parágrafo 1 com classes box e borda</p>
<p class="box borda cor">Parágrafo 2 com classes box, borda e cor</p>
<p class="borda cor">Parágrafo 3 com classe borda</p>

Elementos marcados com o atributo classe cujo valor é uma lista de valores como mostrado no exemplo de marcação anterior podem ser casados tanto com um seletor classe simples (defindo-se apenas um dos valores da lista) como com um seletor multi-classe (defindo-se dois ou mais dos valores da lista de forma encadeada), conforme veremos adiante.
Mas, é bom repetir, que o termo 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 um ou mais seletores classe simples sem uso de espaço entre eles, conforme mostrada a seguir.

Sintaxe para o seletor multi-classe: .valor1.valor2.valor3...

No exemplo mostrado a seguir usa-se um seletor multi-classe para definir 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 mostrada a seguir.

<p class="box borda">Parágrafo 1 com classes box e borda</p>
<p class="box borda cor">Parágrafo 2 com classes box, borda e cor</p>
<p class="borda cor">Parágrafo 3 com classe borda</p>

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 um seletor.

Observe o exemplo mostrado a seguir.

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

O seletor dste exemplo casa com o parágrafo 2 da marcação mostrada a seguir

<p class="box borda">Parágrafo 1 com classes box e borda</p>
<p class="box borda cor">Parágrafo 2 com classes box, borda e cor</p>
<p class="borda cor">Parágrafo 3 com classe borda</p>

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 e 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 valores da qual conste os valores .box e .borda

Dicas sobre seletores multi-classe

Algumas dicas práticas sobre os seletores multi-classe.

  • A ordem em que se declara os valores em uma lista de valores para a classe na marcação HTML é irrelevante.
  • A ordem em que se escreve os seletores componentes de um seletor multi-classe é irrelevante.
  • A especificidade de um seletor seletor multi-classe é igual à soma da especificidade dos seletores simples que o compõem.
    Dúvida com especificidade? Consulte: A especificidade e o efeito cascata.
  • Não há limite para os valores a serem declarados na lista de valores da classe na marcação HTML.
  • É válido 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 funcionamente 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
.h1cor-a { color: #039; } /* azul */
.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
.h1cor-a { color: #039; } /* azul */
.h1cor-a.h1cor-b { color: #f60; } /* laranja */
HTML
<h1 class="h1cor-a>Cabeçalho cor azul</h1>
<h1 class="h1cor-a h1cor-b>Cabeçalho cor laranja</h1>

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 aplicar e como funciona o seletor. A seguir mostraremos um exemplo prático para uso real.

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 de três diferentes maneiras para serem servidos em três diferentes áreas existentes no site, conforme mostrado na figura a seguir:

Três boxes dispostos lado a lado com cores bordas arredondadas e texto em cores diferentes.

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: Criar regra CSS padrão para todos os boxes e regras de estilização diferentes com uso de seletores multi-classe conforme mostrado a seguir:

CSS
/* Regras CSS padrão para todos os boxes */
.box {
	width: 20%;
	float:left;
	min-height:20rem;
	margin:2% 1%;
	padding: 0.5% 2%;
	line-height:1.2;
	border-radius: 1rem;  
}
.box h2 {
	margin:0;
	font-size:2rem;
}
.box p {
	margin:3% 0;
	font-size:1.4rem;
}
/* Regras CSS diferenciadas para estilizar bordas */
.borda1 { border: 0.5rem solid #900; } /* marrom */
.borda2 { border: 0.5rem solid #060; } /* verde */
.borda3 { border: 0.5rem solid #f00; } /* vermelho */

/* Regras CSS diferenciadas para cores de texto */
.cor1 { color: #0b0ce8; }  /* azul */
.cor2 { color: #000000; }  /* preto */
.cor3 { color: #cc3300; }  /* vermelho */

/* Regras CSS diferenciadas para cores de fundo */
.fundo1 { background: #ffffc3; } /* amarelo */
.fundo2 { background: #87c2e8; } /* azul */
.fundo3 { background: #a2ff94; } /* verde */

A marcação HTML para os três boxes mostrados anteriomente é conforme a seguir.

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, definimos também os valores de classes h2 e corNh2 para o elemento h2. Isso dará ao autor maior flexibilidade na estilização dos cabeçalhos, pois terá a sua disposição o seletor multi-classe .h2.corh2 que permitirá estilizar o cabeçalho em cor diferente da cor do parágrafo. Se necessário pode-se adotar a mesma solução para os parágrafos com a inserção das classes .p e .corNp (N nessa sintaxe significa 1, 2 ou 3).

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

Hora da prática

Que tal praticar com os boxes mostrados nesse 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.

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.

Novo visual para os boxes