Para remover a indentação do código-fonte HTML de um bloco de código exibido, remova os espaços iniciais comuns do texto, preservando a indentação relativa. Mantenha os espaços pré-formatados habilitados para que linhas aninhadas e espaçamentos intencionais continuem legíveis.

Este guia é para quem edita uma pequena página HTML em um Mac e a visualiza em um navegador para computador. A tarefa é remover a indentação introduzida pelo layout ao redor da página sem nivelar o código dentro dela.

Por que a indentação HTML aparece dentro de um bloco de código?

Um elemento pre representa texto pré-formatado, e a WHATWG oferece suporte explícito à combinação dele com um elemento code para código de computador. Consequentemente, os espaços usados para indentar o exemplo no arquivo HTML podem fazer parte do exemplo exibido. HTML Standard: The pre element.

Considere este fragmento HTML de uma página sintética que contém um exemplo de painel. Cada linha de conteúdo tem oito espaços iniciais indesejados; as duas linhas de propriedades têm mais dois espaços que devem ser mantidos.

<pre><code>        const panel = {
          label: "Panel A",
          count: 2
        };</code></pre>

O texto exibido desejado é:

const panel = {
  label: "Panel A",
  count: 2
};

O navegador tem uma exceção de análise relevante: ele remove uma única quebra de linha imediatamente após uma tag de abertura pre. Essa exceção não remove a indentação comum, e uma quebra de linha após uma tag de abertura code intermediária não fica imediatamente após pre. A MDN também explica que caracteres literais de marcação em texto pré-formatado ainda precisam ser devidamente escapados. MDN: The preformatted text element.

Escolha a correção adequada ao espaço indesejado

Antes de alterar a página, diferencie a indentação do texto do espaçamento ao redor do elemento. Esta sequência de decisões ajuda a evitar corrigir a camada errada.

O que você observa O que inspecionar Ação adequada
Todas as linhas de conteúdo começam com caracteres de espaço extras O texto do elemento de código Remova apenas a indentação inicial comum
O texto começa corretamente, mas a caixa inteira está recuada O CSS do elemento e seu contêiner Ajuste o espaçamento de layout pertinente
Há uma linha vazia antes ou depois do exemplo As quebras de linha ao redor do conteúdo propriamente dito Remova essa quebra específica, se não for intencional
Linhas longas ultrapassam a caixa O comportamento de quebra de linha Escolha separadamente entre preservar as linhas ou quebrá-las
O exemplo já usa Prism A configuração do plugin de espaços em branco Considere Normalize Whitespace

Para um único exemplo estático, a correção mais simples é editar o conteúdo diretamente: comece a primeira linha imediatamente após a tag de abertura code e remova das linhas seguintes os espaços comuns indesejados. Mantenha qualquer indentação que faça parte do próprio exemplo. A marcação ao redor da página pode continuar indentada de forma independente.

Para exemplos recorrentes, normalize o texto de origem durante a geração da página ou antes do realce de sintaxe. A próxima seção demonstra o cálculo explicitamente para que você possa ver quais espaços desaparecem.

Por que alterar white-space não basta

O CSS white-space: pre preserva espaços e quebras de linha sem a quebra de linha comum. pre-wrap preserva os espaços em branco e permite a quebra de linha. pre-line preserva as quebras de linha, mas reduz sequências de espaços; normal também reduz as quebras de linha do código-fonte. Esses controles não subtraem seletivamente a indentação comum de um exemplo de código. MDN: white-space.

Para esta tarefa, use pre quando for importante preservar cada linha do código-fonte, ou pre-wrap quando for mais importante ajustar linhas longas. Remover a indentação comum é uma operação de texto separada.

O rascunho CSS Text Level 4 da W3C define white-space-trim, mas seu exemplo de bloco pré-formatado mantém explicitamente a indentação do conteúdo propriamente dito. Atualmente, a MDN documenta essa propriedade como não implementada nos navegadores. Portanto, ela não oferece uma solução compatível com navegadores nem o cálculo de indentação comum necessário aqui. W3C: White Space Trimming, MDN: white-space constituent properties.

Use um exemplo completo que preserve a indentação aninhada

O documento HTML independente a seguir não requer biblioteca nem ferramenta de compilação. No editor de código do Mac, salve-o como um arquivo de texto simples chamado indent-demo.html e abra esse arquivo no navegador para computador. O script aparece depois do exemplo, então o elemento de destino já existe quando o script é executado.

A demonstração começa intencionalmente o conteúdo na mesma linha da tag de abertura code. Também deixa uma quebra de linha final antes da tag de fechamento. A função preserva essa quebra de linha final, em vez de remover o exemplo sem avisar.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Code indentation example</title>
  <style>
    body {
      max-width: 48rem;
      margin: 2rem auto;
      padding: 0 1rem;
      font-family: system-ui, sans-serif;
    }
    pre {
      padding: 1rem;
      background: #f2f2f2;
      white-space: pre;
      overflow-x: auto;
    }
    code {
      font-family: monospace;
    }
  </style>
</head>
<body>
  <h1>Panel example</h1>
  <pre><code id="panel-example">        const panel = {
          label: "Panel A",
          count: 2
        };
