Juntando o DNA do HTML com seletores de atributos CSS

Publicados: 2022-03-10
Resumo rápido ↬ Os seletores de atributos são mágicos. Eles podem tirar você de problemas persistentes, ajudar a evitar a adição de classes e apontar alguns problemas em seu código. Mas não se preocupe, embora os seletores de atributos sejam complexos e poderosos, eles são fáceis de aprender e de utilizar. Neste artigo, discutiremos como eles funcionam e daremos algumas ideias sobre como usá-los.

Durante a maior parte da minha carreira, os seletores de atributos foram mais mágicos do que científicos. Eu olhava, boquiaberto, para o CSS para gerar um link em uma folha de estilo de impressão, sem entender nada. Eu obedientemente copiava e colava na minha folha de estilo de impressão e depois corria para lançar qualquer projeto que fosse o maior monte de lixo em chamas.

Mas você não precisa mais olhar de queixo caído para os seletores de atributos CSS. No final deste artigo, você os usará para executar diagnósticos em seu site, corrigir problemas insolúveis e gerar experiências tecnológicas tão avançadas que parecem mágicas. Você pode pensar que estou prometendo demais e você está certo, mas depois de entender o poder dos seletores de atributos, você pode sentir que está exagerando.

No nível mais básico, você coloca um atributo HTML entre colchetes e o chama de seletor de atributo assim:

 [href] { color: chartreuse; }

O texto de qualquer elemento que tenha um href e não tenha um seletor mais específico agora se tornará magicamente chartreuse. A especificidade do seletor de atributo é a mesma das classes.

Nota : Para saber mais sobre a correspondência de gaiola que é especificidade CSS, você pode ler “CSS Specificity: Things You Should Know” ou se você gosta de Star Wars: “CSS Specificity Wars”.

Mas você pode fazer muito mais com seletores de atributos. Assim como o seu DNA, eles têm lógica integrada para ajudá-lo a escolher todos os tipos de combinações e valores de atributos. Em vez de apenas corresponder exatamente da maneira que um seletor de tag, classe ou id faria, eles podem corresponder a qualquer atributo e até mesmo valores de string dentro de atributos.

Mais depois do salto! Continue lendo abaixo ↓

Seleção de atributo

Os seletores de atributos podem viver por conta própria ou ser mais específicos, ou seja, se você precisar selecionar todas as tags div que tenham um atributo title .

 div[title]

Mas você também pode selecionar os filhos de divs que têm um título fazendo o seguinte:

 div [title]

Para ser claro, nenhum espaço entre eles significa que o atributo está no mesmo elemento (assim como um elemento e uma classe sem espaço), e um espaço entre eles significa um seletor descendente, ou seja, selecionando os filhos do elemento que possuem o atributo.

Você pode obter muito mais granularidade na forma como seleciona atributos, incluindo os valores dos atributos.

 div[title="dna"]

O acima seleciona todos os divs com um título exato de “dna”. Um título de “dna é incrível” ou “dnamutation” não seria selecionado, embora existam algoritmos seletores que tratam de cada um desses casos (e mais). Chegaremos a eles em breve.

Nota : As aspas não são obrigatórias em seletores de atributos na maioria dos casos, mas vou usá-las porque acredito que aumenta a clareza e garante que os casos extremos funcionem adequadamente.

Se você quisesse selecionar “dna” de uma lista separada por espaços, como “meu lindo dna” ou “mutar dna é divertido!” você pode adicionar um til ou “squiggly”, como eu gosto de chamá-lo, na frente do sinal de igual.

 div[title~="dna"]

Você pode selecionar títulos como “dontblamemeblamemydna” ou “sua-estupidez-é-de-criação-não-dna”, então você pode usar o cifrão $ para corresponder ao final de um título.

 [title$="dna"]

Para corresponder à frente de um valor de atributo, como títulos de “dnamutants” ou “dna-splicing-for-all”, use um acento circunflexo.

 [title^="dna"]

