Search buenoDC

Nesta página
  1. O que é um SVG
  2. Três jeitos de colocar um SVG na página
  3. Quando vale a pena usar SVG direto no HTML
  4. Passo 1: colar o SVG no HTML
  5. Passo 2: trocar as cores pelo CSS
  6. Passo 3: carregar a fonte de mão
  7. Exemplo do zero
  8. Cuidado ao trocar a fonte

9 min de leitura

Diagramas do Excalidraw que seguem o tema do site

O Excalidraw é uma ferramenta online para desenhar diagramas com cara de rascunho feito à mão, ótima para explicar uma ideia com caixas e setas. Ele exporta o desenho em SVG. Quando você coloca esse arquivo num site com tema claro e escuro usando a tag <img>, aparecem dois problemas: as cores ficam fixas (os traços pretos somem no fundo escuro) e, dependendo da versão do Excalidraw, a letra de mão vira uma fonte comum.

O diagrama abaixo usa as mesmas cores e a mesma fonte de um SVG exportado pelo Excalidraw. Troque o tema do site no botão do topo e veja as cores acompanharem.

Cliente requisição Servidor

O tutorial começa pelo que é um SVG e termina com um exemplo completo, montado do zero.

O que é um SVG

Uma foto em JPG ou PNG é uma imagem de bitmap: uma grade de pontinhos coloridos, os pixels. Se você amplia, os pixels aparecem e a imagem fica borrada.

O SVG (Scalable Vector Graphics) é uma imagem vetorial. Em vez de pixels, ele guarda a descrição das formas: “um retângulo nesta posição, com este tamanho, contorno preto”. O navegador desenha essas formas na hora, no tamanho que for preciso, então o desenho fica nítido numa tela de celular e num telão.

Um SVG também é um arquivo de texto, escrito com tags, como o HTML. Abra um .svg num editor de código e você vê algo assim:

<svg viewBox="0 0 420 120">
  <rect x="10" y="30" width="120" height="60" fill="#a5d8ff" stroke="#1e1e1e" />
  <text x="70" y="67" font-family="Excalifont, Xiaolai, Segoe UI Emoji" fill="#1e1e1e">Cliente</text>
</svg>
  • <rect> é um retângulo, <text> é um texto e <path> (que aparece bastante nos arquivos do Excalidraw) é uma linha qualquer, como uma seta.
  • stroke é a cor do contorno e fill é a cor do preenchimento.
  • #1e1e1e é o quase preto que o Excalidraw usa para traços e textos.
  • font-family diz qual fonte usar. A Excalifont é a letra de mão do Excalidraw.
  • viewBox define o sistema de coordenadas do desenho. É ele que permite o SVG crescer e diminuir sem distorcer.

Três jeitos de colocar um SVG na página

JeitoExemploA fonte de fora carrega?O CSS da página alcança o desenho?
Tag <img><img src="diagrama.svg" alt="...">NãoNão
Fundo no CSSbackground-image: url(diagrama.svg)NãoNão
SVG direto no HTML (inline)o conteúdo do .svg colado na páginaSimSim

Nos dois primeiros jeitos, o navegador trata o SVG como uma imagem fechada. Por segurança, uma imagem não pode baixar outros arquivos nem rodar nada, e o CSS da página não entra nela. Para uma foto isso não faz diferença. Para um diagrama, significa que:

  • se o SVG busca a fonte num endereço da internet ou num arquivo ao lado (algumas versões do Excalidraw fazem isso), a fonte não carrega e o texto aparece numa fonte genérica;
  • uma regra de tema escuro na sua página não muda as cores do desenho, porque elas estão escritas nos atributos stroke e fill, longe do alcance do CSS.

Colado direto no HTML, o SVG faz parte da página, como um <div> ou um <p>: usa as fontes dela e obedece ao CSS dela.

Quando vale a pena usar SVG direto no HTML

Use essa técnica quando o desenho precisa conversar com a página:

  • diagramas e esquemas que precisam funcionar nos temas claro e escuro;
  • ícones que mudam de cor no hover ou acompanham a cor do texto;
  • desenhos com texto, quando você quer que o texto use a mesma fonte do site.

Prefira o <img> quando:

  • a imagem é uma foto ou uma ilustração cheia de cores, que fica igual em qualquer tema;
  • o mesmo SVG grande aparece em muitas páginas. Com <img>, o navegador baixa o arquivo uma vez e guarda em cache. Colado no HTML, o desenho vai junto com cada página;
  • o SVG veio de uma fonte em que você não confia. Um SVG colado no HTML pode conter scripts, que rodam na sua página. Os arquivos que você mesmo exporta do Excalidraw não têm esse problema.

