Estilos

Estilos

Use o CSS que quiser. Para estilos com escopo escritos junto dos componentes, o @velozjs/css oferece css, styled e a prop css.

CSS comum funciona

O Veloz renderiza elementos reais com atributos class reais, então folhas de estilo, CSS modules e bibliotecas baseadas em classes funcionam sem mudança. Este site é estilizado com o salve-css e os ícones são do salve-icons, os dois por classes comuns.

tsx
import 'salve-css';

<button class="btn btn-soft">Salvar</button>

@velozjs/css

bash
npm install @velozjs/css

Importe uma vez na entrada do cliente. É esse import que ativa a prop css.

main.tsx
import '@velozjs/css';

css

Um template com tag que devolve um nome de classe com escopo. Declarações no nível de cima valem para a classe. Regras aninhadas sempre ficam com escopo: & indica onde entra a classe, e uma regra sem & vale para os descendentes. @media, @supports e @container aplicam o escopo ao conteúdo, e @keyframes / @font-face ficam como foram escritos.

tsx
import { css } from '@velozjs/css';

const card = css`
  padding: 1.5rem;
  border-radius: 12px;
  &:hover { box-shadow: 0 4px 12px rgb(0 0 0 / 0.1); }
  .title { font-weight: 600; }            /* .v-xyz .title */
  @media (min-width: 40em) { padding: 2rem; }
`;

<div class={card}>…</div>;

styled

Cria um componente com seus estilos. Interpolações em função recebem as props; quando leem accessors, a classe atualiza de forma reativa.

tsx
import { styled } from '@velozjs/css';

const Button = styled('button')`
  padding: 0.5rem 1rem;
  border-radius: 999px;
  background: ${(p: { tone?: 'danger' }) => (p.tone === 'danger' ? 'crimson' : 'royalblue')};
`;

<Button tone="danger" onClick={remove}>Excluir</Button>;

A prop css

Um objeto de estilos em qualquer elemento. Seletores aninhados e at-rules funcionam, e números ganham px, menos nas propriedades sem unidade (opacity, zIndex, lineHeight...). O mesmo vale para objetos em style.

tsx
<span
  css={{
    color: 'gray',
    '&:hover': { color: 'black' },
    '.icon': { marginInlineEnd: '0.25rem' },
    '@media (min-width: 40em)': { fontSize: '1.25rem' },
  }}
>
  dica
</span>

Como funciona

  • Os nomes de classe são hashes do CSS (v-1x2y3z), então estilos idênticos compartilham uma classe.
  • Os estilos vão para uma folha de estilo construída via JS (adoptedStyleSheets), com um único <style data-veloz-css> como alternativa. Nada de escrever <style> inline, o que mantém a compatibilidade com CSP.
  • No SSR, os estilos são coletados e devolvidos pelo renderToString como css; coloque-os em <style data-veloz-css> e o cliente não os injeta de novo.