Utilidades CSS para JavaFX al estilo Tailwind

Un sistema de clases utilitarias CSS inspirado en Tailwind que puedes usar directamente en tus proyectos JavaFX para estilizar componentes con padding, colores, tipografía, botones y más sin escribir CSS personalizado.

J

JavaFX Master

3 de marzo de 2025 12 min de lectura

Utilidades CSS para JavaFX al estilo Tailwind

Si vienes del mundo web probablemente conoces Tailwind CSS — un framework de utilidades que te permite estilizar elementos directamente con clases como p-4, text-lg o bg-primary. ¿Y si pudieras hacer lo mismo en JavaFX?

En este artículo te presentamos un archivo CSS de utilidades inspirado en Tailwind, diseñado específicamente para JavaFX. En lugar de escribir estilos manuales para cada componente, simplemente agregas clases utilitarias.

Descarga el Archivo Completo

El archivo contiene más de 400 líneas de utilidades listas para usar, incluyendo variables, paleta de colores, botones, badges y soporte para modo oscuro.

Descargar javafx-utilities.css

Cómo Usarlo

  1. Descarga el archivo javafx-utilities.css
  2. Colócalo en src/main/resources/css/ de tu proyecto
  3. Cárgalo en tu aplicación:
scene.getStylesheets().add(
    getClass().getResource("/css/javafx-utilities.css").toExternalForm()
);
  1. Aplica las clases directamente en tu código Java:
Label titulo = new Label("Hola Mundo");
titulo.getStyleClass().addAll("text-2xl", "font-bold", "text-primary");

VBox contenedor = new VBox(titulo);
contenedor.getStyleClass().addAll("p-4", "gap-4", "bg-white", "rounded-lg");

O en tus archivos FXML:

<VBox styleClass="p-4, gap-4, bg-white, rounded-lg">
    <Label text="Hola Mundo" styleClass="text-2xl, font-bold, text-primary"/>
</VBox>

Paleta de Colores

El sistema incluye una paleta completa con 6 familias de colores, cada una con múltiples tonalidades definidas como variables CSS de JavaFX:

ColorVariable BaseHexUso
Primary-color-primary-600#2563ebAcciones principales
Success-color-success-600#059669Éxito, confirmación
Danger-color-danger-600#dc2626Error, eliminación
Warning-color-warning-600#d97706Advertencias
Info-color-info-600#7c3aedInformación
Slate-color-slate-600#475569Texto neutral

Cada familia tiene tonalidades desde 50 (muy claro) hasta 900 (muy oscuro):

.root {
    /* Blue (Primary) */
    -color-primary-50: #eff6ff;
    -color-primary-100: #dbeafe;
    -color-primary-200: #bfdbfe;
    -color-primary-300: #60a5fa;
    -color-primary-500: #3b82f6;
    -color-primary-600: #2563eb;
    -color-primary-700: #1d4ed8;

    /* Slate (Neutral) */
    -color-slate-50: #f8fafc;
    -color-slate-100: #f1f5f9;
    -color-slate-200: #e2e8f0;
    -color-slate-300: #cbd5e1;
    -color-slate-400: #94a3b8;
    -color-slate-500: #64748b;
    -color-slate-600: #475569;
    -color-slate-700: #334155;
    -color-slate-800: #1e293b;
    -color-slate-900: #0f172a;
}

Espaciado (Padding y Gap)

Padding

ClaseValorDescripción
.p-00Sin padding
.p-14pxExtra pequeño
.p-28pxPequeño
.p-312pxMedio
.p-416pxNormal
.p-524pxGrande
.p-632pxExtra grande
.p-848pxMáximo

También disponibles .px-* (horizontal) y .py-* (vertical):

/* Padding uniforme */
.p-4 {
    -fx-padding: 16px;
}

/* Padding horizontal (izquierda/derecha) */
.px-4 {
    -fx-padding: 0 16px;
}

/* Padding vertical (arriba/abajo) */
.py-4 {
    -fx-padding: 16px 0;
}

