(85) 99645-7140 nelclassico@gmail.com Praça Coronel Melquiades, 124
Tecnologia

Vamos usar o seletor de :: enésima letra inexistente agora

“Acho que cansei da realidade.”

O Sétimo Círculo por Arquitetos

Todos nós, em algum momento, tivemos o pensamento que CSS é uma merda . Na verdade, o burburinho exagerado em torno  da nova biblioteca pretext.js  como uma “assassina de CSS” reflete o quanto todos nós queremos estrangular o CSS às vezes

Algum dia no futuro, o CSS poderá responder: “Não, você é aquele que é péssimo em CSS . Aqui está a CSS Parser API . Crie sua própria linguagem de estilo e veja o quão perto qualquer alternativa está da perfeição .”

Bem, CSS, você está me provocando desde 2017 com a possibilidade dessa API, que eu esperava que me deixasse criar minha própria sintaxe CSS, mas nada disso se materializou.

E enquanto estou desabafando, desde 2003 pedimos sobre e sobre e sobre para ::nth-letter, o que parece uma sugestão natural. Quero dizer, sempre tivemos ::first-letter para imitar efeitos de impressão como capitulares , então sabemos que você poderia fazer ::nth-letter se você quiser.

Você é apenas uma provocação, CSS, o que significa que em 2026, ainda não consigo escrever estilos como o de Chris Coyier exemplo hipotético de 2011.

h1.fancy::nth-letter(n) {
  display: inline-block;
  padding: 20px 10px;
  color: white;
}

h1.fancy::nth-letter(even) {
  transform: skewY(15deg);
  background: #C97A7A;
}

h1.fancy::nth-letter(odd) {
  transform: skewY(-15deg);
  background: #8B3F3F;
}

Demonstrações impossíveis de ::nth-letter

Se você preferir brincar com um exemplo interativo, aqui está a sintaxe inválida ::nth-letter funcionando no CodePen.

CodePen Incorporar Fallback

E aqui está um vídeo de demonstração do meu filho de oito anos, para demonstrar que usar essa sintaxe é brincadeira de criança.

Se ::nth-letter existisse, poderíamos migrar meu efeito de rolagem de vórtice de texto para usá-lo e, em seguida, excluir o JavaScript, como visto abaixo. Isso é apenas para Chrome/Safari, devido ao uso da nova função ::nth-letter .

CodePen Incorporar Fallback

Se tivéssemos ::nth-letter, poderíamos migrar o incrível foco elástico com reconhecimento de direção de Temani Afif e, em seguida, excluir alegremente todos os intervalos na marcação original em torno de cada letra. O código ::nth-letter seria conforme mostrado no CodePen abaixo.

CodePen Incorporar Fallback

Se apenas ::nth-letter existisse, minha missão seria atualizar cada estilo de tipografia demo para usá-lo.

Infelizmente, a sintaxe para fazer isso funcionar não é possível com CSS e HTML. Tais capacidades existem apenas nos domínios mais selvagens da nossa imaginação. O artigo termina aqui.

Espere, o que? Como funcionam todas essas demonstrações?

Enquanto estamos no tópico de fazer o impossível, foi dito – por Philip Walton do Google, que se esforçou muito no passado para fazer polyfills CSS prontos para produção – que não é possível escrever um polyfill confiável para CSS . Ele desistiu da ideia, mas gosto de imaginar que seu apelido no Google passou a ser “Polyphil”, então não foi uma perda total.

Philip também criou este framework abandonado para criação de polyfills CSS , que ainda funciona, embora seja tão antigo que os exemplos mostram como polyfill flexbox . Na década desde que ele parou de oferecer suporte a esta biblioteca, não parece que a viabilidade de polyfills CSS perfeitos tenha melhorado.

No entanto, as descobertas de Philip não pararam polyfills CSS legais de existente . Eles podem ser úteis, mesmo que não sejam perfeitos. O perfeito é inimigo do bom.

Por que não vamos desistir de ::nth-letter

