Adding custom styles
Overview
Section titled “Overview”In Tailwind CSS, you extend the framework with custom CSS using @layer, @apply, and @theme. In Flutter with Style, customization works differently because there’s no CSS build step.
Arbitrary values
Section titled “Arbitrary values”The most common way to add custom styles is using arbitrary values — square bracket notation that lets you use any value:
// Custom colorsStyle('bg-[#316ff6]', child: ...)Style('text-[rgb(255,0,128)]', child: ...)
// Custom sizesStyle('w-[200px]', child: ...)Style('h-[calc(100vh-80px)]', child: ...)
// Custom spacingStyle('p-[13px]', child: ...)Style('mt-[7px]', child: ...)This is the Flutter equivalent of Tailwind’s arbitrary value syntax — it works identically.
Combining Style with Flutter widgets
Section titled “Combining Style with Flutter widgets”When you need something Style doesn’t cover, compose with native Flutter widgets:
// Style handles layout and visual stylingStyle( 'rounded-xl bg-white p-6 shadow-lg', child: Column( children: [ // Native Flutter widget for complex behavior TextField( decoration: InputDecoration(hintText: 'Search...'), ), // Style handles the visual treatment Style( 'mt-4 text-sm text-gray-500', child: Text('Type to search'), ), ], ),)Extracting reusable components
Section titled “Extracting reusable components”In Tailwind CSS, @layer components lets you define reusable class combinations. In Flutter, you extract reusable widgets:
// Instead of @layer components { .btn-primary { ... } }// Create a reusable widget:
class PrimaryButton extends StatelessWidget { const PrimaryButton({required this.label, this.onPressed, super.key});
final String label; final VoidCallback? onPressed;
@override Widget build(BuildContext context) { return GestureDetector( onTap: onPressed, child: Style( 'bg-violet-500 hover:bg-violet-700 text-white font-semibold py-2 px-5 rounded-full shadow-md', child: Text(label), ), ); }}
// Usage:PrimaryButton(label: 'Save changes', onPressed: () { ... })This is more powerful than CSS components because you get:
- Type-safe parameters
- Conditional logic
- State management
- Full Flutter widget lifecycle
Custom design tokens
Section titled “Custom design tokens”For systematic customization beyond arbitrary values, use StyleTheme to override design tokens for an entire widget subtree:
StyleTheme( data: StyleThemeData( colors: {'brand': {500: Color(0xFF316FF6)}}, spacing: {'4': 20}, ), child: Style( 'bg-brand-500 p-4 rounded-lg text-white', child: Text('Brand themed'), ),)See Custom themes for full API reference.
Custom variants
Section titled “Custom variants”Define context-aware variants with StyleVariants:
StyleVariants( variants: { 'compact': (context) => MediaQuery.sizeOf(context).width < 500, }, child: Style( 'py-4 px-8 compact:py-2 compact:px-4', child: Text('Adaptive'), ),)See Custom variants for more examples.
Feature mapping
Section titled “Feature mapping”| Tailwind CSS | Style equivalent |
|---|---|
@theme custom tokens | StyleTheme widget with StyleThemeData |
@layer components | Flutter widget extraction |
@apply | Direct Style('...') composition |
@custom-variant | StyleVariants widget |
| Plugins | Not yet supported |