Gap (Espaciado entre hijos)

Para VBox y HBox, usa .gap-* que controla -fx-spacing:

.gap-2 {
    -fx-spacing: 8px;
}
.gap-4 {
    -fx-spacing: 16px;
}
.gap-6 {
    -fx-spacing: 24px;
}

Ejemplo práctico:

VBox sidebar = new VBox();
sidebar.getStyleClass().addAll("p-4", "gap-4");
// Resultado: padding de 16px y 16px entre cada hijo

Tamaños (Width y Height)

/* Width */
.w-full {
    -fx-pref-width: 100%;
    -fx-max-width: Infinity;
}
.w-75 {
    -fx-pref-width: 75%;
}
.w-50 {
    -fx-pref-width: 50%;
}
.w-25 {
    -fx-pref-width: 25%;
}

/* Max Width */
.max-w-sm {
    -fx-max-width: 384px;
}
.max-w-md {
    -fx-max-width: 448px;
}
.max-w-lg {
    -fx-max-width: 512px;
}
.max-w-xl {
    -fx-max-width: 576px;
}

/* Height */
.h-full {
    -fx-pref-height: 100%;
    -fx-max-height: Infinity;
}

Tipografía

Tamaños de Texto

ClaseTamañoUso típico
.text-xs11pxEtiquetas menores
.text-sm13pxTexto secundario
.text-base14pxTexto normal
.text-lg16pxSubtítulos
.text-xl20pxTítulos
.text-2xl24pxEncabezados
.text-3xl30pxTítulos grandes

Peso y Estilo

.font-bold {
    -fx-font-weight: bold;
}
.font-semibold {
    -fx-font-weight: 600;
}
.font-normal {
    -fx-font-weight: normal;
}
.font-italic {
    -fx-font-style: italic;
}

Alineación

.text-center {
    -fx-alignment: center;
    -fx-text-alignment: center;
}
.text-left {
    -fx-alignment: center-left;
    -fx-text-alignment: left;
}
.text-right {
    -fx-alignment: center-right;
    -fx-text-alignment: right;
}

Ejemplo completo:

Label titulo = new Label("Dashboard");
titulo.getStyleClass().addAll("text-3xl", "font-bold");

Label subtitulo = new Label("Resumen del sistema");
subtitulo.getStyleClass().addAll("text-sm", "text-slate-500");

Colores de Texto y Fondo

Texto

label.getStyleClass().add("text-primary");   // Azul
label.getStyleClass().add("text-success");   // Verde
label.getStyleClass().add("text-danger");    // Rojo
label.getStyleClass().add("text-warning");   // Naranja
label.getStyleClass().add("text-info");      // Violeta
label.getStyleClass().add("text-slate-500"); // Gris medio

Fondos

panel.getStyleClass().add("bg-white");       // Blanco
panel.getStyleClass().add("bg-slate-50");    // Gris muy claro
panel.getStyleClass().add("bg-primary");     // Azul primario
panel.getStyleClass().add("bg-danger-50");   // Rojo suave de fondo

Bordes y Redondeo

Bordes

.border {
    -fx-border-color: ...;
    -fx-border-width: 1px;
}
.border-b {
    -fx-border-width: 0 0 1px 0;
} /* Solo borde inferior */
.border-primary {
    -fx-border-color: -color-primary-500;
}
.border-danger {
    -fx-border-color: -color-danger-500;
}

Border Radius

ClaseRadioResultado
.rounded-none0Sin redondeo
.rounded-sm2pxSutil
.rounded4pxNormal
.rounded-md6pxMedio
.rounded-lg8pxGrande
.rounded-xl12pxExtra grande
.rounded-full9999pxCompletamente redondo

Ejemplo de tarjeta:

VBox card = new VBox();
card.getStyleClass().addAll(
    "bg-white", "rounded-lg", "border", "p-4", "gap-3"
);

Botones

El sistema incluye botones listos para usar con variantes sólidas, light, outline y dashed:

Button guardar = new Button("Guardar");
guardar.getStyleClass().addAll("btn", "btn-primary");

