docs/developer/admin/custom-css.mdx
Spree Admin Dashboard uses Tailwind CSS v4 for styling. The stylesheet system is designed to be easily customizable while maintaining consistency with the Spree design system.
When you install Spree Admin, the installer creates a file at app/assets/tailwind/spree_admin.css in your application. This file:
You can use any Tailwind CSS utility class in your custom admin views, helpers, or JavaScript files. The build process automatically scans these locations:
app/views/spree/admin/**/*.erbapp/helpers/spree/admin/**/*.rbapp/javascript/spree/admin/**/*.jsExample usage in a view:
<div class="bg-zinc-100 p-4 rounded-lg shadow-sm">
<h2 class="text-lg font-bold text-zinc-900">Custom Section</h2>
<p class="text-sm text-zinc-600 mt-2">Your content here</p>
</div>
To override Tailwind theme values, add a @theme block in your app/assets/tailwind/spree_admin.css file after the import:
/* Import Spree Admin base styles from the gem */
@import "$SPREE_ADMIN_PATH/app/assets/tailwind/spree/admin/index.css";
/* Override theme colors */
@theme {
--color-primary: #4F46E5; /* Change primary color to indigo */
--color-success: #059669; /* Custom success color */
--color-danger: #DC2626; /* Custom danger color */
}
The Spree Admin theme defines these customizable variables:
| Variable | Default | Description |
|---|---|---|
--color-primary | var(--color-zinc-950) | Primary brand color |
--color-success | var(--color-green-900) | Success state color |
--color-danger | var(--color-red-600) | Error/danger state color |
--color-warning | var(--color-yellow-900) | Warning state color |
--color-info | var(--color-blue-900) | Info state color |
You can also customize layout-related CSS variables:
:root {
--spacing-sidebar-width: 280px; /* Default: 220px */
--spacing-sidebar-collapsed: 70px; /* Default: 59px */
--spacing-header-height: 64px; /* Default: 58px */
}
Use Tailwind's @layer directive to add custom component styles that work seamlessly with the existing design:
@layer components {
/* Custom card style */
.my-custom-card {
@apply bg-white rounded-lg shadow-sm border border-zinc-200 p-4;
}
/* Custom button variant */
.btn-custom {
@apply inline-flex items-center px-4 py-2 rounded-md;
@apply bg-indigo-600 text-white font-medium;
@apply hover:bg-indigo-700 transition-colors;
}
/* Custom status badge */
.status-badge {
@apply inline-flex items-center px-2 py-1 rounded-full text-xs font-medium;
}
.status-badge-active {
@apply status-badge bg-green-100 text-green-800;
}
.status-badge-inactive {
@apply status-badge bg-zinc-100 text-zinc-600;
}
}
For reusable utility classes, use the utilities layer:
@layer utilities {
.text-gradient {
@apply bg-clip-text text-transparent bg-gradient-to-r from-indigo-500 to-purple-500;
}
.scrollbar-hidden {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hidden::-webkit-scrollbar {
display: none;
}
}
If you have admin-related code in non-standard locations, add additional @source directives:
/* Scan host app's custom admin code for Tailwind classes */
@source "../../views/spree/admin/**/*.erb";
@source "../../helpers/spree/admin/**/*.rb";
@source "../../javascript/spree/admin/**/*.js";
/* Add your custom paths */
@source "../../components/admin/**/*.erb";
@source "../../views/admin/**/*.erb";
During development, run the Tailwind CSS watcher to automatically rebuild styles when you make changes:
bin/rails spree:admin:tailwindcss:watch
Or if you're using Procfile.dev with foreman:
bin/dev
The watcher monitors:
app/assets/tailwind/@source patternsCSS is automatically compiled during asset precompilation:
bin/rails assets:precompile
@theme {
/* Use blue as the primary color */
--color-primary: #2563EB;
}
@layer components {
/* Ensure buttons use the new primary color */
.btn-primary {
@apply bg-blue-600 hover:bg-blue-700;
}
}
@layer base {
/* Custom dark mode overrides */
.dark {
--color-primary: #60A5FA;
}
}
@layer components {
/* Custom input style */
.input-custom {
@apply block w-full rounded-md border-zinc-300 shadow-sm;
@apply focus:border-indigo-500 focus:ring-indigo-500;
}
/* Custom select style */
.select-custom {
@apply block w-full rounded-md border-zinc-300 py-2 pl-3 pr-10;
@apply focus:border-indigo-500 focus:outline-none focus:ring-indigo-500;
}
}
bin/rails spree:admin:tailwindcss:watch@source directivesIf a Tailwind class isn't working, ensure:
@sourcebin/rails spree:admin:tailwindcss:buildThe watch task requires the listen gem. Add it to your Gemfile:
group :development do
gem 'listen', '>= 3.0'
end