</code></pre>
  <script>
    function dedentSpaces(text) {
      const lines = text.replace(/\r\n?/g, "\n").split("\n");

      if (lines.some(line => /^[ \t]*\t/.test(line))) {
        throw new Error(
          "Use spaces for leading indentation before dedenting."
        );
      }

      const contentLines = lines.filter(line => /[^ ]/.test(line));
      if (contentLines.length === 0) return lines.join("\n");

      const indent = Math.min(
        ...contentLines.map(line => line.match(/^ */)[0].length)
      );

      return lines.map(line => {
        const leadingSpaces = line.match(/^ */)[0].length;
        return line.slice(Math.min(indent, leadingSpaces));
      }).join("\n");
    }

    const code = document.getElementById("panel-example");
    code.textContent = dedentSpaces(code.textContent);
  </script>
</body>
</html>

A função encontra o menor número de espaços iniciais entre as linhas não vazias. Para esta entrada ilustrativa, as contagens são oito, dez, dez e oito. Subtrair oito resulta em zero, dois, dois e zero: a indentação interna do objeto é preservada.

Linhas vazias não reduzem o mínimo a zero. Em uma linha vazia, a função remove no máximo o número comum de espaços e mantém a quebra de linha. Ela também deixa intactos os espaços finais nas linhas de conteúdo. Essas escolhas tornam a transformação mais restrita do que aplicar trim() a todas as linhas, o que removeria a indentação aninhada.

A implementação normaliza intencionalmente os finais de linha CRLF e CR para LF. Ela rejeita tabulações na indentação inicial, em vez de supor quantas colunas exibidas cada tabulação representa. Uma entrada composta apenas por espaços é devolvida com os espaços preservados, além da normalização explícita dos finais de linha.

A função de dedent foi executada no Node.js com cinco casos de saída determinísticos que cobrem indentação aninhada, linhas vazias, uma linha sem indentação, entrada CRLF e entrada composta apenas por espaços. Uma verificação separada confirmou a rejeição de tabulações iniciais. Essas verificações validam a transformação da string; não constituem um teste de renderização no navegador.

Aplique a transformação antes do realce

O exemplo lê e grava textContent. A MDN documenta que a leitura dessa propriedade coleta o texto dos descendentes, enquanto sua definição substitui os filhos do elemento por um nó de texto. Portanto, execute essa transformação antes que um realçador de sintaxe adicione elementos de token; aplicá-la depois removeria essa marcação de realce. MDN: Node.textContent.

Em uma página existente, mantenha a função, mas substitua o ID da demonstração pelo ID real do elemento de código. Selecione apenas o exemplo desejado. Se um renderizador da página substituir esse elemento posteriormente, inclua a normalização na etapa de preparação desse renderizador para que o conteúdo exibido receba a transformação.

Se a página já usa Prism, use o plugin de espaços em branco

O Prism oferece um plugin chamado Normalize Whitespace para exemplos em bloco que usam pre e code. A opção documentada remove-indent remove a indentação excessiva. As opções padrão também cortam o início e o fim do bloco e removem espaços em branco finais, o que é uma edição mais ampla do que a função acima. Prism: Normalize Whitespace.

Com Prism e Normalize Whitespace já carregados, o fragmento de configuração a seguir mantém habilitada a remoção de indentação e desativa essas três operações adicionais de limpeza padrão. Aplique-o antes de realçar os exemplos de destino.

// Configuration fragment: Prism and its plugin must already be loaded.
Prism.plugins.NormalizeWhitespace.setDefaults({
  "remove-indent": true,
  "remove-trailing": false,
  "left-trim": false,
  "right-trim": false
});

Essas opções padrão afetam o comportamento do plugin além de um único exemplo. O Prism também documenta configurações por bloco usando atributos data- e a classe no-whitespace-normalization para excluir um bloco. Inspecione as configurações existentes antes de adicionar outra etapa de normalização. Prism: Normalize Whitespace usage.

Confira o resultado sem alterar o significado do código

Em um Mac usando Chrome, pressione Command + Option + J para abrir o Console. Depois de abrir a demonstração independente, execute a expressão de inspeção a seguir. O Chrome documenta esse atalho na referência do DevTools. Chrome DevTools: Keyboard shortcuts.

JSON.stringify(document.getElementById("panel-example").textContent)

A string retornada deve conter o texto abaixo. As sequências \n tornam visíveis as quebras de linha; não deve haver espaços antes do primeiro const, dois antes de cada propriedade e nenhum antes da chave de fechamento.

"const panel = {\n  label: \"Panel A\",\n  count: 2\n};\n"

Em seguida, confira o exemplo exibido e copie-o para um editor de texto simples. Confirme que a primeira linha começa corretamente, que as linhas aninhadas mantêm a indentação e que as linhas vazias intencionais permanecem. Se o texto estiver correto, mas a caixa ainda parecer recuada, volte aos estilos de layout em vez de excluir mais caracteres.

Uma linha não vazia sem espaços iniciais faz a função não remover nada. Isso é intencional: uma linha sem indentação significa que não há indentação comum a todas as linhas de conteúdo. Inspecione essa linha antes de escolher um valor fixo para remover.

Por fim, a indentação comum é uma suposição editorial; a função não consegue inferi-la da sintaxe do programa. Evite dedentação automática quando espaços iniciais forem significativos em dados de exemplo, fizerem parte de uma string multilinha ou representarem alinhamento intencional em um diagrama. Para esses exemplos, prepare explicitamente o texto que deve ser exibido.

Para um exemplo de código comum, o fluxo de trabalho confiável é identificar a margem comum do código-fonte, remover essa margem uma vez e deixar o navegador renderizar o texto restante normalmente. Trate a quebra de linha e o espaçamento do contêiner como decisões separadas e, em seguida, verifique tanto o bloco visível quanto o texto subjacente.

Fontes