Passo 1: colar o SVG no HTML

Copie o conteúdo do .svg e cole dentro do HTML, no lugar onde o desenho deve aparecer. Antes, faça alguns ajustes na tag <svg>:

  • Apague os atributos width e height. O Excalidraw exporta com medidas fixas e enormes. Sem elas, o desenho se adapta à largura da página. Mantenha o viewBox, que guarda a proporção.
  • Acrescente uma classe, por exemplo class="diagrama", para o CSS encontrar o desenho.
  • Acrescente role="img" e um aria-label com a descrição do diagrama. Eles fazem o papel do alt de uma imagem para quem usa leitor de tela.

Se o arquivo tiver um bloco <defs> com um <style> que declara a fonte (@font-face ou @import), apague esse bloco. A fonte vai ser declarada no CSS da página, no passo 3.

index.html
<svg class="diagrama" viewBox="0 0 420 120" role="img" aria-label="Cliente enviando uma requisição ao servidor">
  <rect x="10" y="30" width="120" height="60" fill="#a5d8ff" stroke="#1e1e1e" />
  <text font-family="Excalifont, Xiaolai, Segoe UI Emoji" fill="#1e1e1e">Cliente</text>
  <!-- ...o resto do desenho, do jeito que veio do Excalidraw -->
</svg>

O desenho já aparece. As cores ainda são as do arquivo, porque continuam escritas nos atributos.

Passo 2: trocar as cores pelo CSS

Atributos como stroke e fill se chamam atributos de apresentação. Eles têm a prioridade mais baixa possível: qualquer regra de CSS para a mesma propriedade passa por cima deles. Então dá para trocar as cores sem editar o desenho. Para isso, use um seletor de atributo, que escolhe os elementos pelo valor de um atributo:

style.css
/* Traços e textos quase pretos passam a usar a cor do texto da página. */
.diagrama [stroke="#1e1e1e"] {
  stroke: currentColor;
}

.diagrama [fill="#1e1e1e"] {
  fill: currentColor;
}

O seletor [stroke="#1e1e1e"] encontra todo elemento com exatamente esse valor no atributo stroke. Colocando .diagrama antes, a regra só vale dentro do diagrama.

O currentColor significa “a cor do texto deste elemento”. O SVG herda a cor do texto da página, então, se o texto é escuro no tema claro e claro no tema escuro, os traços acompanham sozinhos.

Para as outras cores, como o azul-claro de preenchimento, use variáveis CSS com um valor para cada tema:

style.css
:root {
  --texto: #17171a;
  --fundo: #ffffff;
  --destaque-suave: #dbe4f5;
}

@media (prefers-color-scheme: dark) {
  :root {
    --texto: #f2f2f3;
    --fundo: #111114;
    --destaque-suave: #263248;
  }
}

.diagrama [fill="#a5d8ff"] {
  fill: var(--destaque-suave);
}

A @media (prefers-color-scheme: dark) vale quando o sistema operacional da pessoa está no modo escuro. Dentro dela, você redefine as variáveis, e tudo que usa var(--destaque-suave) muda junto.

Para saber quais cores trocar, procure no .svg por stroke="# e fill="#. Um diagrama do Excalidraw costuma ter poucas cores, repetidas muitas vezes. Os destaques coloridos (azul, roxo, vermelho) em geral funcionam bem nos dois temas. Se algum ficar escuro demais no fundo escuro, dê a ele uma versão mais clara dentro da @media.

Passo 3: carregar a fonte de mão

O texto do diagrama já pede a Excalifont no font-family. Falta a página saber onde está o arquivo da fonte. Ela é livre, com a licença SIL Open Font License, e fica no repositório do Excalidraw, dividida em vários arquivos, um para cada grupo de caracteres. O arquivo Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2 tem as letras sem acento e as acentuadas do português (á, ã, ç, é, õ…). Baixe esse arquivo e guarde no projeto, numa pasta fonts. A licença pede que o texto dela acompanhe a fonte, então guarde também uma cópia da licença.

Depois, declare a fonte no CSS com o mesmo nome que o SVG usa:

style.css
@font-face {
  font-family: "Excalifont";
  src: url("fonts/Excalifont-Regular.woff2") format("woff2");
  font-display: swap;
}

O font-display: swap mostra o texto numa fonte comum enquanto a Excalifont carrega, em vez de deixar o texto invisível.