Para manter nossa motivação para simular ::nth-letter, observo que a falta de uma especificação pode tornar a implementação mais fácil do que escrever um polyfill verdadeiro. Qualquer coisa que criarmos neste espaço será tecnicamente um calço em vez de um polyfill . Todos os polyfills são calços, mas nem todos os calços são polyfills – como todas as vacas são animais, mas não o contrário.

Estamos corrigindo CSS para adicionar funcionalidades que nunca existiram, enquanto um polyfill simula um recurso que existe em determinados ambientes e/ou pelo menos tem uma especificação formal. O mais próximo que chegamos de um rascunho de especificação foi trabalho experimental que a Adobe tentou no WebKit em 2012 , que nunca chegou a lugar nenhum .

Tendo explicado isso, usarei os termos polyfill e shim alternadamente aqui, porque polyfill é o termo mais conhecido e porque, de qualquer forma, estou prestes a brincar rápido e solto com o significado das palavras.

Definindo nossos termos

Como ninguém sabe como ::nth-letter se comportaria, posso inventar minhas próprias respostas para perguntas como as que Jeremy Keith levantou sobre como isso funcionaria.

Como disse Humpty Dumpty, as palavras significarão o que eu quero que elas signifiquem .

1. O que significa “enésimo”?

Jeremy se perguntou qual seria a terceira letra de um parágrafo. Veja este exemplo de marcação:

<p>AB<span>CD</span>EF</p>

A terceira letra pode ser:

  • “C” porque essa é a terceira letra que apareceria quando você lesse da esquerda para a direita, independentemente da estrutura do DOM. Afinal, ::nth-letter selecionaria “A”, mesmo que esse caractere estivesse profundamente aninhado na marcação dentro do parágrafo.
  • “E” porque é isso que <p>AB<span>CD</span>EF</p> faria . E é o terceiro filho direto do elemento parágrafo.
  • “D” ou “B” se estilizarmos o parágrafo para usar uma direção de escrita da direita para a esquerda . Em um cenário mais provável, se o parágrafo acima fosse alterado para p::first-letter Os caracteres hebraicos são inerentemente da direita para a esquerda em Unicode – e então a resposta seria diferente novamente.

A resposta, no universo que criei para este artigo, é que ::nth-letter se comportará da mesma forma que <p>AB<span>CD</span>EF</p>, que depende da ordem de origem do filho direto do elemento .

A vida não é mais simples quando o rigoroso processo de elaboração do W3C é substituído pelos caprichos de um maluco solitário?

2. O que significa “letra”?

Falamos sobre como outros idiomas afetariam ::nth-letter. Apenas metade da web usa inglês . Se estivermos simulando um recurso do navegador, não podemos ignorar outras linguagens, não é mesmo?

As instruções de escrita não são apenas diferentes em outros idiomas além do inglês, mas alguns idiomas usam vários caracteres para representar uma única letra . Agora, em teoria, ::first-letter seleciona todas as partes dessa carta. Mas o suporte do navegador para isso é ruim . ::first-letter tem alguns outros casos extremos interessantes que eu não esperava, como selecionar a pontuação junto com a primeira letra, talvez porque é assim que as letras maiúsculas são normalmente apresentadas.

Neste ponto, decido que qualquer resposta que eu der decepcionaria algumas pessoas se a ideia de uma carta não for a selecionada por ::nth-letter. Para contornar esse debate, digamos que ::nth-letter seja um apelido para o enésimo caractere .

Um pouco extremo, mas os exemplos que mostrei acima de como as pessoas imaginam ::nth-letter não parecem focar se cada caractere é uma letra. E acho que meu filho de 8 anos ficaria desapontado se o ponto de exclamação que ele adicionou ao texto do arco-íris não fosse colorido.

Olha, se você não gosta, volte para o seu próprio universo, onde não existe ::nth-letter. Ou você pode mexer no código-fonte que mostrarei a seguir.

Como escrever um polyfill impossível

