Skip to content

O bundler do Bun tem suporte nativo para CSS com os seguintes recursos:

  • Transpilação de recursos modernos/futuros para funcionar em todos os navegadores (incluindo vendor prefixing)
  • Minificação
  • CSS Modules
  • Tailwind (via um plugin nativo do bundler)

Transpilação

O bundler CSS do Bun permite que você use recursos modernos/futuros de CSS sem se preocupar com compatibilidade de navegadores — tudo graças aos seus recursos de transpilação e vendor prefixing que são habilitados por padrão.

O parser e bundler CSS do Bun é um port direto Rust → Zig do LightningCSS com uma abordagem de bundling inspirada no esbuild. O transpiler converte sintaxe CSS moderna em equivalentes backwards-compatible que funcionam em todos os navegadores.

NOTE

Um enorme agradecimento vai para o trabalho incrível dos autores do LightningCSS e esbuild.

Compatibilidade de Navegadores

Por padrão o bundler CSS do Bun tem como target os seguintes navegadores:

  • ES2020
  • Edge 88+
  • Firefox 78+
  • Chrome 87+
  • Safari 14+

Syntax Lowering

Nesting

A especificação CSS Nesting permite que você escreva stylesheets mais concisos e intuitivos aninhando seletores dentro uns dos outros. Em vez de repetir seletores pais em todo seu arquivo CSS você pode escrever estilos filhos diretamente dentro de seus blocos pais.

styles.css
scss
/* Com nesting */
.card {
  background: white;
  border-radius: 4px;

  .title {
    font-size: 1.2rem;
    font-weight: bold;
  }

  .content {
    padding: 1rem;
  }
}

O bundler CSS do Bun converte automaticamente esta sintaxe aninhada em CSS tradicional plano que funciona em todos os navegadores:

styles.css
css
/* Output compilado */
.card {
  background: white;
  border-radius: 4px;
}

.card .title {
  font-size: 1.2rem;
  font-weight: bold;
}

.card .content {
  padding: 1rem;
}

Você também pode aninhar media queries e outras at-rules dentro de seletores eliminando a necessidade de repetir padrões de seletores:

styles.css
scss
.responsive-element {
  display: block;

  @media (min-width: 768px) {
    display: flex;
  }
}

Isso compila para:

styles.css
css
.responsive-element {
  display: block;
}

@media (min-width: 768px) {
  .responsive-element {
    display: flex;
  }
}

Color mix

A função color-mix() oferece uma maneira fácil de misturar duas cores de acordo com uma proporção especificada em um espaço de cor escolhido. Este recurso poderoso permite que você crie variações de cores sem calcular manualmente os valores resultantes.

styles.css
scss
.button {
  /* Mistura azul e vermelho no espaço de cor RGB com proporção 30/70 */
  background-color: color-mix(in srgb, blue 30%, red);

  /* Cria uma variante mais clara para estado hover */
  &:hover {
    background-color: color-mix(in srgb, blue 30%, red, white 20%);
  }
}

O bundler CSS do Bun avalia estas misturas de cores em tempo de build quando todos os valores de cor são conhecidos (não variáveis CSS) gerando valores de cor estáticos que funcionam em todos os navegadores:

styles.css
css
.button {
  /* Computado para a cor resultante exata */
  background-color: #b31a1a;
}

.button:hover {
  background-color: #c54747;
}

Este recurso é particularmente útil para criar sistemas de cores com tons derivados programaticamente sem precisar de preprocessadores ou ferramentas customizadas.

Relative colors

CSS agora permite que você modifique componentes individuais de uma cor usando sintaxe de cor relativa. Este recurso poderoso permite que você crie variações de cores ajustando atributos específicos como luminosidade saturação ou canais individuais sem precisar recalcular toda a cor.

styles.css
css
.theme-color {
  /* Começa com uma cor base e aumenta luminosidade em 15% */
  --accent: lch(from purple calc(l + 15%) c h);

  /* Pega nosso azul de marca e faz uma versão dessaturada */
  --subtle-blue: oklch(from var(--brand-blue) l calc(c * 0.8) h);
}

O bundler CSS do Bun computa estas modificações de cor relativas em tempo de build (quando não usa variáveis CSS) e gera valores de cor estáticos para compatibilidade com navegadores:

css
.theme-color {
  --accent: lch(69.32% 58.34 328.37);
  --subtle-blue: oklch(60.92% 0.112 240.01);
}

Esta abordagem é extremamente útil para geração de temas criando variantes de cores acessíveis ou construindo escalas de cores baseadas em relações matemáticas em vez de hard-codar cada valor.

LAB colors

CSS moderno suporta espaços de cor perceptualmente uniformes como LAB LCH OKLAB e OKLCH que oferecem vantagens significantes sobre RGB tradicional. Estes espaços de cor podem representar cores fora do gamut RGB padrão resultando em designs mais vibrantes e visualmente consistentes.

styles.css
css
.vibrant-element {
  /* Um vermelho vibrante que excede limites de gamut sRGB */
  color: lab(55% 78 35);

  /* Um gradiente suave usando espaço de cor perceptual */
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}

O bundler CSS do Bun converte automaticamente estes formatos de cor avançados em alternativas backwards-compatible para navegadores que ainda não os suportam:

styles.css
css
.vibrant-element {
  /* Fallback para aproximação RGB mais próxima */
  color: #ff0f52;
  /* Fallback P3 para navegadores com suporte a gamut mais amplo */
  color: color(display-p3 1 0.12 0.37);
  /* Valor original preservado para navegadores que suportam */
  color: lab(55% 78 35);

  background: linear-gradient(to right, #cd4e15, #3887ab);
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}

Esta abordagem em camadas garante renderização de cor ótima em todos os navegadores enquanto permite que você use as mais recentes tecnologias de cor nos seus designs.

Color function

A função color() fornece uma maneira padronizada de especificar cores em vários espaços de cor predefinidos expandindo suas opções de design além do espaço RGB tradicional. Isso permite que você acesse gamuts de cores mais amplos e crie designs mais vibrantes.

styles.css
css
.vivid-element {
  /* Usando o espaço de cor Display P3 para cores de gamut mais amplo */
  color: color(display-p3 1 0.1 0.3);

  /* Usando espaço de cor A98 RGB */
  background-color: color(a98-rgb 0.44 0.5 0.37);
}

Para navegadores que ainda não suportam estas funções de cor avançadas o bundler CSS do Bun fornece fallbacks RGB apropriados:

styles.css
css
.vivid-element {
  /* Fallback RGB primeiro para máxima compatibilidade */
  color: #fa1a4c;
  /* Mantém original para navegadores que suportam */
  color: color(display-p3 1 0.1 0.3);

  background-color: #6a805d;
  background-color: color(a98-rgb 0.44 0.5 0.37);
}

Esta funcionalidade permite que você use espaços de cor modernos imediatamente enquanto garante que seus designs permaneçam funcionais em todos os navegadores com cores ótimas exibidas em navegadores que suportam e aproximações razoáveis nos outros.

HWB colors

O modelo de cor HWB (Hue, Whiteness, Blackness) fornece uma maneira intuitiva de expressar cores baseada em quanto branco ou preto é misturado com um hue puro. Muitos designers acham esta abordagem mais natural para criar variações de cores comparado a manipular valores RGB ou HSL.

styles.css
css
.easy-theming {
  /* Ciano puro sem branco ou preto adicionado */
  --primary: hwb(180 0% 0%);

  /* Mesmo hue mas com 20% de branco adicionado (tint) */
  --primary-light: hwb(180 20% 0%);

  /* Mesmo hue mas com 30% de preto adicionado (shade) */
  --primary-dark: hwb(180 0% 30%);

  /* Versão muted com branco e preto adicionados */
  --primary-muted: hwb(180 30% 20%);
}

O bundler CSS do Bun converte automaticamente cores HWB para RGB para compatibilidade com todos os navegadores:

styles.css
css
.easy-theming {
  --primary: #00ffff;
  --primary-light: #33ffff;
  --primary-dark: #00b3b3;
  --primary-muted: #339999;
}

O modelo HWB torna particularmente fácil criar variações de cores sistemáticas para design systems fornecendo uma abordagem mais intuitiva para criar tints e shades consistentes do que trabalhar diretamente com valores RGB ou HSL.

Color notation

CSS moderno introduziu maneiras mais intuitivas e concisas de expressar cores. A sintaxe de cores com separação por espaços elimina a necessidade de vírgulas em valores RGB e HSL enquanto cores hex com canais alpha fornecem uma maneira compacta de especificar transparência.

styles.css
css
.modern-styling {
  /* Notação RGB com separação por espaços (sem vírgulas) */
  color: rgb(50 100 200);

  /* RGB com separação por espaços com alpha */
  border-color: rgba(100 50 200 / 75%);

  /* Hex com canal alpha (8 dígitos) */
  background-color: #00aaff80;

  /* HSL com notação simplificada */
  box-shadow: 0 5px 10px hsl(200 50% 30% / 40%);
}

O bundler CSS do Bun converte automaticamente estes formatos de cor modernos para garantir compatibilidade com navegadores mais antigos:

styles.css
css
.modern-styling {
  /* Convertido para formato com vírgulas para navegadores mais antigos */
  color: rgb(50, 100, 200);

  /* Canais alpha manipulados apropriadamente */
  border-color: rgba(100, 50, 200, 0.75);

  /* Hex+alpha convertido para rgba quando necessário */
  background-color: rgba(0, 170, 255, 0.5);

  box-shadow: 0 5px 10px rgba(38, 115, 153, 0.4);
}

Este processo de conversão permite que você escreva CSS mais limpo e moderno enquanto garante que seus estilos funcionem corretamente em todos os navegadores.

light-dark() color function

A função light-dark() fornece uma solução elegante para implementar esquemas de cores que respeitam a preferência de sistema do usuário sem requerer media queries complexas. Esta função aceita dois valores de cor e automaticamente seleciona o apropriado baseado no contexto de esquema de cor atual.

styles.css
css
:root {
  /* Define suporte de esquema de cor */
  color-scheme: light dark;
}

.themed-component {
  /* Automaticamente escolhe a cor certa baseada na preferência do sistema */
  background-color: light-dark(#ffffff, #121212);
  color: light-dark(#333333, #eeeeee);
  border-color: light-dark(#dddddd, #555555);
}

/* Sobrescreve preferência do sistema quando necessário */
.light-theme {
  color-scheme: light;
}

.dark-theme {
  color-scheme: dark;
}

Para navegadores que ainda não suportam este recurso o bundler CSS do Bun converte para usar variáveis CSS com fallbacks apropriados:

styles.css
css
:root {
  --lightningcss-light: initial;
  --lightningcss-dark: ;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --lightningcss-light: ;
    --lightningcss-dark: initial;
  }
}

.light-theme {
  --lightningcss-light: initial;
  --lightningcss-dark: ;
  color-scheme: light;
}

.dark-theme {
  --lightningcss-light: ;
  --lightningcss-dark: initial;
  color-scheme: dark;
}

.themed-component {
  background-color: var(--lightningcss-light, #ffffff) var(--lightningcss-dark, #121212);
  color: var(--lightningcss-light, #333333) var(--lightningcss-dark, #eeeeee);
  border-color: var(--lightningcss-light, #dddddd) var(--lightningcss-dark, #555555);
}

Esta abordagem oferece uma maneira limpa de lidar com temas light e dark sem duplicar estilos ou escrever media queries complexas enquanto mantém compatibilidade com navegadores que ainda não suportam o recurso nativamente.

Logical properties

Propriedades lógicas CSS permitem que você defina layout espaçamento e dimensionamento relativo ao modo de escrita do documento e direção do texto em vez de direções físicas da tela. Isso é crucial para criar layouts verdadeiramente internacionais que automaticamente se adaptam a diferentes sistemas de escrita.

styles.css
css
.multilingual-component {
  /* Margin que se adapta à direção de escrita */
  margin-inline-start: 1rem;

  /* Padding que faz sentido independente da direção do texto */
  padding-block: 1rem 2rem;

  /* Border radius para o canto inicial no topo */
  border-start-start-radius: 4px;

  /* Size que respeita o modo de escrita */
  inline-size: 80%;
  block-size: auto;
}

Para navegadores que não suportam totalmente propriedades lógicas o bundler CSS do Bun as compila para propriedades físicas com ajustes direcionais apropriados:

styles.css
css
/* Para idiomas da esquerda para direita */
.multilingual-component:dir(ltr) {
  margin-left: 1rem;
  padding-top: 1rem;
  padding-bottom: 2rem;
  border-top-left-radius: 4px;
  width: 80%;
  height: auto;
}

/* Para idiomas da direita para esquerda */
.multilingual-component:dir(rtl) {
  margin-right: 1rem;
  padding-top: 1rem;
  padding-bottom: 2rem;
  border-top-right-radius: 4px;
  width: 80%;
  height: auto;
}

Se o seletor :dir() não for suportado fallbacks adicionais são automaticamente gerados para garantir que seus layouts funcionem apropriadamente em todos os navegadores e sistemas de escrita. Isso torna criação de designs internacionalizados muito mais simples enquanto mantém compatibilidade com navegadores mais antigos.

:dir() selector

O pseudo-classe seletor :dir() permite que você estilize elementos baseados em sua direção de texto (RTL ou LTR) fornecendo uma maneira poderosa de criar designs direction-aware sem JavaScript. Este seletor corresponde a elementos baseados em sua direcionalidade conforme determinado pelo documento ou atributos de direção explícitos.

styles.css
css
/* Aplica estilos diferentes baseados na direção do texto */
.nav-arrow:dir(ltr) {
  transform: rotate(0deg);
}

.nav-arrow:dir(rtl) {
  transform: rotate(180deg);
}

/* Posiciona elementos baseados no fluxo do texto */
.sidebar:dir(ltr) {
  border-right: 1px solid #ddd;
}

.sidebar:dir(rtl) {
  border-left: 1px solid #ddd;
}

Para navegadores que ainda não suportam o seletor :dir() o bundler CSS do Bun o converte para o seletor :lang() mais amplamente suportado com mapeamentos de linguagem apropriados:

styles.css
css
/* Convertido para usar seletores baseados em linguagem como fallback */
.nav-arrow:lang(en, fr, de, es, it, pt, nl) {
  transform: rotate(0deg);
}

.nav-arrow:lang(ar, he, fa, ur) {
  transform: rotate(180deg);
}

.sidebar:lang(en, fr, de, es, it, pt, nl) {
  border-right: 1px solid #ddd;
}

.sidebar:lang(ar, he, fa, ur) {
  border-left: 1px solid #ddd;
}

Esta conversão permite que você escreva CSS direction-aware que funciona confiavelmente em todos os navegadores até mesmo aqueles que ainda não suportam o seletor :dir() nativamente. Se múltiplos argumentos para :lang() não forem suportados fallbacks adicionais são automaticamente fornecidos.

:lang() selector

O pseudo-classe seletor :lang() permite que você target elementos baseados no idioma em que estão facilitando a aplicação de estilização específica de idioma. CSS moderno permite que o seletor :lang() aceite múltiplos códigos de idioma permitindo que você agrupe regras específicas de idioma mais eficientemente.

styles.css
css
/* Ajustes de tipografia para idiomas CJK */
:lang(zh, ja, ko) {
  line-height: 1.8;
  font-size: 1.05em;
}

/* Estilos de aspas diferentes por grupo de idioma */
blockquote:lang(fr, it, es, pt) {
  font-style: italic;
}

blockquote:lang(de, nl, da, sv) {
  font-weight: 500;
}

Para navegadores que não suportam múltiplos argumentos no seletor :lang() o bundler CSS do Bun converte esta sintaxe para usar o seletor :is() para manter o mesmo comportamento:

styles.css
css
/* Múltiplos idiomas agrupados com :is() para melhor suporte de navegadores */
:is(:lang(zh), :lang(ja), :lang(ko)) {
  line-height: 1.8;
  font-size: 1.05em;
}

blockquote:is(:lang(fr), :lang(it), :lang(es), :lang(pt)) {
  font-style: italic;
}

blockquote:is(:lang(de), :lang(nl), :lang(da), :lang(sv)) {
  font-weight: 500;
}

Se necessário o Bun pode fornecer fallbacks adicionais para :is() também garantindo que seus estilos específicos de idioma funcionem em todos os navegadores. Esta abordagem simplifica a criação de designs internacionalizados com regras tipográficas e de estilização distintas para diferentes grupos de idioma.

:is() selector

A pseudo-classe função :is() (antigamente :matches()) permite que você crie seletores mais concisos e legíveis agrupando múltiplos seletores juntos. Ela aceita uma lista de seletores como argumento e corresponde se qualquer um dos seletores naquela lista corresponder significantemente reduzindo repetição no seu CSS.

styles.css
css
/* Em vez de escrever isto separadamente */
/* 
.article h1,
.article h2,
.article h3 {
  margin-top: 1.5em;
}
*/

/* Você pode escrever isto */
.article :is(h1, h2, h3) {
  margin-top: 1.5em;
}

/* Exemplo complexo com múltiplos grupos */
:is(header, main, footer) :is(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

Para navegadores que não suportam :is() o bundler CSS do Bun fornece fallbacks usando alternativas com vendor prefix:

css
/* Fallback usando -webkit-any */
.article :-webkit-any(h1, h2, h3) {
  margin-top: 1.5em;
}

/* Fallback usando -moz-any */
.article :-moz-any(h1, h2, h3) {
  margin-top: 1.5em;
}

/* Original preservado para navegadores modernos */
.article :is(h1, h2, h3) {
  margin-top: 1.5em;
}

/* Exemplo complexo com fallbacks */
:-webkit-any(header, main, footer) :-webkit-any(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:-moz-any(header, main, footer) :-moz-any(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:is(header, main, footer) :is(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:not() selector

A pseudo-classe :not() permite que você exclua elementos que correspondem a um seletor específico. A versão moderna deste seletor aceita múltiplos argumentos permitindo que você exclua múltiplos padrões com um único seletor conciso.

styles.css
css
/* Seleciona todos os botões exceto variantes primary e secondary */
button:not(.primary, .secondary) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

/* Aplica estilos a todos os headings exceto aqueles dentro de sidebars ou footers */
h2:not(.sidebar *, footer *) {
  margin-top: 2em;
}

Para navegadores que não suportam múltiplos argumentos em :not() o bundler CSS do Bun converte esta sintaxe para uma forma mais compatível enquanto preserva o mesmo comportamento:

styles.css
css
/* Convertido para usar :not com :is() para compatibilidade */
button:not(:is(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

h2:not(:is(.sidebar *, footer *)) {
  margin-top: 2em;
}

E se :is() não for suportado o Bun pode gerar fallbacks adicionais:

styles.css
css
/* Ainda mais fallbacks para máxima compatibilidade */
button:not(:-webkit-any(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

button:not(:-moz-any(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

button:not(:is(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

Esta conversão garante que seus seletores negativos funcionem corretamente em todos os navegadores enquanto mantém a especificidade correta e comportamento do seletor original.

Math functions

CSS agora inclui um rico conjunto de funções matemáticas que permitem que você realize cálculos complexos diretamente nas suas stylesheets. Estas incluem funções matemáticas padrão (round(), mod(), rem(), abs(), sign()), funções trigonométricas (sin(), cos(), tan(), asin(), acos(), atan(), atan2()) e funções exponenciais (pow(), sqrt(), exp(), log(), hypot()).

styles.css
css
.dynamic-sizing {
  /* Clamp um valor entre mínimo e máximo */
  width: clamp(200px, 50%, 800px);

  /* Round para o múltiplo mais próximo */
  padding: round(14.8px, 5px);

  /* Trigonometria para animações ou layouts */
  transform: rotate(calc(sin(45deg) * 50deg));

  /* Matemática complexa com múltiplas funções */
  --scale-factor: pow(1.25, 3);
  font-size: calc(16px * var(--scale-factor));
}

O bundler CSS do Bun avalia estas expressões matemáticas em tempo de build quando todos os valores são constantes conhecidas (não variáveis) resultando em output otimizado:

styles.css
css
.dynamic-sizing {
  width: clamp(200px, 50%, 800px);
  padding: 15px;
  transform: rotate(35.36deg);
  --scale-factor: 1.953125;
  font-size: calc(16px * var(--scale-factor));
}

Esta abordagem permite que você escreva CSS mais expressivo e mantível com relações matemáticas significativas que então são compiladas para valores otimizados para máxima compatibilidade com navegadores e desempenho.

Media query ranges

CSS moderno suporta sintaxe de range intuitiva para media queries permitindo que você especifique breakpoints usando operadores de comparação como <, >, <= e >= em vez dos prefixes min- e max- mais verbosos. Esta sintaxe é mais legível e corresponde como normalmente pensamos sobre valores e ranges.

styles.css
css
/* Sintaxe moderna com operadores de comparação */
@media (width >= 768px) {
  .container {
    max-width: 720px;
  }
}

/* Range inclusivo usando <= e >= */
@media (768px <= width <= 1199px) {
  .sidebar {
    display: flex;
  }
}

/* Range exclusivo usando < e > */
@media (width > 320px) and (width < 768px) {
  .mobile-only {
    display: block;
  }
}

O bundler CSS do Bun converte estas queries de range modernas para sintaxe de media query tradicional para compatibilidade com todos os navegadores:

styles.css
css
/* Convertido para sintaxe min/max tradicional */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  .sidebar {
    display: flex;
  }
}

@media (min-width: 321px) and (max-width: 767px) {
  .mobile-only {
    display: block;
  }
}

Isso permite que você escreva media queries mais intuitivas e matemáticas enquanto garante que suas stylesheets funcionem corretamente em todos os navegadores incluindo aqueles que não suportam a sintaxe de range moderna.

Shorthands

CSS introduziu vários shorthand properties modernos que melhoram legibilidade e mantibilidade de código. O bundler CSS do Bun garante que estes shorthands convenientes funcionem em todos os navegadores convertendo-os para seus equivalentes longhand quando necessário.

styles.css
css
/* Shorthands de alignment */
.flex-container {
  /* Shorthand para align-items e justify-items */
  place-items: center start;

  /* Shorthand para align-content e justify-content */
  place-content: space-between center;
}

.grid-item {
  /* Shorthand para align-self e justify-self */
  place-self: end center;
}

/* Overflow de dois valores */
.content-box {
  /* Primeiro valor para horizontal, segundo para vertical */
  overflow: hidden auto;
}

/* text-decoration aprimorado */
.fancy-link {
  /* Combina múltiplas propriedades de text decoration */
  text-decoration: underline dotted blue 2px;
}

/* Sintaxe display de dois valores */
.component {
  /* Tipo de display outer + tipo de display inner */
  display: inline flex;
}

Para navegadores que não suportam estes shorthands modernos o Bun os converte para suas propriedades longhand componentes:

styles.css
css
.flex-container {
  /* Propriedades de alignment expandidas */
  align-items: center;
  justify-items: start;

  align-content: space-between;
  justify-content: center;
}

.grid-item {
  align-self: end;
  justify-self: center;
}

.content-box {
  /* Propriedades overflow separadas */
  overflow-x: hidden;
  overflow-y: auto;
}

.fancy-link {
  /* Propriedades text decoration individuais */
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: blue;
  text-decoration-thickness: 2px;
}

.component {
  /* Display de valor único */
  display: inline-flex;
}

Esta conversão garante que suas stylesheets permaneçam limpas e mantíveis enquanto fornecem a mais ampla compatibilidade possível com navegadores.

Double position gradients

A sintaxe de double position gradient é um recurso CSS moderno que permite que você crie hard color stops em gradients especificando a mesma cor em duas posições adjacentes. Isso cria uma transição sharp em vez de um fade suave que é útil para criar stripes color bands e outros designs multi-color.

styles.css
css
.striped-background {
  /* Cria uma transição sharp de verde para vermelho em 30%-40% */
  background: linear-gradient(
    to right,
    yellow 0%,
    green 20%,
    green 30%,
    red 30%,
    /* Double position cria hard stop */ red 70%,
    blue 70%,
    blue 100%
  );
}

.progress-bar {
  /* Cria seções de cor distintas */
  background: linear-gradient(
    to right,
    #4caf50 0% 25%,
    /* Verde de 0% a 25% */ #ffc107 25% 50%,
    /* Amarelo de 25% a 50% */ #2196f3 50% 75%,
    /* Azul de 50% a 75% */ #9c27b0 75% 100% /* Roxo de 75% a 100% */
  );
}

Para navegadores que não suportam esta sintaxe o bundler CSS do Bun automaticamente converte para o formato tradicional duplicando color stops:

styles.css
css
.striped-background {
  background: linear-gradient(
    to right,
    yellow 0%,
    green 20%,
    green 30%,
    red 30%,
    /* Dividido em dois color stops */ red 70%,
    blue 70%,
    blue 100%
  );
}

.progress-bar {
  background: linear-gradient(
    to right,
    #4caf50 0%,
    #4caf50 25%,
    /* Dois stops para seção verde */ #ffc107 25%,
    #ffc107 50%,
    /* Dois stops para seção amarela */ #2196f3 50%,
    #2196f3 75%,
    /* Dois stops para seção azul */ #9c27b0 75%,
    #9c27b0 100% /* Dois stops para seção roxa */
  );
}

Esta conversão permite que você use a sintaxe double position mais limpa no seu código fonte enquanto garante que gradients sejam exibidos corretamente em todos os navegadores.

system-ui font

A generic font family system-ui permite que você use a fonte UI nativa do dispositivo criando interfaces que se sentem mais integradas com o sistema operacional. Isso fornece um look and feel mais nativo sem ter que especificar diferentes font stacks para cada plataforma.

styles.css
css
.native-interface {
  /* Usa a fonte UI padrão do sistema */
  font-family: system-ui;
}

.fallback-aware {
  /* Fonte UI do sistema com fallbacks explícitos */
  font-family: system-ui, sans-serif;
}

Para navegadores que não suportam system-ui o bundler CSS do Bun automaticamente expande para um comprehensive cross-platform font stack:

styles.css
css
.native-interface {
  /* Expandido para suportar todas as principais plataformas */
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    "Noto Sans",
    Ubuntu,
    Cantarell,
    "Helvetica Neue";
}

.fallback-aware {
  /* Preserva o fallback original após o stack expandido */
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    "Noto Sans",
    Ubuntu,
    Cantarell,
    "Helvetica Neue",
    sans-serif;
}

Esta abordagem oferece a simplicidade de escrever apenas system-ui no seu código fonte enquanto garante que sua interface se adapte corretamente a todos os sistemas operacionais e navegadores. O font stack expandido inclui fontes de sistema apropriadas para macOS/iOS, Windows, Android, Linux e fallbacks para navegadores mais antigos.

CSS Modules

O bundler do Bun também suporta bundling de CSS modules além de CSS regular com suporte para os seguintes recursos:

  • Detecção automática de arquivos CSS module (.module.css) com zero configuração
  • Composition (propriedade composes)
  • Importação de CSS modules para JSX/TSX
  • Warnings/errors para usos inválidos de CSS modules

Um CSS module é um arquivo CSS (com a extensão .module.css) onde todos os class names e animations são scoped ao arquivo. Isso ajuda você a evitar colisões de class names já que declarações CSS são globalmente scoped por padrão.

Por baixo dos panos o bundler do Bun transforma class names localmente scoped em unique identifiers.

Getting started

Crie um arquivo CSS com a extensão .module.css:

styles.module.css
css
.button {
  color: red;
}
other-styles.module.css
css
.button {
  color: blue;
}

Você pode então importar este arquivo por exemplo em um arquivo TSX:

app.tsx
tsx
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";

export default function App() {
  return (
    <>
      <button className={styles.button}>Red button!</button>
      <button className={otherStyles.button}>Blue button!</button>
    </>
  );
}

O objeto styles de importar o arquivo CSS module será um objeto com todos os class names como keys e seus unique identifiers como values:

app.tsx
ts
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";

console.log(styles);
console.log(otherStyles);

Isso outputará:

app.tsx
ts
{
  button: "button_123";
}

{
  button: "button_456";
}

Como você pode ver os class names são únicos para cada arquivo evitando quaisquer colisões!

Composition

CSS modules permitem que você compose class selectors juntos. Isso permite que você reutilize style rules em múltiplas classes.

Por exemplo:

styles.module.css
css
.button {
  composes: background;
  color: red;
}

.background {
  background-color: blue;
}

Seria o mesmo que escrever:

styles.module.css
css
.button {
  background-color: blue;
  color: red;
}

.background {
  background-color: blue;
}

Há algumas regras para manter em mente ao usar composes:

styles.module.css
css
#button {
  /* Inválido! `#button` não é um class selector */
  composes: background;
}

.button,
.button-secondary {
  /* Inválido! `.button, .button-secondary` não é um simple selector */
  composes: background;
}

Composing de um arquivo CSS module separado

Você também pode compor classes de um arquivo CSS module separado:

background.module.css
css
.background {
  background-color: blue;
}
styles.module.css
css
.button {
  composes: background from "./background.module.css";
  color: red;
}

Bun by www.bunjs.com.cn edit