Exemplo do zero

Um projeto completo, do desenho no Excalidraw até a página funcionando nos dois temas.

1. Desenhe e exporte

  1. Abra o Excalidraw e desenhe dois retângulos, um ao lado do outro, ligados por uma seta.
  2. Escreva “Cliente” num retângulo e “Servidor” no outro. Pinte o fundo do primeiro de azul-claro.
  3. Abra o menu e escolha exportar a imagem. Desmarque a opção de fundo (senão vem um retângulo branco atrás do desenho, que fica estranho no tema escuro) e a de modo escuro. Clique em SVG.

2. Monte a pasta do projeto

meu-projeto/
├── index.html
├── style.css
└── fonts/
    ├── Excalifont-Regular.woff2
    └── LICENSE.txt

3. Escreva a página

Abra o SVG exportado num editor de código, copie todo o conteúdo e cole dentro do <body>. Depois aplique os ajustes do passo 1. O desenho abaixo é uma versão simplificada do que o Excalidraw gera, mas o processo é o mesmo com o arquivo real, que é bem mais longo.

index.html
<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cliente e servidor</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <h1>Como funciona uma requisição</h1>

    <svg class="diagrama" viewBox="0 0 420 120" role="img" aria-label="Cliente enviando uma requisição ao servidor">
      <rect x="10" y="30" width="120" height="60" rx="8" fill="#a5d8ff" stroke="#1e1e1e" stroke-width="2" />
      <text x="70" y="67" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="22" fill="#1e1e1e" text-anchor="middle">Cliente</text>
      <path d="M140 60H272M262 52L274 60L262 68" fill="none" stroke="#1971c2" stroke-width="2" />
      <text x="206" y="48" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="16" fill="#1971c2" text-anchor="middle">requisição</text>
      <rect x="290" y="30" width="120" height="60" rx="8" fill="none" stroke="#1e1e1e" stroke-width="2" />
      <text x="350" y="67" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="22" fill="#1e1e1e" text-anchor="middle">Servidor</text>
    </svg>

    <p>O navegador (cliente) pede a página ao servidor, que responde com o HTML.</p>
  </body>
</html>

4. Escreva o CSS

style.css
@font-face {
  font-family: "Excalifont";
  src: url("fonts/Excalifont-Regular.woff2") format("woff2");
  font-display: swap;
}

:root {
  --texto: #17171a;
  --fundo: #ffffff;
  --destaque: #1971c2;
  --destaque-suave: #dbe4f5;
}

@media (prefers-color-scheme: dark) {
  :root {
    --texto: #f2f2f3;
    --fundo: #111114;
    --destaque: #74c0fc;
    --destaque-suave: #263248;
  }
}

body {
  max-width: 40rem;
  margin: 2rem auto;
  padding: 0 1rem;
  background: var(--fundo);
  color: var(--texto);
  font-family: system-ui, sans-serif;
}

.diagrama {
  display: block;
  width: 100%;
  height: auto;
}

.diagrama [stroke="#1e1e1e"] {
  stroke: currentColor;
}

.diagrama [fill="#1e1e1e"] {
  fill: currentColor;
}

.diagrama [fill="#a5d8ff"] {
  fill: var(--destaque-suave);
}

.diagrama [stroke="#1971c2"] {
  stroke: var(--destaque);
}

.diagrama [fill="#1971c2"] {
  fill: var(--destaque);
}

Repare que o azul da seta (#1971c2) também virou variável: ele é escuro demais para o fundo escuro, então ganhou uma versão mais clara no tema escuro.

5. Teste os dois temas

Abra o index.html no navegador. Para ver o tema escuro, mude o sistema operacional para o modo escuro, ou use as ferramentas de desenvolvedor: no Chrome, abra o DevTools, aperte Ctrl + Shift + P (Cmd + Shift + P no Mac), digite “dark” e escolha a opção que emula prefers-color-scheme: dark. Os traços e os textos devem ficar claros, a caixa do cliente num azul escuro suave e o texto em letra de mão nos dois casos.

Cuidado ao trocar a fonte

O Excalidraw posiciona cada texto calculando a largura das letras da fonte usada no desenho. Se você troca a fonte pelo CSS, por exemplo, colocando letra de mão num texto que foi escrito com a fonte de código do Excalidraw, as palavras mudam de largura. Setas e caixas desenhadas em volta de uma palavra podem sair do lugar. Se precisar de outra fonte num texto, troque dentro do próprio Excalidraw, ajuste o desenho e exporte de novo.