Embora ter uma correspondência exata seja útil, pode ser uma seleção muito apertada, e a correspondência frontal do cursor pode ser muito ampla para suas necessidades. Por exemplo, você pode não querer selecionar um título de “genealogia”, mas ainda assim selecionar “gene” e “gene-data”. O caractere pipe (ou barra vertical) é exatamente isso; ele faz uma correspondência exata, mas inclui quando a correspondência exata é seguida por um traço.

 [title|="gene"]

Por fim, há um operador de atributo de pesquisa completo que corresponderá a qualquer substring.

 [title*="dna"]

Mas use-o com sabedoria, pois o acima corresponderá a “eu-gosto-meu-dna-como-minha-carne-raro”, bem como “edna”, “sequestro” e “equidnas” (algo que Edna realmente não deveria fazer. )

O que torna esses seletores de atributos ainda mais poderosos é que eles são empilháveis, permitindo que você selecione elementos com vários fatores de correspondência.

Mas você precisa encontrar a tag que tenha um título e uma classe que termine em “genes”? Veja como:

 a[title][class$="genes"]

Além de selecionar os atributos de um elemento HTML, você também pode imprimir seus genes mutantes usando pseudo-“ciência” (significando pseudoelementos e a declaração de conteúdo).

 <span class="joke" title="Gene Editing!">What's the first thing a biotech journalist does after finishing the first draft of an article?</span>
 .joke:hover:after { content: "Answer:" attr(title); display: block; }

O código acima mostrará a resposta para uma das piores piadas já escritas no hover (sim, eu mesmo escrevi e, sim, chamar de “brincadeira” é ser generoso).

A última coisa a saber é que você pode adicionar um sinalizador para tornar as pesquisas de atributo insensíveis a maiúsculas e minúsculas. Você adiciona um i antes do colchete de fechamento.

 [title*="DNA" i]

E assim corresponderia a “dna”, “DNA”, “dnA” e qualquer outra variação.

A única desvantagem disso é que o i só funciona no Firefox, Chrome, Safari, Opera e um punhado de navegadores móveis.

Agora que vimos como selecionar com seletores de atributo, vamos ver alguns casos de uso. Eu os dividi em duas categorias: Usos Gerais e Diagnósticos .

Usos Gerais

Estilo por tipo de entrada

Você pode estilizar os tipos de entrada de forma diferente, por exemplo, e-mail versus telefone.

 input[type="email"] { color: papayawhip; } input[type="tel"] { color: thistle; }

Exibir links de telefone

Você pode ocultar um número de telefone em determinados tamanhos e exibir um link de telefone para facilitar as chamadas em um telefone.

 span.phone { display: none; } a[href^="tel"] { display: block; }

Links Internos x Externos, Seguros x Inseguros

Você pode tratar links internos e externos de forma diferente e estilizar links seguros de forma diferente dos links inseguros.

 a[href^="http"]{ color: bisque; } a:not([href^="http"]) { color: darksalmon; } a[href^="https://"]:after { content: url(unlock-icon.svg); } a[href^="https://"]:after { content: url(lock-icon.svg); }

Baixar ícones

Um atributo que o HTML5 nos deu foi “download”, que diz ao navegador para, você adivinhou, baixar esse arquivo em vez de tentar abri-lo. Isso é útil para PDFs e DOCs que você deseja que as pessoas acessem, mas não deseja que eles sejam abertos agora. Também facilita o fluxo de trabalho para baixar muitos arquivos em sequência. A desvantagem do atributo download é que não há um visual padrão que o diferencie de um link mais tradicional. Muitas vezes é isso que você quer, mas quando não é, você pode fazer algo como o abaixo.

 a[download]:after { content: url(download-arrow.svg); }

Você também pode comunicar tipos de arquivo com ícones diferentes, como PDF vs. DOCX vs. ODF, e assim por diante.

 a[href$="pdf"]:after { content: url(pdf-icon.svg); } a[href$="docx"]:after { content: url(docx-icon.svg); } a[href$="odf"]:after { content: url(open-office-icon.svg); }

