Estilos en NextJS 16

NextJS soporta varios metodos de styling. Esta guia cubre los mas comunes: Tailwind CSS (recomendado), CSS Modules y CSS global.

Tailwind CSS

create-next-app incluye Tailwind por defecto. Escribes clases directamente en tus componentes:

tsx
export default function Card({ title, description }: {
  title: string
  description: string
}) {
  return (
    <div className="bg-gray-800 border border-gray-700 rounded-lg p-6 hover:border-blue-500 transition-colors">
      <h3 className="text-xl font-semibold text-white mb-2">{title}</h3>
      <p className="text-gray-400 text-sm leading-relaxed">{description}</p>
    </div>
  )
}

Variantes con clases condicionales

tsx
function Badge({ status }: { status: "activo" | "inactivo" | "pendiente" }) {
  const styles = {
    activo: "bg-green-500/10 text-green-400 border-green-500/30",
    inactivo: "bg-red-500/10 text-red-400 border-red-500/30",
    pendiente: "bg-yellow-500/10 text-yellow-400 border-yellow-500/30",
  }

  return (
    <span className={`text-xs font-medium px-2 py-1 rounded border ${styles[status]}`}>
      {status}
    </span>
  )
}

Responsive

tsx
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  {productos.map((p) => (
    <ProductCard key={p.id} producto={p} />
  ))}
</div>
  • grid-cols-1 → 1 columna en mobile
  • md:grid-cols-2 → 2 columnas desde 768px
  • lg:grid-cols-3 → 3 columnas desde 1024px

CSS Modules

Si prefieres CSS puro con scope local:

css
/* app/components/Button.module.css */
.button {
  background-color: #2563eb;
  color: white;
  padding: 0.5rem 1.5rem;
  border-radius: 0.5rem;
  font-weight: 600;
  transition: background-color 0.2s;
}

.button:hover {
  background-color: #1d4ed8;
}

.secondary {
  background-color: transparent;
  border: 1px solid #374151;
  color: #9ca3af;
}

.secondary:hover {
  border-color: #2563eb;
  color: white;
}
tsx
// app/components/Button.tsx
import styles from "./Button.module.css"

interface ButtonProps {
  variant?: "primary" | "secondary"
  children: React.ReactNode
}

export default function Button({ variant = "primary", children }: ButtonProps) {
  const className = variant === "secondary"
    ? `${styles.button} ${styles.secondary}`
    : styles.button

  return <button className={className}>{children}</button>
}

Las clases se renombran automaticamente para evitar conflictos (ej. Button_button_a1b2c).

CSS Global

Estilos que aplican a toda la app van en app/globals.css:

css
/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Estilos globales custom */
body {
  background-color: #0a0a0a;
  color: #ededed;
}

::selection {
  background-color: #2563eb;
  color: white;
}

/* Scrollbar custom (Webkit) */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-thumb {
  background-color: #374151;
  border-radius: 4px;
}

Se importa una sola vez en app/layout.tsx:

tsx
import "./globals.css"

CSS-in-JS

Librerias como styled-components o Emotion no funcionan en Server Components. Solo puedes usarlas en Client Components ("use client").

Si ya tienes un proyecto con CSS-in-JS, funciona pero tiene limitaciones:

tsx
"use client" // Obligatorio para CSS-in-JS

import styled from "styled-components"

const StyledButton = styled.button`
  background: #2563eb;
  color: white;
  padding: 0.5rem 1.5rem;
  border-radius: 0.5rem;
`

export default function MyButton() {
  return <StyledButton>Click</StyledButton>
}
Recomendacion

Para proyectos nuevos, usa Tailwind CSS. Es el mas compatible con Server Components, tiene cero runtime JavaScript y funciona perfecto con NextJS 16.

Ejemplo: componente card con variantes

tsx
// components/Card.tsx
interface CardProps {
  variant?: "default" | "outlined" | "elevated"
  children: React.ReactNode
}

const variantStyles = {
  default: "bg-gray-800 border-gray-700",
  outlined: "bg-transparent border-gray-600",
  elevated: "bg-gray-800 border-gray-700 shadow-lg shadow-black/20",
}

export default function Card({ variant = "default", children }: CardProps) {
  return (
    <div className={`border rounded-lg p-6 ${variantStyles[variant]}`}>
      {children}
    </div>
  )
}
tsx
// Uso
<Card>Contenido default</Card>
<Card variant="outlined">Con borde</Card>
<Card variant="elevated">Con sombra</Card>