Emmet: Atributos Personalizados `[attr=val]` e Numeração `$`
Após as primeiras 7 aulas, você já pode escrever HTML com aninhamento arbitrário, atributos arbitrários e repetição arbitrária usando Emmet. Mas dois cenários "estilo fábrica" permanecem não resolvidos — "10 inputs cada um com um nome diferente" e "100 linhas de tabela com números autoincrementais". Esses dois cenários são resolvidos por atributos personalizados
[attr=val]e numeração$respectivamente — as duas últimas peças do quebra-cabeça para as capacidades de geração em lote do Emmet.
1. O Que Você Vai Aprender
- Atributos personalizados
[attr=val]: adicionar qualquer atributo incluindo HTML5 data-* e aria-* - Atributos abreviados: atalho
[attr](sem valor), encadeando múltiplos atributos - Numeração
$: inserir números de sequência autoincrementais em valores de classe, id e atributo - Zero à esquerda com múltiplos dígitos
$$$: gerar automaticamente 001, 002, 003 - Direção da numeração e valor inicial:
@-para reversa,@Npara começar a contar de N - Aplicação combinada: tabela + atributos + numeração + tags implícitas
2. A História Real de Uma Desenvolvedora Front-End
(1) A Dor: Muitos Campos de Formulário + Muitas Linhas de Tabela
Alice recebeu a tarefa de construir um formulário combinado de login + registro com 5 inputs (nome de usuário, email, senha, confirmar senha, lembrar-me) e 1 botão de envio. Após escrever um formulário, ela percebeu que todos os nomes dos inputs pareciam quase idênticos — name="user", name="email", name="pwd" e assim por diante — cada um tinha que ser digitado manualmente.
Pior ainda era a tabela de "Termos de Serviço" na página de registro: 100 linhas de termos, cada linha um tr, com a coluna 1 sendo um número de sequência (1–100) e a coluna 2 sendo o texto do termo. Alice tentou escrever manualmente: tr>td{1}+td{Termo 1}, tr>td{2}+td{Termo 2}, ... na linha 30 ela desistiu. Apenas escrever 30 linhas similares de "tr + 2 td" levou 30 minutos.
Finalmente, após escrever todos os campos, Alice também precisava adicionar atributos HTML5 como aria-label="Campo de nome de usuário" e data-validate="email" aos inputs — cada atributo exigia verificar especificações, digitar sinais de igual e adicionar aspas. 30 linhas de input se transformaram em 90 linhas de HTML.
(2) Como [attr=val] e $ Resolvem Isso
O Emmet fornece dois mecanismos complementares para resolver os problemas de Alice:
Atributos personalizados [attr=val]: Escreva qualquer atributo dentro de colchetes, apresentado diretamente como HTML — Alice pode escrever cada input como input[name=user type=text] em uma linha, e atributos aria e data-* podem similarmente ir dentro dos colchetes.
Numeração $: Faz os valores de classe, id e atributo de elementos repetidos autoincrementarem. Os números de sequência dos 100 termos podem ser gerados com td.item$@100*100 em uma linha (começando de 100, decrescente), e o texto do termo pode ser preenchido com {texto} (abordado na Aula 09).
Alice reescreveu todo o formulário em uma linha de Emmet:
form>(input[name=user type=text placeholder="Username"])+(input[type=email name=email])+(input[type=password name=pwd])+(input[type=password name=pwd-confirm])+(label>input[type=checkbox name=remember]+{Lembrar-me})+(button[type=submit]{Login})
E a tabela de 100 linhas de termos:
(table>(tr>td{item $}*3)*5)
Após verificar, Alice exclamou: "5 campos de input foram de 25 linhas escritas manualmente para 1 linha, e a tabela de 100 linhas de termos foi de 350 linhas para 1 linha. O aumento de eficiência do Emmet em cenários de formulário e tabela é de 30 vezes ou mais."
(3) Benefícios
[attr=val] e $ são os operadores centrais do Emmet para lidar com cenários de "repetição + estilo fábrica". O primeiro permite cobrir todos os atributos HTML5 em uma linha de abreviação, enquanto o último faz os números de sequência rodarem automaticamente. Após esta aula, Alice pode escrever um formulário de 5 campos em 12 segundos e uma tabela de 100 linhas em 10 segundos. Esta aula também marca a conclusão da Fase 2 — as 9 aulas restantes abordarão atalhos CSS e Ações do editor.
3. Atributos Personalizados [attr=val]: Atributos HTML5 em Colchetes
[attr=val] é a sintaxe do Emmet para adicionar atributos arbitrários a uma tag. O conteúdo escrito dentro de colchetes se torna atributos HTML brutos — sejam atributos padrão HTML5 (colspan, type, placeholder), atributos HTML5 mais recentes (data-*, aria-*) ou atributos personalizados.
(1) Regras de Atalho
| Abreviação | Expansão | Observações |
|---|---|---|
td[title="Hello"] |
<td title="Hello"></td> |
Atributo único com aspas duplas |
td[colspan=3] |
<td colspan="3"></td> |
Atributo único sem aspas (OK quando o valor não tem espaços) |
td[title colspan=3] |
<td title="" colspan="3"></td> |
Forma abreviada (atributos sem valor) |
input[type=text name=user] |
<input type="text" name="user"> |
Múltiplos atributos separados por espaços |
a[href="#" data-id=$] |
<a href="#" data-id="1"></a> |
Atributo data-* com placeholder de numeração |
Dica: A forma sem valor
[attr](ex.:[disabled]) geraattr=""— o valor é uma string vazia. Se você quiser um atributo booleano (ex.:<input disabled>), o Emmet não removerá automaticamente o valor; você precisará editá-lo manualmente. No entanto, a maioria dos atributos padrão HTML modernos suporta a forma com valor, mantendo as coisas consistentes.
Ponto-Chave: O conteúdo dentro de colchetes é analisado inteiramente de acordo com a sintaxe de atributos HTML5 — valores podem usar aspas simples, aspas duplas ou sem aspas (quando não há espaços); múltiplos atributos são separados por espaços. Nota: aqui, espaços são delimitadores válidos, diferente da própria regra "espaço = caractere de parada" do Emmet. Colchetes formam um contexto "fechado".
4. Numeração $: O Placeholder Autoincremental
$ é o placeholder de numeração do Emmet — escreva $ em uma classe, id, valor de atributo ou até posição de texto, emparelhe com repetição *N, e ele é automaticamente substituído pelo número de sequência atual (padrão começando de 1).
(1) Onde $ Pode Ser Usado
| Localização | Abreviação | Expansão (*3) |
|---|---|---|
| Dentro de classe | li.item$*3 |
<li class="item1">, <li class="item2">, <li class="item3"> |
| Dentro de id | div#user$*3 |
<div id="user1"> ... |
| Dentro de valor de atributo | a[data-id=$]*3 |
<a data-id="1"> ... |
| Dentro de texto ({}) | a{Link $}*3 |
<a href="">Link 1</a> ... (abordado na Aula 09) |
(2) Zero à Esquerda com Múltiplos Dígitos $$$
Encadear múltiplos caracteres $ produz zero à esquerda com múltiplos dígitos:
Contagem de $ |
Forma Expandida | Caso de Uso |
|---|---|---|
item$ |
item1 item2 item3 | Listas, menus |
item$$ |
item01 item02 item03 | Listas pequenas |
item$$$ |
item001 item002 item003 | Linhas de tabela, cartões |
item$$$$ |
item0001 ... | Raro (milhares de linhas) |
(3) Reversa $- e Valor Inicial $@N
Por padrão, a numeração começa de 1 crescente. Use @- para decrescente e @N para começar de N:
| Modificador | Significado | Exemplo (*3) |
|---|---|---|
$ (padrão) |
Crescente, de 1 | 1, 2, 3 |
$- ou @- |
Decrescente (máx → 1) | 3, 2, 1 |
$@3 |
Crescente, de 3 | 3, 4, 5 |
$-3 ou @-3 |
Decrescente, de 3 para trás | 3, 2, 1 |
Ponto-Chave: Em
$@N, N é o valor inicial, não o valor final. Isso é comumente usado para cenários como "começar de um número específico" (ex.: números de página de paginação, códigos SKU de produtos, números de versão).
5. Exemplos Práticos
Os 5 exemplos a seguir cobrem todas as combinações principais de [attr] e $ — de atributos únicos a múltiplos atributos, de numeração básica a zero à esquerda com múltiplos dígitos, de reversa a cenários de tabela.
▶ Exemplo: Atributos Básicos td[title="Hello" colspan=3] (Dificuldade ⭐)
Adicione ambos os atributos title e colspan a um td. Esta é uma das combinações de atributos mais clássicas em tabelas HTML.
Abreviação:
td[title="Hello" colspan=3]
Expansão:
<td title="Hello" colspan="3"></td>
Saída:
TEXT 📖 Somente leituraAspas duplas envolvem o title contendo um espaço ("Hello"), e sem aspas envolve o valor sem espaço (3). O Emmet automaticamente adiciona aspas a todos os atributos independentemente de você as ter incluído na abreviação. Múltiplos atributos são separados por espaços, o que é diferente da própria regra "espaço = caractere de parada" do Emmet — espaços têm significado especial dentro de colchetes. colspan=3 indica que a célula abrange 3 colunas horizontalmente.
▶ Exemplo: Atributos de Input input[type=text name=user placeholder=Username] (Dificuldade ⭐)
Adicione atributos type, name e placeholder a um input de uma vez. Input é uma das tags mais "densas em atributos" no HTML.
Abreviação:
input[type=text name=user placeholder=Username]
Expansão:
<input type="text" name="user" placeholder="Username">
Saída:
TEXT 📖 Somente leituraTrês atributos concluídos em uma abreviação. Nota: o Emmet inteligentemente assume input como type="text" (mesmo se você omitir type), então escrever apenas `input[name=user placeholder=Username]` ainda produz type="text". Se você quiser type="password" ou type="email", deve escrevê-lo explicitamente. Três atributos encadeados são o atalho de maior frequência em cenários de formulário.
▶ Exemplo: Numeração com $ Único ul>li.item$*5 (Dificuldade ⭐)
Cinco elementos li, cada um com uma classe que autoincrementa de 1 a 5 — o exemplo principal da documentação oficial do Emmet.
Abreviação:
ul>li.item$*5
Expansão:
<ul>
<li class="item1"></li>
<li class="item2"></li>
<li class="item3"></li>
<li class="item4"></li>
<li class="item5"></li>
</ul>
Saída:
TEXT 📖 Somente leituraCinco elementos li com classes item1, item2, item3, item4, item5. Este é o padrão padrão do Emmet para itens numerados unicamente (item + número). Se o nome da classe não precisar de uma parte numérica, simplesmente escreva .item (sem $), e todos os elementos li compartilham a mesma classe.
▶ Exemplo: Zero à Esquerda com Múltiplos Dígitos $$$ ul>li.item$$$*5 (Dificuldade ⭐)
Use 3 caracteres $ para auto-preencher com zero à esquerda a numeração para 3 dígitos.
Abreviação:
ul>li.item$$$*5
Expansão:
<ul>
<li class="item001"></li>
<li class="item002"></li>
<li class="item003"></li>
<li class="item004"></li>
<li class="item005"></li>
</ul>
Saída:
TEXT 📖 Somente leituraQuantidade de dígitos do zero à esquerda = número de caracteres $. 3 caracteres $ = zero à esquerda de 3 dígitos (item001, item002...). Cenários de zero à esquerda incluem: números de pedido (prefixados, fáceis de ordenar), IDs de tabela, SKUs e números de capítulo. Para preenchimento de 4 dígitos, use item$$$$; para 5 dígitos, use item$$$$$. Nota: quando o número real excede a largura do preenchimento, ele não é truncado — ex.: *12 com $$ produz item01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12 (os primeiros 9 são preenchidos com zero; os números 10–12 exibem com seus dígitos reais porque excedem 2 dígitos).
▶ Exemplo: Tabela + Numeração (table>(tr>td{item $})*3) (Dificuldade ⭐⭐)
Agrupamento + repetição + conteúdo de texto — uma "lista numerada" de 3 linhas × 1 coluna, usando agrupamento para que td siga a repetição de cada tr.
Abreviação:
(table>(tr>td{item $})*3)
Expansão:
<table>
<tr>
<td>item 1</td>
</tr>
<tr>
<td>item 2</td>
</tr>
<tr>
<td>item 3</td>
</tr>
</table>
Saída:
TEXT 📖 Somente leituraDetalhamento: os parênteses externos encapsulam a tabela inteira como uma unidade independente; o interno (tr>td{item $}) é um modelo para "uma linha com um item N", e *3 repete este modelo 3 vezes. Cada repetição substitui $ pelo número de sequência atual (1, 2, 3), resultando em 3 elementos tr cada um contendo um td com texto "item 1", "item 2" e "item 3". Este é o padrão central do Emmet para cenários como "numeração de termos", "numeração de lista de tarefas" e "listas de produtos". Para obter múltiplas células por linha, mude td{item $} para td{item $}+td{...} (conteúdo de texto abordado na Aula 09).
6. Exemplo Completo: Fieldset de Formulário + IDs com Zero à Esquerda de Múltiplos Dígitos
Combine [attr] e $ — um formulário de registro com 5 campos de input, cada campo tendo um id com zero à esquerda de 3 dígitos.
▶ Exemplo: Formulário de Registro + IDs de 3 Dígitos (Dificuldade ⭐⭐)
Abreviação:
form#register>(fieldset>legend{Informações da Conta})+(input#field-001.form-control[type=text name=user])+(input#field-002.form-control[type=email name=email])+(input#field-003.form-control[type=password name=pwd])+(label>input#field-004[type=checkbox name=news]+{Assinar newsletter})+(button#btn-100.btn.btn-primary[type=submit]{Registrar})
Expansão:
<form id="register">
<fieldset>
<legend>Informações da Conta</legend>
</fieldset>
<input id="field-001" class="form-control" type="text" name="user">
<input id="field-002" class="form-control" type="email" name="email">
<input id="field-003" class="form-control" type="password" name="pwd">
<label>
<input id="field-004" type="checkbox" name="news">
Assinar newsletter
</label>
<button id="btn-100" class="btn btn-primary" type="submit">Registrar</button>
</form>
Saída:
TEXT 📖 Somente leituraDetalhamento: este exemplo combina todos os operadores da Fase 2 — > (aninhamento), + (irmão), #id, .class, [] (atributos), {} (conteúdo de texto). Nota: o id de cada input é escrito manualmente porque o $ do Emmet só pode ser usado dentro de estruturas de repetição *N. Aqui, os 5 inputs usam uma abordagem híbrida — "id manual + classe automática" — onde id serve como "âncora de campo" do formulário (gancho JS) e deve ser único, enquanto class serve como "tipo de campo" (seletor CSS) e pode ser reutilizada. Este padrão "id manual + classe automática" é um padrão de alta frequência no desenvolvimento de formulários.
❓ Perguntas Frequentes
P: Qual é a diferença entre
[attr]e[attr=]? R:[attr]é atalho equivalente a[attr=""](valor de string vazia), expandindo para<tag attr="">;[attr=]explicitamente atribui uma string vazia, expandindo para o mesmo<tag attr="">. Ambos produzem resultados idênticos. Na semântica HTML, um atributo sem valor (ex.:disabled="") se comporta da mesma forma que um nome de atributo simples (disabled) — mas o Emmet por padrão gera a forma com valor, então você pode precisar apará-lo manualmente.
P:
$só pode ser usado uma vez? Qual é o máximo? *R: Não há limite.$$$$$$$$(8 $) expande para zero à esquerda de 8 dígitos. Nota: o número de caracteres $ determina a largura mínima de preenchimento, mas quando o número real excede essa largura, ele é exibido normalmente (sem truncamento). Se 12 usa $$, 1–9 exibem como 01–09, e 10–12 exibem como 10–12 (não truncados para, digamos, 8 dígitos).
P:
[data-id=$]pode funcionar sem*? R: Sim, mas sem repetição*,$assume 1 por padrão. Entãoa[data-id=$]expande para<a data-id="1"></a>— o que geralmente não é o que você quer. Se você quer apenas um data ID sem numeração, escrevaa[data-id=user]com o valor real.
P: Qual é o correto,
@-ou$-? R: A documentação oficial do Emmet suporta ambas as formas:@Nsignifica começar de N,@-significa decrescente. A forma combinada$-3é equivalente a@-3— ambas significam decrescente começando de 3. Usar a forma prefixada com@($@3,@3,@-3) é recomendado para clareza e compatibilidade.
📖 Resumo
[attr=val]adiciona atributos arbitrários a uma tag; múltiplos atributos são separados por espaços- A forma sem valor
[attr]é equivalente a[attr=""]; ambas geram atributos com valor vazio - Colchetes formam um contexto "fechado" — espaços são delimitadores de atributos, não caracteres de parada
$é um placeholder de numeração; emparelhe com*Npara substituição automática pelo número de sequência atual (padrão crescente de 1)- Múltiplos caracteres
$auto-preenchem com zero à esquerda ($$$→ zero à esquerda de 3 dígitos) $@Ninicia a numeração de N;@-produz numeração decrescente$pode ser colocado em valores de classe, id e atributo- Todos os 8 operadores da Fase 2 agora estão cobertos:
>+^*().#[]$
📝 Exercícios
- Básico (Dificuldade ⭐): Escreva abreviações Emmet de uma linha que expandam para: (a) uma tag
acomhref="#",class="link",data-id="$"(nota:$sem*assume 1); (b) umtdcomtitle="Célula",colspan=2,rowspan=3; (c) umul>li*5, cada li com uma classerow-$(numeração de dígito único). - Intermediário (Dificuldade ⭐⭐): Escreva uma "planilha de notas" de 5 linhas × 4 colunas com a primeira linha como cabeçalho (th) e linhas 2–5 como dados (td), com ids de células de dados usando zero à esquerda de 3 dígitos (
cell-001atécell-020). Escreva tudo em uma linha Emmet e explique por que $ pode ser usado para ids mas class não funcionaria da mesma forma. - Desafio (Dificuldade ⭐⭐⭐): Escreva uma "Tabela de Termos de Serviço" de 100 linhas com estrutura de 3 colunas: (a) uma coluna de número de sequência usando
td.item$@100*100para numeração reversa (de 100 para 1); (b) uma coluna de título usando conteúdo de texto{Termo $}(conteúdo de texto abordado na Aula 09); (c) uma coluna de conteúdo deixada vazia por enquanto. Escreva tudo em uma linha Emmet, verifique a expansão e compare a diferença de tempo entre escrever 100 linhas manualmente vs. uma linha de Emmet.