Você também pode garantir que esses ícones estejam apenas em links para download empilhando o seletor de atributos.

 a[download][href$="pdf"]:after { content: url(pdf-icon.svg); }

Substituir ou reaplicar código obsoleto/obsoleto

Todos nós já encontramos sites antigos com código desatualizado, mas às vezes atualizar o código não vale o tempo que levaria para fazer isso em seis mil páginas. Você pode precisar substituir ou mesmo reaplicar um estilo implementado como um atributo antes do HTML5.

 <div bgcolor="#000000" color="#FFFFFF">Old, holey genes</div> div[bgcolor="#000000"] { /*override*/ background-color: #222222 !important; } div[color="#FFFFFF"] { /*reapply*/ color: #FFFFFF; }

Substituir estilos inline específicos

Às vezes, você encontrará estilos inline que estão atrapalhando o trabalho, mas eles vêm de código fora do seu controle. Deve-se dizer que se você puder alterá-los, isso seria o ideal, mas se não puder, aqui está uma solução alternativa.

Observação : Isso funciona melhor se você souber a propriedade e o valor exatos que deseja substituir e se desejar que sejam substituídos onde quer que apareçam.

Para este exemplo, a margem do elemento é definida em pixels, mas precisa ser expandida e definida em em s para que o elemento possa reajustar adequadamente se o usuário alterar o tamanho da fonte padrão.

 <divTeenage Mutant Ninja Myrtle</div> div[style*="margin: 8px"] { margin: 1em !important; }

Nota : Esta abordagem deve ser usada com extrema cautela, pois se você precisar substituir esse estilo, você cairá em uma guerra !important e os gatinhos morrerão.

Mostrando tipos de arquivo

A lista de arquivos aceitáveis ​​para uma entrada de arquivo é invisível por padrão. Normalmente, usaríamos um pseudo elemento para expô-los e, embora você não possa fazer pseudo elementos na maioria das tags de input (ou no Firefox ou Edge), você pode usá-los em entradas de arquivo.

 <input type="file" accept="pdf,doc,docx"> [accept]:after { content: "Acceptable file types: " attr(accept); }

Menu Acordeão HTML

Os details não muito divulgados e a dupla de tags de summary são uma maneira de fazer menus expansíveis/acordeados com apenas HTML. Os detalhes envolvem a tag de summary e o conteúdo que você deseja exibir quando o acordeão estiver aberto. Clicar no resumo expande a tag de detail e adiciona um atributo aberto. O atributo open facilita a estilização de uma tag de details abertos de forma diferente de uma tag de details fechada.

 <details> <summary>List of Genes</summary> Roddenberry Hackman Wilder Kelly Luen Yang Simmons </details>
 details[open] { background-color: hotpink; }

Imprimindo links

Mostrar URLs em estilos de impressão me levou a entender os seletores de atributos. Você deve saber como construí-lo agora. Você simplesmente seleciona todas as tags com a href , adiciona um pseudo-elemento e as imprime usando attr() e content .

 a[href]:after { content: " (" attr(href) ") "; }

Dicas de ferramentas personalizadas

Criar dicas de ferramentas personalizadas é divertido e fácil com seletores de atributos (ok, divertido se você for um nerd como eu, mas fácil de qualquer maneira).

Nota : Este código deve levá-lo à vizinhança geral, mas pode precisar de alguns ajustes no espaçamento, preenchimento e esquema de cores, dependendo do ambiente do seu site e se você tem um gosto melhor do que eu ou não.

 [title] { position: relative; display: block; } [title]:hover:after { content: attr(title); color: hotpink; background-color: slateblue; display: block; padding: .225em .35em; position: absolute; right: -5px; bottom: -5px; }

Teclas de acesso

Uma das grandes vantagens da web é que ela oferece muitas opções diferentes para acessar informações. Um atributo raramente usado é a capacidade de definir uma tecla de accesskey para que esse item possa ser acessado diretamente por meio de uma combinação de teclas e a letra definida pela tecla de accesskey (a combinação exata de teclas depende do navegador). Mas não há uma maneira fácil de saber quais teclas foram definidas em um site.

O código a seguir mostrará essas chaves em :focus . Eu não uso no hover porque na maioria das vezes as pessoas que precisam da accesskey de acesso são aquelas que têm problemas para usar o mouse. Você pode adicionar isso como uma segunda opção, mas certifique-se de que não seja a única opção.

 a[accesskey]:focus:after { content: " AccessKey: " attr(accesskey); }

Diagnóstico

Essas opções são para ajudá-lo a identificar problemas durante o processo de compilação ou localmente ao tentar corrigir problemas. Colocá-los em seu site de produção fará com que os erros se destaquem para seus usuários.

Áudio sem controles

Eu não uso a tag audio com muita frequência, mas quando a uso, muitas vezes esqueço de incluir o atributo de controls . O resultado: nada é mostrado. Se você estiver trabalhando no Firefox, este código pode ajudá-lo a descobrir se você tem um elemento de áudio escondido ou se a sintaxe ou algum outro problema está impedindo que ele apareça (só funciona no Firefox).

 audio:not([controls]) { width: 100px; height: 20px; background-color: chartreuse; display: block; }

Sem texto alternativo

Imagens sem texto alternativo são um pesadelo de logística e acessibilidade. Eles são difíceis de encontrar apenas olhando para a página, mas se você adicionar isso, eles aparecerão imediatamente.

Nota : Eu uso outline em vez de border porque as bordas podem aumentar a largura do elemento e atrapalhar o layout. outline não adiciona largura.

 img:not([alt]) { /* no alt attribute */ outline: 2em solid chartreuse; } img[alt=""] { /* alt attribute is blank */ outline: 2em solid cadetblue; }

Arquivos Javascript assíncronos

As páginas da Web podem ser um conglomerado de sistemas de gerenciamento de conteúdo, plugins, frameworks e códigos que Ted (sentado em três cubículos) escreveu nas férias porque o site estava fora do ar e ele teme seu chefe. Descobrir o que o JavaScript carrega de forma assíncrona e o que não carrega pode ajudá-lo a se concentrar em onde melhorar o desempenho da página.

 script[src]:not([async]) { display: block; width: 100%; height: 1em; background-color: red; } script:after { content: attr(src); }

Elementos de evento Javascript

Você também pode destacar elementos que tenham um atributo de evento JavaScript para refatorá-los em seu arquivo JavaScript. Concentrei-me no atributo OnMouseOver aqui, mas funciona para qualquer um dos atributos de evento JavaScript.

 [OnMouseOver] { color: burlywood; } [OnMouseOver]:after { content: "JS: " attr(OnMouseOver); }

Itens ocultos

Se você precisar ver onde estão seus elementos ocultos ou entradas ocultas, você pode mostrá-los com:

 [hidden], [type="hidden"] { display: block; }

Mas com todos esses recursos incríveis, você acha que deve haver um problema. Certamente os seletores de atributos devem funcionar apenas enquanto sinalizados no Chrome ou nas compilações noturnas do Fiery Foxes on the Edge of a Safari. Isso é bom demais para ser verdade. E, infelizmente, há uma pegadinha.

Se você quiser trabalhar com seletores de atributos nos navegadores mais amados — isto é, IE6 — você não poderá. (Está tudo bem; deixe as lágrimas caírem. Sem julgamentos.) Praticamente em qualquer outro lugar que você esteja pronto para ir. Os seletores de atributos fazem parte da especificação CSS 2.1 e, portanto, estão nos navegadores há quase uma década.

E assim, esses seletores não devem mais ser mágicos para você, mas revelados como uma tecnologia suficientemente avançada. Eles são mais ciência do que magia, e agora que você conhece seus segredos mais profundos, cabe a você. Vá em frente e trabalhe maravilhas misteriosas da ciência na web.