El empaquetador de Bun tiene soporte integrado para CSS con las siguientes características:
- Transpilación de características modernas/futuras para funcionar en todos los navegadores (incluyendo prefijos de proveedor)
- Minificación
- Módulos CSS
- Tailwind (vía un plugin nativo del empaquetador)
Transpilación
El empaquetador CSS de Bun te permite usar características CSS modernas/futuras sin tener que preocuparte por la compatibilidad con navegadores, todo gracias a sus características de transpilación y prefijos de proveedor que están habilitadas por defecto.
El analizador y empaquetador CSS de Bun es un port directo Rust → Zig de LightningCSS, con un enfoque de empaquetado inspirado en esbuild. El transpilador convierte la sintaxis CSS moderna en equivalentes compatibles con versiones anteriores que funcionan en todos los navegadores.
NOTE
Un gran agradecimiento va al increíble trabajo de los autores de LightningCSS y esbuild.Compatibilidad con Navegadores
Por defecto, el empaquetador CSS de Bun tiene como objetivo los siguientes navegadores:
- ES2020
- Edge 88+
- Firefox 78+
- Chrome 87+
- Safari 14+
Reducción de Sintaxis
Anidamiento
La especificación CSS Nesting te permite escribir hojas de estilo más concisas e intuitivas anidando selectores uno dentro de otro. En lugar de repetir selectores padre en todo tu archivo CSS, puedes escribir estilos hijos directamente dentro de sus bloques padre.
/* Con anidamiento */
.card {
background: white;
border-radius: 4px;
.title {
font-size: 1.2rem;
font-weight: bold;
}
.content {
padding: 1rem;
}
}El empaquetador CSS de Bun convierte automáticamente esta sintaxis anidada en CSS plano tradicional que funciona en todos los navegadores:
/* Salida compilada */
.card {
background: white;
border-radius: 4px;
}
.card .title {
font-size: 1.2rem;
font-weight: bold;
}
.card .content {
padding: 1rem;
}También puedes anidar media queries y otras reglas at dentro de selectores, eliminando la necesidad de repetir patrones de selectores:
.responsive-element {
display: block;
@media (min-width: 768px) {
display: flex;
}
}Esto se compila a:
.responsive-element {
display: block;
}
@media (min-width: 768px) {
.responsive-element {
display: flex;
}
}Mezcla de colores
La función color-mix() te ofrece una forma fácil de mezclar dos colores según una proporción especificada en un espacio de color elegido. Esta poderosa característica te permite crear variaciones de color sin calcular manualmente los valores resultantes.
.button {
/* Mezcla azul y rojo en el espacio de color RGB con proporción 30/70 */
background-color: color-mix(in srgb, blue 30%, red);
/* Crea una variante más clara para el estado hover */
&:hover {
background-color: color-mix(in srgb, blue 30%, red, white 20%);
}
}El empaquetador CSS de Bun evalúa estas mezclas de colores en tiempo de construcción cuando todos los valores de color son conocidos (no variables CSS), generando valores de color estáticos que funcionan en todos los navegadores:
.button {
/* Calculado al color resultante exacto */
background-color: #b31a1a;
}
.button:hover {
background-color: #c54747;
}Esta característica es particularmente útil para crear sistemas de color con tonos, tintes y acentos derivados programáticamente sin necesitar preprocesadores o herramientas personalizadas.
Colores relativos
CSS ahora te permite modificar componentes individuales de un color usando sintaxis de color relativo. Esta poderosa característica te permite crear variaciones de color ajustando atributos específicos como luminosidad, saturación o canales individuales sin tener que recalcular todo el color.
.theme-color {
/* Comienza con un color base y aumenta la luminosidad un 15% */
--accent: lch(from purple calc(l + 15%) c h);
/* Toma nuestro azul de marca y haz una versión desaturada */
--subtle-blue: oklch(from var(--brand-blue) l calc(c * 0.8) h);
}El empaquetador CSS de Bun computa estas modificaciones de color relativo en tiempo de construcción (cuando no se usan variables CSS) y genera valores de color estáticos para compatibilidad con navegadores:
.theme-color {
--accent: lch(69.32% 58.34 328.37);
--subtle-blue: oklch(60.92% 0.112 240.01);
}Este enfoque es extremadamente útil para generación de temas, crear variantes de color accesibles o construir escalas de color basadas en relaciones matemáticas en lugar de codificar cada valor.
Colores LAB
El CSS moderno soporta espacios de color perceptualmente uniformes como LAB, LCH, OKLAB y OKLCH que ofrecen ventajas significativas sobre el RGB tradicional. Estos espacios de color pueden representar colores fuera de la gama RGB estándar, resultando en diseños más vibrantes y visualmente consistentes.
.vibrant-element {
/* Un rojo vibrante que excede los límites de la gama sRGB */
color: lab(55% 78 35);
/* Un degradado suave usando espacio de color perceptual */
background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}El empaquetador CSS de Bun convierte automáticamente estos formatos de color avanzados a alternativas compatibles con versiones anteriores para navegadores que aún no los soportan:
.vibrant-element {
/* Fallback a aproximación RGB más cercana */
color: #ff0f52;
/* Fallback P3 para navegadores con soporte de gama más amplia */
color: color(display-p3 1 0.12 0.37);
/* Valor original preservado para navegadores que lo soportan */
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));
}Este enfoque en capas asegura un renderizado de color óptimo en todos los navegadores mientras te permite usar las últimas tecnologías de color en tus diseños.
Función color
La función color() proporciona una forma estandarizada de especificar colores en varios espacios de color predefinidos, expandiendo tus opciones de diseño más allá del espacio RGB tradicional. Esto te permite acceder a gamas de color más amplias y crear diseños más vibrantes.
.vivid-element {
/* Usando el espacio de color Display P3 para colores de gama más amplia */
color: color(display-p3 1 0.1 0.3);
/* Usando espacio de color A98 RGB */
background-color: color(a98-rgb 0.44 0.5 0.37);
}Para navegadores que aún no soportan estas funciones de color avanzadas, el empaquetador CSS de Bun proporciona fallbacks RGB apropiados:
.vivid-element {
/* Fallback RGB primero para máxima compatibilidad */
color: #fa1a4c;
/* Original mantenido para navegadores que lo soportan */
color: color(display-p3 1 0.1 0.3);
background-color: #6a805d;
background-color: color(a98-rgb 0.44 0.5 0.37);
}Esta funcionalidad te permite usar espacios de color modernos inmediatamente mientras aseguras que tus diseños permanezcan funcionales en todos los navegadores, con colores óptimos mostrados en navegadores compatibles y aproximaciones razonables en otros.
Colores HWB
El modelo de color HWB (Hue, Whiteness, Blackness / Tono, Blancura, Negruzco) proporciona una forma intuitiva de expresar colores basada en cuánta blancura o negrura se mezcla con un tono puro. Muchos diseñadores encuentran este enfoque más natural para crear variaciones de color comparado con manipular valores RGB o HSL.
.easy-theming {
/* Cian puro sin blancura ni negrura añadida */
--primary: hwb(180 0% 0%);
/* Mismo tono, pero con 20% de blancura añadida (tinte) */
--primary-light: hwb(180 20% 0%);
/* Mismo tono, pero con 30% de negrura añadida (sombra) */
--primary-dark: hwb(180 0% 30%);
/* Versión atenuada con blancura y negrura añadidas */
--primary-muted: hwb(180 30% 20%);
}El empaquetador CSS de Bun convierte automáticamente los colores HWB a RGB para compatibilidad con todos los navegadores:
.easy-theming {
--primary: #00ffff;
--primary-light: #33ffff;
--primary-dark: #00b3b3;
--primary-muted: #339999;
}El modelo HWB hace particularmente fácil crear variaciones de color sistemáticas para sistemas de diseño, proporcionando un enfoque más intuitivo para crear tintes y sombras consistentes que trabajar directamente con valores RGB o HSL.
Notación de color
El CSS moderno ha introducido formas más intuitivas y concisas de expresar colores. La sintaxis de color separada por espacios elimina la necesidad de comas en valores RGB y HSL, mientras que los colores hex con canales alfa proporcionan una forma compacta de especificar transparencia.
.modern-styling {
/* Notación RGB separada por espacios (sin comas) */
color: rgb(50 100 200);
/* RGB separado por espacios con alfa */
border-color: rgba(100 50 200 / 75%);
/* Hex con canal alfa (8 dígitos) */
background-color: #00aaff80;
/* HSL con notación simplificada */
box-shadow: 0 5px 10px hsl(200 50% 30% / 40%);
}El empaquetador CSS de Bun convierte automáticamente estos formatos de color modernos para asegurar compatibilidad con navegadores más antiguos:
.modern-styling {
/* Convertido a formato de comas para navegadores antiguos */
color: rgb(50, 100, 200);
/* Canales alfa manejados apropiadamente */
border-color: rgba(100, 50, 200, 0.75);
/* Hex+alfa convertido a rgba cuando es necesario */
background-color: rgba(0, 170, 255, 0.5);
box-shadow: 0 5px 10px rgba(38, 115, 153, 0.4);
}Este proceso de conversión te permite escribir CSS más limpio y moderno mientras aseguras que tus estilos funcionen correctamente en todos los navegadores.
Función de color light-dark()
La función light-dark() proporciona una solución elegante para implementar esquemas de color que respetan la preferencia del sistema del usuario sin requerir media queries complejas. Esta función acepta dos valores de color y selecciona automáticamente el apropiado basado en el contexto del esquema de color actual.
:root {
/* Define soporte de esquema de color */
color-scheme: light dark;
}
.themed-component {
/* Automáticamente elige el color correcto basado en la preferencia del sistema */
background-color: light-dark(#ffffff, #121212);
color: light-dark(#333333, #eeeeee);
border-color: light-dark(#dddddd, #555555);
}
/* Sobrescribe la preferencia del sistema cuando sea necesario */
.light-theme {
color-scheme: light;
}
.dark-theme {
color-scheme: dark;
}Para navegadores que aún no soportan esta característica, el empaquetador CSS de Bun lo convierte para usar variables CSS con fallbacks apropiados:
: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);
}Este enfoque te da una forma limpia de manejar temas claros y oscuros sin duplicar estilos o escribir media queries complejas, mientras mantienes compatibilidad con navegadores que aún no soportan la característica nativamente.
Propiedades lógicas
Las propiedades lógicas CSS te permiten definir diseño, espaciado y dimensionamiento relativo al modo de escritura del documento y dirección del texto en lugar de direcciones físicas de pantalla. Esto es crucial para crear diseños verdaderamente internacionales que se adapten automáticamente a diferentes sistemas de escritura.
.multilingual-component {
/* Margen que se adapta a la dirección de escritura */
margin-inline-start: 1rem;
/* Relleno que tiene sentido sin importar la dirección del texto */
padding-block: 1rem 2rem;
/* Radio de borde para la esquina inicial en la parte superior */
border-start-start-radius: 4px;
/* Tamaño que respeta el modo de escritura */
inline-size: 80%;
block-size: auto;
}Para navegadores que no soportan completamente las propiedades lógicas, el empaquetador CSS de Bun las compila a propiedades físicas con ajustes direccionales apropiados:
/* Para idiomas de izquierda a derecha */
.multilingual-component:dir(ltr) {
margin-left: 1rem;
padding-top: 1rem;
padding-bottom: 2rem;
border-top-left-radius: 4px;
width: 80%;
height: auto;
}
/* Para idiomas de derecha a izquierda */
.multilingual-component:dir(rtl) {
margin-right: 1rem;
padding-top: 1rem;
padding-bottom: 2rem;
border-top-right-radius: 4px;
width: 80%;
height: auto;
}Si el selector :dir() no es soportado, se generan fallbacks adicionales automáticamente para asegurar que tus diseños funcionen correctamente en todos los navegadores y sistemas de escritura. Esto hace crear diseños internacionalizados mucho más simple mientras mantienes compatibilidad con navegadores antiguos.
Selector :dir()
El selector pseudo-clase :dir() te permite estilizar elementos basado en su dirección de texto (RTL o LTR), proporcionando una forma poderosa de crear diseños conscientes de la dirección sin JavaScript. Este selector coincide con elementos basado en su direccionalidad según lo determinado por el documento o atributos de dirección explícitos.
/* Aplica diferentes estilos basado en la dirección del texto */
.nav-arrow:dir(ltr) {
transform: rotate(0deg);
}
.nav-arrow:dir(rtl) {
transform: rotate(180deg);
}
/* Posiciona elementos basado en el flujo del texto */
.sidebar:dir(ltr) {
border-right: 1px solid #ddd;
}
.sidebar:dir(rtl) {
border-left: 1px solid #ddd;
}Para navegadores que aún no soportan el selector :dir(), el empaquetador CSS de Bun lo convierte al selector :lang() más ampliamente soportado con mapeos de lenguaje apropiados:
/* Convertido para usar selectores basados en lenguaje 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 conversión te permite escribir CSS consciente de la dirección que funciona confiablemente en todos los navegadores, incluso aquellos que aún no soportan el selector :dir() nativamente. Si múltiples argumentos a :lang() no son soportados, se proporcionan fallbacks adicionales automáticamente.
Selector :lang()
El selector pseudo-clase :lang() te permite apuntar a elementos basado en el idioma en el que están, haciendo fácil aplicar estilizado específico del idioma. El CSS moderno permite al selector :lang() aceptar múltiples códigos de idioma, permitiéndote agrupar reglas específicas del idioma más eficientemente.
/* Ajustes tipográficos para idiomas CJK */
:lang(zh, ja, ko) {
line-height: 1.8;
font-size: 1.05em;
}
/* Diferentes estilos de cita 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 no soportan múltiples argumentos en el selector :lang(), el empaquetador CSS de Bun convierte esta sintaxis para usar el selector :is() para mantener el mismo comportamiento:
/* Múltiples idiomas agrupados con :is() para mejor soporte 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;
}Si es necesario, Bun puede proporcionar fallbacks adicionales para :is() también, asegurando que tus estilos específicos del idioma funcionen en todos los navegadores. Este enfoque simplifica crear diseños internacionalizados con reglas tipográficas y de estilizado distintas para diferentes grupos de idiomas.
Selector :is()
La función pseudo-clase :is() (anteriormente :matches()) te permite crear selectores más concisos y legibles agrupando múltiples selectores juntos. Acepta una lista de selectores como argumento y coincide si cualquiera de los selectores en esa lista coincide, reduciendo significativamente la repetición en tu CSS.
/* En lugar de escribir estos por separado */
/*
.article h1,
.article h2,
.article h3 {
margin-top: 1.5em;
}
*/
/* Puedes escribir esto */
.article :is(h1, h2, h3) {
margin-top: 1.5em;
}
/* Ejemplo complejo con múltiples grupos */
:is(header, main, footer) :is(h1, h2, .title) {
font-family: "Heading Font", sans-serif;
}Para navegadores que no soportan :is(), el empaquetador CSS de Bun proporciona fallbacks usando alternativas con prefijo de proveedor:
/* 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;
}
/* Ejemplo complejo con 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;
}Selector :not()
La pseudo-clase :not() te permite excluir elementos que coinciden con un selector específico. La versión moderna de este selector acepta múltiples argumentos, permitiéndote excluir múltiples patrones con un selector único y conciso.
/* Selecciona todos los botones excepto variantes primary y secondary */
button:not(.primary, .secondary) {
background-color: #f5f5f5;
border: 1px solid #ddd;
}
/* Aplica estilos a todos los encabezados excepto aquellos dentro de sidebars o footers */
h2:not(.sidebar *, footer *) {
margin-top: 2em;
}Para navegadores que no soportan múltiples argumentos en :not(), el empaquetador CSS de Bun convierte esta sintaxis a una forma más compatible mientras preserva el mismo comportamiento:
/* Convertido para usar :not con :is() para compatibilidad */
button:not(:is(.primary, .secondary)) {
background-color: #f5f5f5;
border: 1px solid #ddd;
}
h2:not(:is(.sidebar *, footer *)) {
margin-top: 2em;
}Y si :is() no es soportado, Bun puede generar fallbacks adicionales:
/* Aún más fallbacks para máxima compatibilidad */
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 conversión asegura que tus selectores negativos funcionen correctamente en todos los navegadores mientras mantienes la especificidad y comportamiento correctos del selector original.
Funciones matemáticas
CSS ahora incluye un rico conjunto de funciones matemáticas que te permiten realizar cálculos complejos directamente en tus hojas de estilo. Estas incluyen funciones matemáticas estándar (round(), mod(), rem(), abs(), sign()), funciones trigonométricas (sin(), cos(), tan(), asin(), acos(), atan(), atan2()), y funciones exponenciales (pow(), sqrt(), exp(), log(), hypot()).
.dynamic-sizing {
/* Limita un valor entre mínimo y máximo */
width: clamp(200px, 50%, 800px);
/* Redondea al múltiplo más cercano */
padding: round(14.8px, 5px);
/* Trigonometría para animaciones o diseños */
transform: rotate(calc(sin(45deg) * 50deg));
/* Matemáticas complejas con múltiples funciones */
--scale-factor: pow(1.25, 3);
font-size: calc(16px * var(--scale-factor));
}El empaquetador CSS de Bun evalúa estas expresiones matemáticas en tiempo de construcción cuando todos los valores son constantes conocidas (no variables), resultando en salida optimizada:
.dynamic-sizing {
width: clamp(200px, 50%, 800px);
padding: 15px;
transform: rotate(35.36deg);
--scale-factor: 1.953125;
font-size: calc(16px * var(--scale-factor));
}Este enfoque te permite escribir CSS más expresivo y mantenible con relaciones matemáticas significativas, que luego se compila a valores optimizados para máxima compatibilidad y rendimiento con navegadores.
Rangos de media queries
El CSS moderno soporta sintaxis de rango intuitiva para media queries, permitiéndote especificar puntos de quiebre usando operadores de comparación como <, >, <=, y >= en lugar de los prefijos min- y max- más verbosos. Esta sintaxis es más legible y coincide con cómo normalmente pensamos sobre valores y rangos.
/* Sintaxis moderna con operadores de comparación */
@media (width >= 768px) {
.container {
max-width: 720px;
}
}
/* Rango inclusivo usando <= y >= */
@media (768px <= width <= 1199px) {
.sidebar {
display: flex;
}
}
/* Rango exclusivo usando < y > */
@media (width > 320px) and (width < 768px) {
.mobile-only {
display: block;
}
}El empaquetador CSS de Bun convierte estas consultas de rango modernas a sintaxis de media query tradicional para compatibilidad con todos los navegadores:
/* Convertido a sintaxis 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;
}
}Esto te permite escribir media queries más intuitivas y matemáticas mientras aseguras que tus hojas de estilo funcionen correctamente en todos los navegadores, incluyendo aquellos que no soportan la sintaxis de rango moderna.
Abreviaturas
CSS ha introducido varias propiedades abreviadas modernas que mejoran la legibilidad y mantenibilidad del código. El empaquetador CSS de Bun asegura que estas abreviaturas convenientes funcionen en todos los navegadores convirtiéndolas a sus equivalentes desarrollados cuando es necesario.
/* Abreviaturas de alineación */
.flex-container {
/* Abreviatura para align-items y justify-items */
place-items: center start;
/* Abreviatura para align-content y justify-content */
place-content: space-between center;
}
.grid-item {
/* Abreviatura para align-self y justify-self */
place-self: end center;
}
/* Overflow de dos valores */
.content-box {
/* Primer valor para horizontal, segundo para vertical */
overflow: hidden auto;
}
/* text-decoration mejorado */
.fancy-link {
/* Combina múltiples propiedades de decoración de texto */
text-decoration: underline dotted blue 2px;
}
/* Sintaxis display de dos valores */
.component {
/* Tipo de display externo + tipo de display interno */
display: inline flex;
}Para navegadores que no soportan estas abreviaturas modernas, Bun las convierte a sus propiedades desarrolladas componentes:
.flex-container {
/* Propiedades de alineación expandidas */
align-items: center;
justify-items: start;
align-content: space-between;
justify-content: center;
}
.grid-item {
align-self: end;
justify-self: center;
}
.content-box {
/* Propiedades overflow separadas */
overflow-x: hidden;
overflow-y: auto;
}
.fancy-link {
/* Propiedades de decoración de texto individuales */
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 conversión asegura que tus hojas de estilo permanezcan limpias y mantenibles mientras proporcionas la compatibilidad más amplia posible con navegadores.
Degradados de doble posición
La sintaxis de degradado de doble posición es una característica CSS moderna que te permite crear paradas de color duras en degradados especificando el mismo color en dos posiciones adyacentes. Esto crea una transición aguda en lugar de un desvanecimiento suave, lo cual es útil para crear rayas, bandas de color y otros diseños multicolor.
.striped-background {
/* Crea una transición aguda de verde a rojo en 30%-40% */
background: linear-gradient(
to right,
yellow 0%,
green 20%,
green 30%,
red 30%,
/* Doble posición crea parada dura */ red 70%,
blue 70%,
blue 100%
);
}
.progress-bar {
/* Crea secciones de color distintas */
background: linear-gradient(
to right,
#4caf50 0% 25%,
/* Verde de 0% a 25% */ #ffc107 25% 50%,
/* Amarillo de 25% a 50% */ #2196f3 50% 75%,
/* Azul de 50% a 75% */ #9c27b0 75% 100% /* Púrpura de 75% a 100% */
);
}Para navegadores que no soportan esta sintaxis, el empaquetador CSS de Bun automáticamente la convierte al formato tradicional duplicando paradas de color:
.striped-background {
background: linear-gradient(
to right,
yellow 0%,
green 20%,
green 30%,
red 30%,
/* Dividido en dos paradas de color */ red 70%,
blue 70%,
blue 100%
);
}
.progress-bar {
background: linear-gradient(
to right,
#4caf50 0%,
#4caf50 25%,
/* Dos paradas para sección verde */ #ffc107 25%,
#ffc107 50%,
/* Dos paradas para sección amarilla */ #2196f3 50%,
#2196f3 75%,
/* Dos paradas para sección azul */ #9c27b0 75%,
#9c27b0 100% /* Dos paradas para sección púrpura */
);
}Esta conversión te permite usar la sintaxis de doble posición más limpia en tu código fuente mientras aseguras que los degradados se muestren correctamente en todos los navegadores.
Fuente system-ui
La familia de fuente genérica system-ui te permite usar la fuente UI nativa del dispositivo, creando interfaces que se sienten más integradas con el sistema operativo. Esto proporciona una apariencia y sensación más nativa sin tener que especificar diferentes pilas de fuentes para cada plataforma.
.native-interface {
/* Usa la fuente UI predeterminada del sistema */
font-family: system-ui;
}
.fallback-aware {
/* Fuente UI del sistema con fallbacks explícitos */
font-family: system-ui, sans-serif;
}Para navegadores que no soportan system-ui, el empaquetador CSS de Bun automáticamente lo expande a una pila de fuentes multiplataforma comprehensiva:
.native-interface {
/* Expandido para soportar todas las plataformas principales */
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Noto Sans",
Ubuntu,
Cantarell,
"Helvetica Neue";
}
.fallback-aware {
/* Preserva el fallback original después de la pila expandida */
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Noto Sans",
Ubuntu,
Cantarell,
"Helvetica Neue",
sans-serif;
}Este enfoque te da la simplicidad de escribir solo system-ui en tu código fuente mientras aseguras que tu interfaz se adapte correctamente a todos los sistemas operativos y navegadores. La pila de fuentes expandida incluye fuentes de sistema apropiadas para macOS/iOS, Windows, Android, Linux, y fallbacks para navegadores antiguos.
Módulos CSS
El empaquetador de Bun también soporta empaquetar módulos CSS además de CSS regular con soporte para las siguientes características:
- Detección automática de archivos de módulo CSS (
.module.css) con cero configuración - Composición (propiedad
composes) - Importar módulos CSS en JSX/TSX
- Advertencias/errores para usos inválidos de módulos CSS
Un módulo CSS es un archivo CSS (con la extensión .module.css) donde todos los nombres de clase y animaciones están limitados al archivo. Esto te ayuda a evitar colisiones de nombres de clase ya que las declaraciones CSS están limitadas globalmente por defecto.
Bajo el capó, el empaquetador de Bun transforma nombres de clase limitados localmente en identificadores únicos.
Primeros pasos
Crea un archivo CSS con la extensión .module.css:
.button {
color: red;
}.button {
color: blue;
}Luego puedes importar este archivo, por ejemplo en un archivo TSX:
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";
export default function App() {
return (
<>
<button className={styles.button}>¡Botón rojo!</button>
<button className={otherStyles.button}>¡Botón azul!</button>
</>
);
}El objeto styles de importar el archivo de módulo CSS será un objeto con todos los nombres de clase como claves y sus identificadores únicos como valores:
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";
console.log(styles);
console.log(otherStyles);Esto mostrará:
{
button: "button_123";
}
{
button: "button_456";
}¡Como puedes ver, los nombres de clase son únicos para cada archivo, evitando cualquier colisión!
Composición
Los módulos CSS te permiten componer selectores de clase juntos. Esto te permite reusar reglas de estilo en múltiples clases.
Por ejemplo:
.button {
composes: background;
color: red;
}
.background {
background-color: blue;
}Sería lo mismo que escribir:
.button {
background-color: blue;
color: red;
}
.background {
background-color: blue;
}Hay un par de reglas a tener en mente al usar composes:
#button {
/* ¡Inválido! `#button` no es un selector de clase */
composes: background;
}
.button,
.button-secondary {
/* ¡Inválido! `.button, .button-secondary` no es un selector simple */
composes: background;
}Componer desde un archivo de módulo CSS separado
También puedes componer desde un archivo de módulo CSS separado:
.background {
background-color: blue;
}.button {
composes: background from "./background.module.css";
color: red;
}