Publiquei esta biblioteca experimental no npm. Isso é o que o CodePen acima usa via unpckg . O pacote ::nth-letter recebeu 1,3 mil downloads em sua primeira semana sem que eu o anunciasse, então foi legal.

Em vez de tentar construir um polyfill perfeito, há uma certa liberdade em saber que não podemos. Portanto, faremos a coisa mais simples que poderia funcionar . Reescrevemos o CSS e transformamos o DOM para que o navegador possa fazer o resto. Aqui está uma versão simplificada com 29 linhas de JavaScript e que funciona nos navegadores atuais. À medida que exploramos como funciona, você verá que a brevidade é alcançada aproveitando o que o CSS já pode fazer com o mínimo de adulteração.

import getCssData from 'get-css-data';
import { SplitText } from 'gsap/SplitText';

getCssData({
  onComplete(cssText, cssArray, nodeArray) {
    nodeArray.forEach(e => e.remove());
    const selectors = new Set();
    const nthArgs = new Set();
    cssText = cssText.replace(//*[sS]*?*//g, '');
    // Replace ::nth-letter with :nth-child in CSS
    let rewrittenCss = cssText.replace(
      /([^,{{rn]+?)::?nth-letter[ t]*(([^n)]*))/gi,
      (full, selector, args) => {
        selector = selector.trim();
        selectors.add(selector);
        nthArgs.add(args);
        // Use :nth-child instead of ::nth-letter
        return `${selector} .char:nth-child(${args})`;
      }
    );
    document.head.insertAdjacentHTML("beforeend", `<style>${rewrittenCss}</style>`);
    selectors.forEach(selector => {
      document.querySelectorAll(selector).forEach(el => {
        if (el.hasAttribute('data-nth-letter')) return;
        el.setAttribute('data-nth-letter', 'attached');
        new SplitText(el, { type: 'chars', charsClass: 'char' });
      });
    });
  }
});

Muita coisa está acontecendo neste pequeno bloco de código, então vamos dividir as fases.

Traduzindo ::nth-letter em CSS válido

Mesmo nesta primeira fase, temos a sensação de que a introdução da sintaxe CSS personalizada não será tão fácil quanto esperamos. É menos convenientemente óbvio como fazer isso do que monkey patching JavaScript, embora os riscos sejam comparáveis ​​aos patches globais em JavaScript.

A forma como o CSS é aplicado a uma página da web não oferece uma boa oportunidade para interceptar comportamentos CSS padrão e personalizá-los.

De fato, mesmo disponibilizar a sintaxe não padrão ::nth-letter para nosso código JavaScript é complicado , porque o analisador CSS descartará CSS inválido, então se o usuário incluir o seletor import getCssData from 'get-css-data';
import { SplitText } from 'gsap/SplitText';

getCssData({
onComplete(cssText, cssArray, nodeArray) {
nodeArray.forEach(e => e.remove());
const selectors = new Set();
const nthArgs = new Set();
cssText = cssText.replace(//*[sS]*?*//g, '');
// Replace ::nth-letter with :nth-child in CSS
let rewrittenCss = cssText.replace(
/([^,{{rn]+?)::?nth-letter[ t]*(([^n)]*))/gi,
(full, selector, args) => {
selector = selector.trim();
selectors.add(selector);
nthArgs.add(args);
// Use :nth-child instead of ::nth-letter
return `${selector} .char:nth-child(${args})`;
}
);
document.head.insertAdjacentHTML("beforeend", `<style>${rewrittenCss}</style>`);
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(el => {
if (el.hasAttribute('data-nth-letter')) return;
el.setAttribute('data-nth-letter', 'attached');
new SplitText(el, { type: 'chars', charsClass: 'char' });
});
});
}
});
, ele não estará disponível para JavaScript quando ele acessar a propriedade ::nth-letter do DOM .

Precisamos reunir todo CSS bruto livre de julgamento de validade, então vamos usar ::nth-letter , que concatena o conteúdo bruto de qualquer .rainbow::nth-letter(2n) tags no DOM e usa stylesheets para incluir o conteúdo de cada folha de estilo importada via get-css-data tags.

Sidenote: ::nth-letter não funcionará se a política CORS não permitir, mas essa é uma das limitações inerentes aos polyfills CSS.

Em seguida, reescrevemos o CSS fora do padrão usando expressões regulares, que é um pouco gueto . Uma abordagem mais rigorosa usaria algo como PostCSS no momento da construção. Mas podemos usar regex neste caso, porque não estamos fazendo nossa própria análise de CSS; estamos fazendo uma localização e substituição relativamente simples, na qual o regex é bom.

O resultado da substituição traduzirá o CSS inválido…

.rainbow::nth-letter(n) {
  color: #f432a0;
}

…neste CSS válido:

.rainbow .char:nth-child(n) {
  color: #f432a0;
}

Este ótimo vídeo conclui que a opção menos ruim para implementar um polyfill CSS é “reescrever o CSS para direcionar elementos individuais, mantendo a ordem em cascata”. Philip acrescenta que “nunca viu um polyfill fazer isso. Não recomendo, mas acho que é a melhor das opções ruins”. Antes tarde do que nunca para criar um polyfill usando esta estratégia.

Implementando o tradutor para ::nth-letter

O shim remove os estilos originais da página e os substitui pelos estilos reescritos, assim:

getCssData({
  onComplete(cssText, cssArray, nodeArray) {
    nodeArray.forEach(e => e.remove());
    const selectors = new Set();
    const nthArgs = new Set();
    cssText = cssText.replace(//*[sS]*?*//g, '');
    // Replace ::nth-letter with :nth-child in CSS
    let rewrittenCss = cssText.replace(
      /([^,{{rn]+?)::?nth-letter[ t]*(([^n)]*))/gi,
      (full, selector, args) => {
        selector = selector.trim();
        selectors.add(selector);
        nthArgs.add(args);
        // Use :nth-child instead of ::nth-letter
        return `${selector} .char:nth-child(${args})`;
      }
    );

    document.head.insertAdjacentHTML("beforeend", `<style>${rewrittenCss}</style>`);
  }
});

Neste ponto, traduzimos a sintaxe ::nth-letter não suportada em CSS válido. Mas ainda precisa de alguns elementos DOM para estilizar, ou não fará nada.

Preparando o DOM

Como ::nth-letter não existe, minha implementação é, em última análise, uma abstração conveniente para o que fiz manualmente em meu artigo de rolagem em espiral . Portanto, depois de reunir todos os elementos que exigem estilo de caracteres individuais, dividimos o conteúdo direcionado em .rainbow::nth-letter(n) {
color: #f432a0;
}
tags, usando o plugin SplitText disponível gratuitamente do GSAP .

selectors.forEach(selector => {
  document.querySelectorAll(selector).forEach(el => {
    if (el.hasAttribute('data-nth-letter')) return;
    el.setAttribute('data-nth-letter', 'attached');
    new SplitText(el, { type: 'chars', charsClass: 'char' });
  });
}

Funciona! O CSS gerado automaticamente de forma mágica recebe um DOM gerado automaticamente de forma mágica para estilizar. Todos viveremos felizes para sempre. O artigo acabou de verdade desta vez.

Ou é?

Precisamos modificar o DOM para isso?

Conforme mencionado em um boletim informativo CSS-Tricks de 2021 que lamentou ::nth-letter ser “infelizmente ainda não é uma coisa”, a solução de cuspir o texto em elementos separados por caractere é “muito grosseira, certo? É uma pena que tenhamos que bagunçar a marcação para fazer uma mudança estética relativamente simples.

A mesma postagem falava de um possível problema de acessibilidade se você dividisse os personagens em seus próprios elementos: “os leitores de tela (alguns, afinal?) leem cada um desses personagens com pausas entre eles”. A pesquisa mostra que VoiceOver pode causar esse problema , embora seja relatado que o atributo ::nth-letter agora pode aliviá-lo . O plug-in SplitText que uso também leva em conta automaticamente a acessibilidade , mas pode não funcionar em todos os leitores de tela e, infelizmente, a acessibilidade para texto dividido é mais difícil de acertar do que você imagina.

Além disso, se ::nth-letter fosse um recurso nativo, seria um pseudoelemento . Seria ótimo se pudéssemos simular isso, sabendo que existe o risco de tropeçarmos nesses elementos extras que minha biblioteca adiciona ao DOM.

Um pseudoelemento poderia nos dar o melhor dos dois mundos para resolver a tarefa em questão: algo que é puramente de apresentação e não polui o DOM, mas ainda pode se comportar como parte do DOM apenas para fins de estilo. Podemos implementar algo semelhante para evitar poluir nosso DOM?

Sim e não.

A dura verdade é que talvez nunca consigamos implementar nossos próprios pseudoelementos personalizados.

Anteriormente, expressei a esperança de que a API CSS Parser algum dia ajudasse, mas mesmo no caso improvável de essa API se materializar, a intenção não seria permitir que os desenvolvedores implementassem sua própria sintaxe CSS ou pseudoelementos. Como você pode ver neste 2021 rascunho não oficial , se algum dia obtivermos essa API, ela provavelmente exporia o analisador CSS do navegador para uso programático – mas provavelmente não nos ajudaria a personalizar como o CSS é interpretado. Pseudoelementos personalizados seriam o domínio de uma hipotética API de renderização CSS, algo que meu cérebro acabou de inventar e que ninguém propôs.

Bramus, da equipe do Chrome, tem um documento preliminar descrevendo como uma  API de extensões do analisador CSS  funcionaria, e isso está mais próximo do que imaginei que a hipotética API do analisador CSS poderia fornecer, mas o documento de Bramus atualmente não discute psuedo-elementos personalizados. Há também a proposta  HTML-in-canvas API  que nos permitiria personalizar a forma como os elementos são renderizados sem modificar seu DOM. Isso  já está disponível experimentalmente no Chrome , mas ainda não nos daria psuedo-elementos personalizados que poderíamos estilizar arbitrariamente usando CSS.

Versão Shadow DOM de ::nth-letter

Se estivermos presos à manipulação do DOM, o mais próximo que podemos chegar dos pseudoelementos personalizados é ocultar os elementos de caractere no shadow DOM dos elementos de destino, enquanto expomos uma API que nos permite estilizar caracteres selecionados de fora do destino.

Se estivermos determinados que os elementos direcionados deste novo seletor não poluirão o light DOM com marcação extra, então teremos que ocultar essa marcação no shadow DOM. Se fizermos isso, o mais próximo que conheço de um pseudoelemento personalizado é o pseudoelemento ::nth-letter . Se usarmos isso, então, por design, não poderemos usar:

.container::part(character):nth-child(2) {
  color: red;
}

O motivo é que o shadow DOM do meu elemento ficaria assim:

<div part="character">1</div>
<div part="character">2</div>

Um consumidor do meu componente não deveria ser capaz de conhecer a estrutura do shadow DOM de fora do componente usando CSS. É por isso que “ pseudoclasses estruturais que correspondem com base nas informações da árvore, como div e selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(el => {
if (el.hasAttribute('data-nth-letter')) return;
el.setAttribute('data-nth-letter', 'attached');
new SplitText(el, { type: 'chars', charsClass: 'char' });
});
}
, não podem ser anexado“ a ::nth-letter. Era uma vez, havia um pseudoelemento ###CODE_c4e8b15f4b49e083c6094b6ff0ffffee9### que nos permitiria estilizar <p>AB<span>CD</span>EF</p> de fora do shadow DOM, mas era obsoleto há muito tempo.

Na verdade, ainda existe uma maneira de usar <p>AB<span>CD</span>EF</p> junto com ::nth-letter se você pensar lateralmente.

E se preenchermos o atributo ::nth-letter de cada personagem com base nos seletores <p>AB<span>CD</span>EF</p> que sabemos que precisaremos oferecer suporte? Sabemos o que são, pois os criamos quando estávamos substituindo os estilos por regex!

Então teríamos:

.rainbow::part(nth-child(n)) {
  color: #f432a0;
}

E o HTML em nosso shadow DOM seria algo como:

<h1 class="rainbow" data-nth-letter="attached">Rainbow</h1>
Rainbow
#ShadowRoot
<span aria-hidden="true" aria-label="Rainbow">
  <div class="char" aria-hidden="true" part="nth-child(n) nth-child(odd)">R</div>
  <!-- etc. -->
</span>

Podemos gerar esse shadow DOM usando a seguinte versão um pouco mais complexa do JavaScript:

import getCssData from 'get-css-data';
import { SplitText } from 'gsap/SplitText';
getCssData({
  onComplete(cssText, cssArray, nodeArray) {
    nodeArray.forEach(e => e.remove());
    const selectors = new Set();
    const nthArgs = new Set();

    // Remove CSS comments
    cssText = cssText.replace(//*[sS]*?*//g, '');

    let rewrittenCss = cssText.replace(
      /([^,{rn]+?)::?nth-letter[ t]*(([^n)]*))/gi,
      (full, selector, args) => {
        selector = selector.trim();
        selectors.add(selector);
        nthArgs.add(args);
        return `${selector}::part(nth-child\(${CSS.escape(args)}\))`;
      }
    );

    document.head.insertAdjacentHTML("beforeend", `<style>${rewrittenCss}</style>`);

    selectors.forEach(selector => {
      document.querySelectorAll(selector).forEach(el => {
        if (el.shadowRoot || el.hasAttribute('data-nth-letter')) return;

        const shadow = el.attachShadow({ mode: "closed" });
        el.setAttribute('data-nth-letter', 'attached');
        const wrapper = document.createElement("span");
        wrapper.setAttribute('aria-hidden', 'true');
        wrapper.innerHTML = el.innerHTML;
        shadow.appendChild(wrapper);
        const split = new SplitText(wrapper, { type: "chars", charsClass: "char" });

        nthArgs.forEach((arg, i) => {
          let chars = wrapper.querySelectorAll(`.char:nth-child(${arg})`);
          chars.forEach(c => {
            const prev = c.part || "";
            c.part = (prev ? prev + " " : "") + `nth-child(${arg})`;
          });
        });
      });
    });
  }
});

Pré-calculando os <p>AB<span>CD</span>EF</p> seletores como nomes das partes de sombra que correspondem aos ::nth-letter usos que nosso CSS solicitou, podemos selecioná-los de do lado de fora, sem tocar no DOM de luz e sem atingir uma parede de tijolos das limitações intencionais do DOM de sombra.

Funciona! Já chegamos? A melhor resposta é usar shadow DOM?

Na verdade não, isso causa pelo menos dois grandes problemas:

  1. Esta versão não funcionará em elementos que não suportam anexar um shadow DOM , como :last-child ou ::part.
  2. Não podemos usar a função emergente ::nth-letter nos estilos para uma parte de sombra, porque ::nth-letter depende do conhecimento da estrutura do DOM, assim como <p>AB<span>CD</span>EF</p> faz. Isso impede o suporte às demonstrações de estilo de texto que mostrei no início. Essas demonstrações não funcionariam com a versão shadow DOM de ::nth-letter.

Percebo que ::first-letter também é seriamente limitado no estilo que suporta . Isso não é razão suficiente para prejudicar conscientemente nossa implementação de ::nth-letter quando há uma opção de não fazê-lo. Concluo que a versão light do DOM é melhor. Pode ser uma marcação “bruta”, mas pelo menos não somos mais nós que precisamos escrevê-la ou mantê-la. E se os navegadores suportarem ::nth-letter nativamente, o design do shim foi planejado para que mantivéssemos o CSS como está, excluíssemos a referência à minha biblioteca e nunca mais falássemos sobre isso.

O final (real)

Agora que temos uma base simples para implementar coisas como ::nth-letter, seria viável adicionar import getCssData from 'get-css-data';
import { SplitText } from 'gsap/SplitText';
getCssData({
onComplete(cssText, cssArray, nodeArray) {
nodeArray.forEach(e => e.remove());
const selectors = new Set();
const nthArgs = new Set();

// Remove CSS comments
cssText = cssText.replace(//*[sS]*?*//g, '');

let rewrittenCss = cssText.replace(
/([^,{rn]+?)::?nth-letter[ t]*(([^n)]*))/gi,
(full, selector, args) => {
selector = selector.trim();
selectors.add(selector);
nthArgs.add(args);
return `${selector}::part(nth-child\(${CSS.escape(args)}\))`;
}
);

document.head.insertAdjacentHTML("beforeend", `<style>${rewrittenCss}</style>`);

selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(el => {
if (el.shadowRoot || el.hasAttribute('data-nth-letter')) return;

const shadow = el.attachShadow({ mode: "closed" });
el.setAttribute('data-nth-letter', 'attached');
const wrapper = document.createElement("span");
wrapper.setAttribute('aria-hidden', 'true');
wrapper.innerHTML = el.innerHTML;
shadow.appendChild(wrapper);
const split = new SplitText(wrapper, { type: "chars", charsClass: "char" });

nthArgs.forEach((arg, i) => {
let chars = wrapper.querySelectorAll(`.char:nth-child(${arg})`);
chars.forEach(c => {
const prev = c.part || "";
c.part = (prev ? prev + " " : "") + `nth-child(${arg})`;
});
});
});
});
}
});
, :nth-child e assim por diante. Chris Coyier mostrou casos de uso interessantes para aqueles em [sua chamada para ::nth-letter tudo .

Ainda existem muitas limitações para o calço ::nth-letter, como:

  1. Não funciona se você alterar o DOM ou os estilos na hora, embora provavelmente possamos oferecer suporte a isso.
  2. Não funciona se você usar ::nth-letter em um seletor CSS passado para sibling-index() , embora pudéssemos corrigir o JavaScript para fazer isso funcionar.
  3. Não tenho certeza de quão escalonável é.
  4. Isso pode levar a bugs difíceis de diagnosticar porque reescreve todo o CSS e adiciona divs “char” inesperados ao DOM. Percebi que o polyfill de Philip Schatz para um rascunho de trabalho maluco chamado de “Módulo de conteúdo gerado por CSS” exige que o consumidor opte por usar atributos especiais no get-css-data ou .rainbow::nth-letter(2n) tags. Esse é um compromisso interessante que pode limitar o raio de explosão, acionando apenas as reescritas de CSS onde precisamos delas, mas parece menos conveniente do que apenas referenciar a biblioteca e depois usar a nova sintaxe.
  5. Folhas de estilo externas não permitidas pelo CORS não funcionarão.

Em resumo, eu provavelmente usaria ::nth-letter e seus amigos hipotéticos o tempo todo se esses recursos fossem integrados aos navegadores. Mas devo admitir que, tendo explorado a complexidade da construção de suporte genérico para um design que muitas vezes podemos resolver adequadamente com algumas linhas de JavaScript, vejo por que os navegadores estão relutantes em implementar e manter tal recurso.

Meu shim pode dar os poderes que são outro motivo para dizer que o suporte nativo não é necessário, ou se muitas pessoas usarem meu ::nth-letter hack na natureza, os deuses do navegador podem reconhecer a necessidade de implementá-lo de verdade.

De qualquer forma, nunca mais discutiremos, CSS. Agora entendo por que você fez o que fez. Eu nunca conseguiria ficar bravo com você.


Vamos usar o inexistente ::seletor de enésima letra agora originalmente escrito à mão e publicado com amor em CSS-Tricks . Você realmente deveria receber o boletim informativo também.

Deixe um comentário

Seu email não será publicado. Campos obrigatórios marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.