# Substituindo funções de cor do Sass por CSS nativo

> Guia prático para substituir funções de cor do Sass como lighten(), darken() e tint() por CSS moderno com color-mix() e sintaxe de cores relativas.

URL: https://dpw.dev/css/substituindo-funcoes-de-cor-sass-por-css-nativo/  
Publicado em: 2026-03-26  
Categoria: css  
Tags: sass  
Autor: Tárcio Zemel

12 anos atrás, no artigo <a href="https://www.alwaystwisted.com/articles/colour-me-sass-y/" target="_blank" rel="noopener noreferrer">Colour me Sass-y</a>, Stuart Robson apresentou uma série de helpers de cor do Sass que tornavam a estilização diária rápida e prática.

Naquela época, o Sass era o caminho mais fácil. Em 2026, o CSS moderno oferece muito mais poder nativo de manipulação de cores do que havia em 2014.

> Artigo baseado em [Un-Sass'ing My CSS: Colour Functions Without Sass](https://www.alwaystwisted.com/articles/UnSassing-my-CSS-colour-functions).

## tl;dr

Se o fluxo de trabalho com Sass depende muito de helpers de cor, estas são as principais substituições nativas em CSS:

* `rgba($color, 0.4)` → `rgb(from var(--color) r g b / 40%)`
* `lighten($color, 20%)` → `hsl(from var(--color) h s calc(l + 20))` (paridade com Sass)
* `darken($color, 20%)` → `hsl(from var(--color) h s calc(l - 20))` (paridade com Sass)
* `tint($color, 20%)` → `color-mix(in srgb, var(--color) 80%, white 20%)` (paridade com Sass)
* `shade($color, 20%)` → `color-mix(in srgb, var(--color) 80%, black 20%)` (paridade com Sass)
* `adjust-hue($color, 40deg)` → `hsl(from var(--color) calc(h + 40) s l)`
* `grayscale($color)` → `hsl(from var(--color) h 0% l)`
* `complement($color)` → `hsl(from var(--color) calc(h + 180) s l)`

`lighten()`/`darken()` e `tint()`/`shade()` não são a mesma operação no Sass. `lighten()`/`darken()` ajustam a luminosidade HSL, enquanto `tint()`/`shade()` fazem mistura com branco/preto.

Substituições adicionais:

* `saturate($color, 20%)` → `hsl(from var(--color) h calc(s + 20) l)`
* `desaturate($color, 20%)` → `hsl(from var(--color) h calc(s - 20) l)`

## Por que isso funciona melhor agora

O Sass trouxe manipulação de cores muito antes dos navegadores; agora o CSS nativo alcançou esse patamar de duas formas importantes:

1. `color-mix()` oferece mistura confiável para tints, shades e blending.
2. A **sintaxe de cores relativas** (`rgb(from ...)`, `hsl(from ...)`) permite derivar novas cores a partir de tokens existentes.

Juntas, essas funcionalidades abrem um fluxo de trabalho onde uma única cor de origem pode gerar múltiplos estados e temas.

## Uma cor de origem

A ideia é manter uma cor principal da marca como <a href="/css/variaveis-css-guia-pratico/">custom property CSS</a> e derivar tudo a partir dela.

Uma boa regra geral: usar OKLCH para os tokens e OKLab para as misturas. OKLCH — lightness, chroma, hue — é fácil de ler e ajustar manualmente. OKLab mistura de forma mais limpa, sem mudanças inesperadas de matiz no meio do caminho.

```css
:root {
  --brand: oklch(62% 0.19 26);

  /* Superfícies e ênfase */
  --brand-soft: color-mix(in oklab, var(--brand), white 88%);
  --brand-strong: color-mix(in oklab, var(--brand), black 22%);

  /* Estados */
  --brand-hover: color-mix(in oklab, var(--brand), black 12%);
  --brand-active: color-mix(in oklab, var(--brand), black 24%);
  --brand-border: color-mix(in oklab, var(--brand), black 35%);

  /* Variantes com alfa */
  --brand-alpha-08: rgb(from var(--brand) r g b / 8%);
  --brand-alpha-18: rgb(from var(--brand) r g b / 18%);
}
```

Com essa abordagem, não se está mais armazenando dez valores hex sem relação entre si. Os valores são derivados de uma única custom property, o que torna refatoração e tematização muito mais fáceis. Inclusive, esse é o tipo de técnica que pode ser aproveitada para criar <a href="/css/dark-mode-css-facil/">dark mode com CSS</a> de forma muito mais simples.

## Substituindo funções comuns de cor do Sass

### rgba()

A versão clássica do Sass:

```scss
$brand: #d13400;
background-color: rgba($brand, 20%);
```

Equivalente em CSS nativo:

```css
:root {
  --brand: #d13400;
}

.alert {
  background-color: rgb(from var(--brand) r g b / 20%);
}
```

[Exemplo no CodePen](https://codepen.io/sturobson/pen/YPGWRYE/f48f1652d5c6607abb50d5d49cc064cc)

### lighten() e darken()

Ambas são nativas do Sass e ajustam a luminosidade HSL diretamente:

```scss
lighten(#6b717f, 20%);
darken(#6b717f, 20%);
```

Equivalente em CSS nativo usando sintaxe de cores relativas:

```css
:root {
  --brand: #6b717f;

  --brand-lighten-20: hsl(from var(--brand) h s calc(l + 20));
  --brand-darken-20: hsl(from var(--brand) h s calc(l - 20));
}
```

Para resultados com aparência mais natural, pode-se usar OKLCH:

```css
:root {
  --brand: #6b717f;

  --brand-lighten-20: oklch(from var(--brand) calc(l + 0.2) c h);
  --brand-darken-20: oklch(from var(--brand) calc(l - 0.2) c h);
}
```

[Exemplo no CodePen](https://codepen.io/sturobson/pen/pvEbQpM/0acf557ff6ab01907c755d1a15fd7d97)

### tint() e shade()

Estas não eram nativas do Sass, eram comumente escritas como helpers personalizados ou obtidas de uma biblioteca:

```scss
@function tint($color, $percentage) {
  @return mix(white, $color, $percentage);
}

@function shade($color, $percentage) {
  @return mix(black, $color, $percentage);
}
```

Equivalente em CSS nativo usando `color-mix()`. Pode-se usar `srgb` para paridade com o Sass, ou trocar para `oklab` para misturas com melhor aparência perceptual:

```css
:root {
  --brand: #6b717f;

  /* srgb: mais próximo da saída do Sass */
  --brand-tint-20: color-mix(in srgb, var(--brand) 80%, white 20%);
  --brand-shade-20: color-mix(in srgb, var(--brand) 80%, black 20%);

  /* oklab: melhor mistura perceptual */
  --brand-tint-20: color-mix(in oklab, var(--brand) 80%, white 20%);
  --brand-shade-20: color-mix(in oklab, var(--brand) 80%, black 20%);
}
```

[Exemplo no CodePen](https://codepen.io/sturobson/pen/bNweQLO/2d26c2edce25ee3de612934820ac0436)

### adjust-hue() e complement()

As versões do Sass:

```scss
adjust-hue(#d13400, 40deg);
complement(#d13400);
```

Equivalente em CSS nativo usando sintaxe de cores relativas em `hsl()`:

```css
:root {
  --brand: #d13400;

  --brand-shift-40: hsl(from var(--brand) calc(h + 40) s l);
  --brand-complement: hsl(from var(--brand) calc(h + 180) s l);
}
```

Demonstração de `adjust-hue()`:

[Exemplo no CodePen](https://codepen.io/sturobson/pen/pvEbQaM/b3ab88307b875b4481c6c1c04ada0a3a)

Demonstração de `complement()`:

[Exemplo no CodePen](https://codepen.io/sturobson/pen/zxKBMWq/6d1df1d86ee14c07e54756148c81b18e)

### grayscale()

A versão do Sass:

```scss
grayscale(#d13400);
```

Equivalente em CSS nativo:

```css
:root {
  --brand: #d13400;
  --brand-gray: hsl(from var(--brand) h 0% l);
}
```

[Exemplo no CodePen](https://codepen.io/sturobson/pen/LERZXdy/c1b4b422a29e2c8dff3802d6c4fa2242)

### saturate() e desaturate()

As versões do Sass:

```scss
saturate(#d13400, 20%);
desaturate(#d13400, 20%);
```

Equivalente em CSS nativo:

```css
:root {
  --brand: #d13400;

  --brand-more-sat: hsl(from var(--brand) h calc(s + 20) l);
  --brand-less-sat: hsl(from var(--brand) h calc(s - 20) l);
}
```

[Exemplo no CodePen](https://codepen.io/sturobson/pen/myrEQxx/5d632adefad93b47c17381b466cf577d)

## Um exemplo prático de componente

Aqui está uma receita simples de botão que obtém todos os seus estados de cor a partir de um único token.

```css
:root {
  --btn: oklch(58% 0.2 28);
  --btn-text: white;

  --btn-hover: color-mix(in oklab, var(--btn), black 10%);
  --btn-active: color-mix(in oklab, var(--btn), black 18%);
  --btn-ring: rgb(from var(--btn) r g b / 35%);
  --btn-subtle-bg: color-mix(in oklab, var(--btn), white 90%);
}

.button {
  background: var(--btn);
  color: var(--btn-text);
  border: 1px solid color-mix(in oklab, var(--btn), black 30%);
  box-shadow: 0 0 0 0 var(--btn-ring);
}

.button:hover {
  background: var(--btn-hover);
}

.button:active {
  background: var(--btn-active);
}

.button:focus-visible {
  box-shadow: 0 0 0 0.25rem var(--btn-ring);
}

.button--subtle {
  background: var(--btn-subtle-bg);
  color: color-mix(in oklab, var(--btn), black 45%);
}
```

[Exemplo no CodePen](https://codepen.io/sturobson/pen/QwKEJmP/244c2622cbe756b224a293845716aa2b)

Esse é um conjunto completo de estados a partir de uma única cor de origem, sem necessidade de funções Sass.

## Progressive enhancement e fallbacks

As funções de cor modernas têm excelente suporte nos navegadores, mas se for necessário dar suporte a navegadores mais antigos, será preciso usar fallbacks. A estratégia é direta: fornecer uma cor estática primeiro, depois aprimorar com `@supports`.

### Fallback básico com @supports

```css
.badge {
  /* Fallback: cor estática que funciona em qualquer lugar */
  background: #d13400;
  color: white;
}

@supports (color: color-mix(in oklab, red, white)) {
  /* Aprimoramento: cores derivadas para navegadores modernos */
  .badge {
    background: color-mix(in oklab, #d13400, white 15%);
    color: color-mix(in oklab, #d13400, black 55%);
  }
}
```

### Suporte dos navegadores

**color-mix:** `color-mix()` permite misturar duas cores com um peso especificado, sendo essencial para criar tints, shades e variações de cor personalizadas sem Sass.

**Sintaxe de cores relativas:** a sintaxe de cores relativas permite derivar novas cores a partir de existentes usando funções como `hsl(from var(--color) ...)`, possibilitando transformações de cor dinâmicas diretamente no CSS.

## Conclusão

O Sass ainda é uma ferramenta válida e ainda é utilizado por muitos. Mas, especificamente para trabalho com cores, o CSS nativo passou de "quase lá" para "muito utilizável".

Se o projeto pode contar com suporte a navegadores modernos, já é possível fazer bastante manipulação de cores diretamente em CSS. Ou seja, dá para "des-Sassificar" o CSS um pouco mais.

Para quem quer se aprofundar, vale conferir também o artigo sobre <a href="/css/variaveis-css-valores-possiveis/">o que é possível colocar em uma variável CSS</a> e a discussão sobre se <a href="/css/variaveis-css-loops-sass/">variáveis CSS são melhores que loops de Sass</a>.

---

Fonte: [dpw - desenvolvimento para web](https://dpw.dev/) (pt-BR).
Guia para agentes: https://dpw.dev/llms.txt
Índice completo: https://dpw.dev/sitemap-index.xml
Feed: https://dpw.dev/rss.xml