Button eliminar = new Button("Eliminar");
eliminar.getStyleClass().addAll("btn", "btn-danger");

Button cancelar = new Button("Cancelar");
cancelar.getStyleClass().addAll("btn", "btn-secondary");

Button especial = new Button("Info");
especial.getStyleClass().addAll("btn", "btn-light-primary");

Variantes disponibles:

ClaseEstilo
.btn-primaryAzul sólido
.btn-successVerde sólido
.btn-dangerRojo sólido
.btn-warningNaranja sólido
.btn-infoVioleta sólido
.btn-darkNegro sólido
.btn-secondaryGris suave
.btn-light-primaryAzul claro con texto azul
.btn-outline-primaryBorde azul, fondo transparente
.btn-dashedBorde punteado

Tamaños: .btn-sm (pequeño) y .btn-lg (grande).

Badges

Etiquetas pequeñas para estados o categorías:

Label badge = new Label("Nuevo");
badge.getStyleClass().addAll("badge", "badge-primary");

Label badgeEstado = new Label("Activo");
badgeEstado.getStyleClass().addAll("badge", "badge-light-success");

Layout y Alineación

/* Alineamiento para contenedores (VBox, HBox, StackPane) */
.items-center {
    -fx-alignment: center;
}
.items-top-center {
    -fx-alignment: top-center;
}
.items-top-left {
    -fx-alignment: top-left;
}
.items-center-left {
    -fx-alignment: center-left;
}
.items-center-right {
    -fx-alignment: center-right;
}

Ejemplo:

HBox toolbar = new HBox();
toolbar.getStyleClass().addAll("items-center", "gap-3", "px-4", "py-2", "bg-white", "border-b");

Modo Oscuro

El archivo incluye un bloque .root.dark que redefine los tokens semánticos. Para activarlo:

// Activar modo oscuro
scene.getRoot().getStyleClass().add("dark");

// Desactivar modo oscuro
scene.getRoot().getStyleClass().remove("dark");

Los tokens que cambian automáticamente son:

.root.dark {
    -color-bg-body: -color-slate-900; /* Fondo general */
    -color-bg-surface: -color-slate-800; /* Tarjetas */
    -color-text-primary: -color-slate-100; /* Texto principal */
    -color-text-secondary: -color-slate-400; /* Texto secundario */
    -color-border-default: -color-slate-700; /* Bordes */
}

Tip: Si usas tokens semánticos como -color-bg-surface en lugar de colores hardcodeados, el modo oscuro funciona automáticamente sin cambiar tu código.

Ejemplo Completo: Formulario Estilizado

// Título
Label titulo = new Label("Crear Cuenta");
titulo.getStyleClass().addAll("text-2xl", "font-bold");

Label subtitulo = new Label("Ingresa tus datos para registrarte");
subtitulo.getStyleClass().addAll("text-sm", "text-slate-500");

// Campos
TextField nombre = new TextField();
nombre.setPromptText("Nombre completo");
nombre.getStyleClass().addAll("rounded-md");

TextField email = new TextField();
email.setPromptText("Email");
email.getStyleClass().addAll("rounded-md");

// Botones
Button registrar = new Button("Registrarse");
registrar.getStyleClass().addAll("btn", "btn-primary", "w-full");

Button google = new Button("Continuar con Google");
google.getStyleClass().addAll("btn", "btn-outline-primary", "w-full");

// Layout
VBox form = new VBox();
form.getStyleClass().addAll(
    "bg-white", "rounded-xl", "p-6", "gap-4",
    "border", "max-w-sm"
);
form.getChildren().addAll(titulo, subtitulo, nombre, email, registrar, google);

Siguiente Paso

Con estas utilidades ya puedes estilizar rápidamente cualquier componente JavaFX. En el próximo artículo veremos cómo crear componentes avanzados como tablas, barras de navegación y tarjetas estadísticas usando estas mismas clases.

forumComentarios

Deja tu comentario

progress_activityCargando comentarios...