dacs 0.6.0 copy "dacs: ^0.6.0" to clipboard
dacs: ^0.6.0 copied to clipboard

Tailwind-like utility classes for Flutter. Apply text styles, padding, margins, colors, and borders via concise string expressions.

DACS #

pub.dev license

DACS brings Tailwind-inspired utility classes to Flutter. Write concise string expressions to define text styles, padding, colors, borders, shadows, transforms, gradients, and more.

Text('Hello, World!', style: 'text-2xl font-medium text-sky-500'.dText)

Features #

  • Zero-config — just install and use

  • Tailwind v3 color palette — 22 colors × 11 shades

  • Spacing scale — 0 to 384px in Tailwind increments

  • Text utilities — size, weight, color, letter spacing, line height, decoration

  • Background & border — colors, border width, border radius with directional variants

  • Sizing, shadows & opacity — width, height, box shadows, opacity

  • Position — inset-, top-, right-, bottom-, left-, start-, end-*

  • Transform — scale, rotate, translate, skew

  • Gradient — linear gradients from Tailwind color tokens

  • Theme colors from ColorSchemetext-primary, bg-surface, border-error

  • Arbitrary valuestext-[#ff0000], p-[20], w-[50%], rounded-[12]

  • Material widget extensions — style any Material widget: .dButton(context), .dCheckbox(context), .dCard(context), etc.

  • WidgetState variantshover:, focus:, disabled:, pressed:, selected:, error:, dragged:, scrolledUnder:

  • Chained compound variants — combine any prefixes: dark:hover:, dark:md:focus:, light:lg:disabled:

  • Dark/Light, accessibility & responsive variantsdark:, light:, high-contrast:, motion-reduce:, sm:, md:, etc.

  • Material 3 theme coverage — includes buttons, inputs, menus, navigation, drawers, badges, sliders, date pickers, and time pickers

  • Semantic design tokens — configure bg-brand-primary, p-content, rounded-card, shadow-floating, font-brand, text-body, and aliases like type-hero

  • Static validation — run dart run dacs:dacs analyze to catch invalid utility strings before UI execution

Documentation #

Installation #

dependencies:
  dacs: ^0.6.0

Usage #

Configuration and compilation #

DACS works without configuration, but you can enable diagnostics for unknown utilities and tune the parser cache:

Dacs.configure(
  strictMode: false,
  cacheSize: 500,
  onUnknownUtility: (utility) {
    debugPrint('Unknown DACS utility: $utility');
  },
  onDiagnostic: (diagnostic) {
    debugPrint('${diagnostic.code}: ${diagnostic.utility}');
  },
  config: const {
    'policy': {
      'arbitraryValues': 'allow', // allow | warn | reject
      'failFast': false,
    },
    'theme': {
      'extend': {
        'colors': {
          'brand-primary': {
            'DEFAULT': '#0057B8',
            'dark': '#8AB4F8',
          },
          'brand-muted': {
            'DEFAULT': '#6B7280',
            'dark': '#CBD5E1',
          },
        },
        'spacing': {'content': '24'},
        'borderRadius': {'card': '16'},
        'boxShadow': {
          'floating': '0 8 24 rgba(0, 0, 0, 0.18)',
        },
        'screens': {
          'compact': '0',
          'medium': '600',
          'expanded': '840',
        },
        'fontFamily': {
          'brand': 'Inter, Roboto, Arial, sans-serif',
        },
        'fontSize': {
          'body': [
            '16',
            {'lineHeight': '24', 'letterSpacing': '0'},
          ],
        },
        'transitionDuration': {
          'standard': '200ms',
          'short': '100ms',
        },
        'transitionTimingFunction': {
          'standard': 'cubic-bezier(0.2, 0, 0, 1)',
        },
        'motion': {
          'standard': 'duration-standard ease-standard',
          'fade-short': 'duration-short ease-out',
        },
        'typography': {
          'hero': 'font-brand text-2xl font-bold text-brand-primary',
          'body': 'font-brand text-body text-brand-muted',
        },
      },
    },
  },
);

final sheet = DacsCompiler.compile('text-sm dark:md:hover:bg-red-500');

Static validation #

Use the CLI to validate constant DACS strings in Dart files before the UI path is executed:

dart run dacs:dacs analyze lib test

It reports unknown utilities, malformed arbitrary values, rejected arbitrary values, and utilities that are valid but not consumed by a specific adapter such as .dText or .dPads. Add --format json for editor/CI integrations and --fatal-warnings when warnings should fail CI.

For custom tokens and policies, create a dacs.config.dart with a const dacsConfig map using the same string-first shape accepted by Dacs.configure(config: ...).

Compilation is context-free: DacsCompiler.compile only parses the string into a DacsStyleSheet. Runtime values such as BuildContext, theme colors, brightness, breakpoints, and widget states are applied later by methods such as .dTextOf(context), .dBoxOf(context), and .dButton(context).

The config object is deliberately Tailwind-like: use plain Map, List, String, bool, and num values. DACS converts those strings to Flutter objects internally.

Text styles #

Text('Heading', style: 'text-3xl font-bold text-gray-900'.dText)
Text('Body', style: 'text-base leading-relaxed text-gray-600'.dText)

Padding & Margin #

Container(
  padding: 'px-4 py-2'.dPads,
  margin: 'mt-4'.dPads,
  child: Text('Content', style: 'text-base'.dText),
)

For direction-aware UI, use logical spacing:

Container(
  padding: 'ps-4 pe-2 py-3'.dPadsGeometry,
  child: Text('RTL-aware spacing'),
)

Box decoration #

Container(
  decoration: 'bg-blue-500 rounded-lg shadow-md'.dBox,
  child: Text('Button', style: 'text-white font-medium'.dText),
)

Gradients #

Container(
  decoration: 'bg-gradient-to-r from-sky-400 to-blue-600'.dBox,
  child: Text('Gradient', style: 'text-white text-xl'.dText),
)

Shadows #

Container(decoration: 'bg-white rounded-xl shadow-lg'.dBox)
// Or just the shadow list:
final shadows = 'shadow-lg'.dShadow;

Sizing #

final (width, height) = 'w-64 h-48'.dSize;

Position (for Stack) #

final (top, right, bottom, left) = 'inset-0'.dPosition;
final logical = 'top-2 start-4 end-2'.dPositionDirectional;

Transform #

Transform(
  transform: 'scale-125 rotate-45'.dTransform,
  child: Text('Styled'),
)

Dark / Light mode variants #

// Resolves automatically from the active Flutter Theme:
Text(
  'Responsive text',
  style: 'text-gray-900 dark:text-white'.dTextOf(context),
)

Container(
  decoration: 'bg-white dark:bg-gray-900'.dBoxOf(context),
  child: Text(
    'Content',
    style: 'text-base text-gray-600 dark:text-gray-300'.dTextOf(context),
  ),
)

Responsive variants #

// Applies breakpoints based on screen width from MediaQuery:
Text(
  'Responsive heading',
  style: 'text-base sm:text-lg md:text-xl lg:text-2xl'.dTextOf(context),
)

Container(
  padding: 'p-4 md:p-8 lg:p-12'.dPadsOf(context),
  decoration: 'bg-white dark:bg-gray-900 rounded-lg'.dBoxOf(context),
  child: Text(
    'Content',
    style: 'text-sm md:text-base'.dTextOf(context),
  ),
)

Configure custom breakpoints through theme.screens or theme.extend.screens:

Dacs.configure(
  config: const {
    'theme': {
      'extend': {
        'screens': {
          'medium': '600',
          'expanded': '840',
        },
      },
    },
  },
);

Text(
  'Responsive heading',
  style: 'text-base medium:text-xl expanded:text-2xl'.dTextOf(context),
)

theme.screens replaces the default sm/md/lg/xl/2xl set. theme.extend.screens keeps the defaults and adds or overrides individual names.

Accessibility variants #

DACS can resolve high-contrast and motion preferences from MediaQuery through context-aware APIs:

Container(
  decoration:
      'border-gray-300 high-contrast:border-black'.dBoxOf(context),
)

ElevatedButton(
  style: 'motion-standard motion-reduce:motion-none'.dButton(context),
  onPressed: () {},
  child: const Text('Motion-aware'),
)

Supported accessibility prefixes:

  • high-contrast: when MediaQueryData.highContrast is true.
  • normal-contrast: when high contrast is false.
  • motion-safe: when no reduced-motion preference is active.
  • motion-reduce: when motion is reduced or disabled.
  • motion-disabled: only when animations are disabled.

Use DacsResolveContext(motionPreference: DacsMotionPreference.reduce) when an integration can distinguish reduced motion from disabled animations. Flutter's default MediaQueryData.disableAnimations maps to motion-disabled:.

Theme colors #

Use any ColorScheme key as a color — no need to import or reference the theme directly:

Text('Primary', style: 'text-primary font-bold'.dTextOf(context))
Container(decoration: 'bg-surface rounded-lg border-outline'.dBoxOf(context))
CheckboxTheme(
  data: 'checked:bg-primary unchecked:bg-surface'.dCheckbox(context),
  child: Checkbox(value: true, onChanged: (_) {}),
)

Supported keys: primary, onPrimary, primaryContainer, onPrimaryContainer, secondary, onSecondary, secondaryContainer, onSecondaryContainer, tertiary, onTertiary, tertiaryContainer, onTertiaryContainer, error, onError, errorContainer, onErrorContainer, surface, onSurface, surfaceVariant, onSurfaceVariant, outline, outlineVariant, inverseSurface, onInverseSurface, inversePrimary, shadow, scrim

Semantic tokens #

Register app-specific names in Dacs.configure(config: ...) and use them as normal utility strings:

Dacs.configure(
  config: const {
    'theme': {
      'extend': {
        'colors': {
          'brand-primary': {
            'DEFAULT': '#0057B8',
            'dark': '#8AB4F8',
          },
          'brand-surface': {
            'DEFAULT': '#F3F7FC',
            'dark': '#111827',
          },
          'brand-muted': {
            'DEFAULT': '#6B7280',
            'dark': '#CBD5E1',
          },
        },
        'spacing': {'content': '24'},
        'borderRadius': {'card': '16'},
        'boxShadow': {'floating': '0 8 24 rgba(0, 0, 0, 0.18)'},
        'screens': {'medium': '600', 'expanded': '840'},
        'fontFamily': {
          'brand': 'Inter, Roboto, Arial, sans-serif',
        },
        'fontSize': {
          'body': [
            '16',
            {'lineHeight': '24'},
          ],
        },
        'transitionDuration': {
          'standard': '200ms',
          'short': '100ms',
        },
        'transitionTimingFunction': {
          'standard': 'cubic-bezier(0.2, 0, 0, 1)',
        },
        'motion': {
          'standard': 'duration-standard ease-standard',
          'fade-short': 'duration-short ease-out',
        },
        'typography': {
          'hero': 'font-brand text-2xl font-bold text-brand-primary',
          'body': 'font-brand text-body text-brand-muted',
        },
      },
    },
  },
);

Container(
  padding: 'p-content'.dPads,
  decoration: 'bg-brand-surface rounded-card shadow-floating'.dBoxOf(context),
  child: Text('Brand', style: 'type-hero'.dTextOf(context)),
)

Use theme.extend to add or override individual names while keeping DACS defaults. Use theme.colors, theme.spacing, theme.borderRadius, or theme.boxShadow, theme.screens, theme.fontFamily, or theme.fontSize to replace that whole section.

Configured typography remains string-first:

'font-brand text-body'
'type-body'
'motion-standard'

fontFamily values may be a comma-separated string, a list, or a map with a package field. DACS applies them to Flutter's TextStyle.fontFamily, fontFamilyFallback, and package.

DACS does not bundle, install, download, or preload fonts. The app remains responsible for making each configured family available to Flutter:

  • declare local font assets in pubspec.yaml;
  • depend on a package that exposes the font and use the configured package;
  • preload/load external fonts in app code, for example when using google_fonts;
  • or rely on a platform/system font when that is acceptable.

Example with local assets:

flutter:
  fonts:
    - family: Inter
      fonts:
        - asset: assets/fonts/Inter-Regular.ttf
        - asset: assets/fonts/Inter-Bold.ttf
          weight: 700

Then reference the family in DACS:

Dacs.configure(
  config: const {
    'theme': {
      'extend': {
        'fontFamily': {
          'brand': 'Inter, sans-serif',
          'mono': 'JetBrains Mono, monospace',
        },
        'typography': {
          'body': 'font-brand text-base',
          'code': 'font-mono text-sm',
        },
      },
    },
  },
);

With packages such as google_fonts, call/preload the desired families in your app; DACS only references those family names through utilities like font-brand.

Motion tokens #

Motion is also string-first. Configure durations, curves, and aliases:

Dacs.configure(
  config: const {
    'theme': {
      'reducedMotionFallback': 'motion-none',
      'extend': {
        'transitionDuration': {
          'standard': '200ms',
          'short': '100ms',
        },
        'transitionTimingFunction': {
          'standard': 'cubic-bezier(0.2, 0, 0, 1)',
        },
        'motion': {
          'standard': 'duration-standard ease-standard',
          'fade-short': 'duration-short ease-out',
        },
      },
    },
  },
);

Use configured aliases like normal utilities:

final motion = 'motion-standard motion-reduce:motion-none'
    .dStyleOf(context)
    .motion;

AnimatedContainer(
  duration: motion?.duration ?? Duration.zero,
  curve: motion?.curve ?? Curves.linear,
  // ...
)

duration-<ms> remains supported and animationDuration still reflects the resolved motion duration. Built-in curves are ease-linear, ease-in, ease-out, and ease-in-out. In motion-disabled contexts DACS resolves declared motion to zero duration and a linear curve unless an explicit motion-disabled:* override is present.

Arbitrary values #

Use square brackets for one-off values:

'text-[#ff0000]'         // exact color
'bg-[rgb(255,0,0)]'      // rgb syntax
'p-[20]'                  // 20px padding
'w-[50%]'                 // 50% width
'rounded-[12]'            // 12px border radius
'opacity-[0.75]'          // 75% opacity
'scale-[200]'             // 2x scale

Design systems can discourage or reject arbitrary values centrally:

Dacs.configure(
  config: const {
    'policy': {
      'arbitraryValues': 'reject',
      'failFast': true,
    },
  },
  onDiagnostic: (diagnostic) {
    debugPrint('${diagnostic.severity}: ${diagnostic.utility}');
  },
);

Policies:

  • allow is the default and preserves the previous behavior.
  • warn reports DacsDiagnosticCode.arbitraryValueDisallowed and still compiles the utility.
  • reject reports an error diagnostic and does not materialize the arbitrary value.

When failFast is true, rejected arbitrary values throw DacsArbitraryValueException. Malformed bracket syntax such as p-[], p-[20]x, or bg-[#ff0000 always emits DacsDiagnosticCode.malformedUtility; with failFast, it throws DacsMalformedUtilityException.

The policy applies to every utility that uses [...], including text/input helpers such as label-[Email] and image utilities such as image-asset-[assets/card.png].

Material widget extensions #

Style Material widgets via context-aware methods. WidgetState variant support (hover:, focus:, disabled:, etc.) varies by adapter — see the table below.

ElevatedButton(
  style: 'bg-primary text-white rounded-lg'.dButton(context),
  onPressed: () {},
  child: const Text('Submit'),
)

CheckboxTheme(
  data: 'bg-primary hover:bg-primaryContainer'.dCheckbox(context),
  child: Checkbox(value: true, onChanged: (_) {}),
)

CardTheme(
  data: 'bg-surface rounded-xl shadow-md'.dCard(context),
  child: Card(child: Text('Content', style: 'text-base'.dText)),
)

All 37 Material adapters are supported: dButton, dIconButton, dSegmentedButton, dCheckbox, dSwitch, dRadio, dChip, dBadge, dAppBar, dCard, dListTile, dTabBar, dBottomNav, dNavBar, dNavRail, dDrawer, dBottomAppBar, dInput, dProgress, dTooltip, dDivider, dScrollbar, dSnackBar, dDialog, dBottomSheet, dExpansionTile, dFab, dDataTable, dSearchBar, dMenu, dPopupMenu, dDropdownMenu, dSlider, dDatePicker, dTimePicker, dIcon, dShape.

For the detailed per-widget property matrix, see the widget support matrix.

TextField inputs #

TextField.style and TextField.decoration are different Flutter APIs. Use .dTextOf(context) for the typed text and .dInputOf(context) for the input chrome: label, hint, helper, error, prefix/suffix, fill, density, padding, and borders.

const classes = 'text-onSurface label-[Email] hint-[you@example.com] '
    'helper-[Use your work email] filled dense bg-surface '
    'border-outline focus:border-primary error:border-error '
    'focus:error:border-primaryContainer rounded-lg p-4';

TextField(
  style: classes.dTextOf(context),
  decoration: classes.dInputOf(context),
)

Date and time picker themes #

Picker adapters use explicit semantic color channels, so DACS does not guess hover, selected, disabled, or overlay colors for you. Declare every visual state you want to control:

Theme(
  data: Theme.of(context).copyWith(
    datePickerTheme:
        'bg-surface text-onSurface rounded-lg shadow-md '
        'date-header-bg-primary date-header-text-onPrimary '
        'date-day-text-onSurface selected:date-day-bg-primary '
        'hover:date-day-overlay-secondary date-today-text-secondary'
            .dDatePicker(context),
    timePickerTheme:
        'bg-surface text-onSurface rounded-lg shadow-md '
        'time-dial-bg-surfaceVariant time-dial-hand-primary '
        'time-hour-minute-bg-surfaceVariant '
        'selected:time-hour-minute-bg-secondary '
        'time-hour-minute-text-onSurface '
        'selected:time-hour-minute-text-onSecondary'
            .dTimePicker(context),
  ),
  child: const SizedBox.shrink(),
)

WidgetState variants #

For Material widgets, use interactive state variants:

ElevatedButton(
  style: 'bg-primary hover:bg-primaryContainer disabled:bg-surface 
          rounded-lg hover:rounded-xl'.dButton(context),
  onPressed: () {},
  child: const Text('Submit'),
)

State order: base → disabled → pressed → hover → focus → selected → error → dragged → scrolledUnder. Shape variants (hover:rounded-xl, pressed:rounded-sm) resolve dynamically via _stateProp.

Chained compound variants #

Combine any variant prefixes with ::

// Applies only in dark mode AND when hovered
Text(
  'Styled text',
  style: 'text-white dark:hover:text-primary'.dTextOf(context),
)

// Triple compound: dark mode, medium breakpoint, hover
Container(
  decoration: 'bg-primary dark:md:hover:bg-error'.dBoxOf(context),
)

Parsed style access #

final sheet = 'text-lg font-bold text-red-600 dark:text-white'.dStyle;
final base = sheet.base;

print(base.fontSize);   // 18
print(base.fontWeight); // FontWeight.w700
print(base.color);      // Color(0xFFDC2626)

final resolved = sheet.resolveFor(context); // DacsResolvedStyle

Extension methods #

Simple getters (no context) #

These parse classes and convert immediately. Useful when you don't need variant resolution.

Getter Returns
.dText TextStyle
.dPads EdgeInsets
.dPadsGeometry EdgeInsetsGeometry
.dBox BoxDecoration
.dStyle DacsStyleSheet
.dBase DacsStyle
.dShadow List<BoxShadow>
.dSize (double?, double?)
.dFixedSize Size?
.dLayout DacsLayoutStyle
.dPosition (double?, double?, double?, double?)
.dPositionDirectional DacsPositionValues
.dTransform Matrix4
.dGradient LinearGradient?
.dBorder BoxBorder?
.dBorderSide BorderSide?
.dRadius BorderRadiusGeometry?
.dConstraints BoxConstraints?
.dAlignment AlignmentGeometry?
.dShapeBorder ShapeBorder?
.dMotion DacsMotionSpec?

Context-aware methods (resolve variants) #

These accept a BuildContext to resolve dark/light mode, responsive breakpoints, and theme colors from MediaQuery / Theme.

Method Returns
.dTextOf(context) TextStyle
.dPadsOf(context) EdgeInsets
.dPadsGeometryOf(context) EdgeInsetsGeometry
.dMarginOf(context) EdgeInsets
.dMarginGeometryOf(context) EdgeInsetsGeometry
.dBoxOf(context) BoxDecoration
.dStyleOf(context) DacsResolvedStyle
.dShadowOf(context) List<BoxShadow>
.dSizeOf(context) (double?, double?)
.dFixedSizeOf(context) Size?
.dLayoutOf(context) DacsLayoutStyle
.dPositionOf(context) (double?, double?, double?, double?)
.dPositionDirectionalOf(context) DacsPositionValues
.dTransformOf(context) Matrix4
.dGradientOf(context) LinearGradient?
.dBorderOf(context) BoxBorder?
.dBorderSideOf(context) BorderSide?
.dRadiusOf(context) BorderRadiusGeometry?
.dConstraintsOf(context) BoxConstraints?
.dAlignmentOf(context) AlignmentGeometry?
.dShapeBorderOf(context) ShapeBorder?
.dMotionOf(context) DacsMotionSpec?

Material widget extensions #

These accept a BuildContext and return Material theme data with variant resolution. WidgetState support is marked per method. For property-level support, see the widget support matrix.

Method Returns WidgetState
.dButton(context) ButtonStyle full
.dIconButton(context) IconButtonThemeData full through ButtonStyle
.dSegmentedButton(context) SegmentedButtonThemeData full through ButtonStyle
.dCheckbox(context) CheckboxThemeData partial
.dSwitch(context) SwitchThemeData partial
.dRadio(context) RadioThemeData partial
.dChip(context) ChipThemeData only color
.dBadge(context) BadgeThemeData
.dScrollbar(context) ScrollbarThemeData partial
.dNavBar(context) NavigationBarThemeData only label
.dNavRail(context) NavigationRailThemeData
.dDrawer(context) DrawerThemeData
.dBottomAppBar(context) BottomAppBarThemeData
.dDataTable(context) DataTableThemeData partial
.dSearchBar(context) SearchBarThemeData partial
.dMenu(context) MenuStyle partial
.dPopupMenu(context) PopupMenuThemeData partial
.dDropdownMenu(context) DropdownMenuThemeData partial
.dSlider(context) SliderThemeData partial
.dDatePicker(context) DatePickerThemeData partial
.dTimePicker(context) TimePickerThemeData partial
.dAppBar(context) AppBarTheme
.dCard(context) CardTheme
.dListTile(context) ListTileThemeData
.dTabBar(context) TabBarTheme
.dBottomNav(context) BottomNavigationBarThemeData
.dInput(context) / .dInputOf(context) InputDecoration focus, disabled, error, focus:error border mappings
.dProgress(context) ProgressIndicatorThemeData
.dTooltip(context) TooltipThemeData
.dDivider(context) DividerThemeData
.dSnackBar(context) SnackBarThemeData
.dDialog(context) DialogTheme
.dBottomSheet(context) BottomSheetThemeData
.dExpansionTile(context) ExpansionTileThemeData
.dFab(context) FloatingActionButtonThemeData
.dIcon(context) IconThemeData
.dShape(context) ShapeDecoration

Supported classes #

Typography #

Class Flutter property
text-xstext-9xl fontSize (12 … 128)
text-{configured} configured fontSize, optional line height and letter spacing
font-thinfont-black fontWeight (100 … 900)
font-{configured} configured font family/fallback/package
leading-3leading-10 height (line height)
leading-noneleading-loose height (relative)
tracking-tightertracking-widest letterSpacing
italic / not-italic fontStyle
underline / line-through / no-underline textDecoration
decoration-solid / double / dotted / dashed / wavy textDecorationStyle
decoration-{1..} textDecorationThickness
decoration-{color}-{shade} textDecorationColor

Motion #

Class Flutter property
duration-0, duration-75, duration-100, duration-150, duration-200, duration-300, duration-500, duration-700, duration-1000 DacsMotionSpec.duration and legacy animationDuration
duration-{integer} duration in milliseconds
duration-{configured} configured transitionDuration
ease-linear, ease-in, ease-out, ease-in-out DacsMotionSpec.curve
ease-{configured} configured transitionTimingFunction
motion-none zero duration and linear curve
motion-{configured} configured theme.motion alias

Colors (text, background, border, decoration) #

Format: {prefix}-{color}-{shade}

'text-sky-500'         // text color
'bg-blue-200'          // background color
'border-red-600'       // border color
'decoration-green-500' // text decoration color

Supported colors: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose

Shades: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950

Also: text-black, text-white, text-transparent

Spacing #

Class Output
p-4 EdgeInsets.all(16)
px-4 EdgeInsets.symmetric(horizontal: 16)
py-2 EdgeInsets.symmetric(vertical: 8)
pt-4, pr-4, pb-4, pl-4 Physical side padding
ps-4, pe-4 Logical start/end padding
m-*, mx-*, my-*, mt-*, mr-*, mb-*, ml-* Same for physical margin
ms-4, me-4 Logical start/end margin

Spacing keys: 0, px, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96

Border #

Class Output
rounded-none BorderRadius.circular(0)
rounded-sm BorderRadius.circular(2)
rounded BorderRadius.circular(4)
rounded-md / rounded-lg / rounded-xl / rounded-2xl / rounded-3xl 6 / 8 / 12 / 16 / 24
rounded-full BorderRadius.circular(9999)
rounded-t-lg, rounded-b-sm, rounded-l-md, rounded-r-xl Directional
rounded-tl-lg, rounded-tr-lg, rounded-bl-lg, rounded-br-lg Corner-specific
border Border.all(width: 1)
border-2border-8 Border.all(width: size)

Sizing & opacity #

'w-64'       // width: 256
'h-32'       // height: 128
'w-full'     // width: double.infinity
'opacity-50' // opacity: 0.5

Shadows #

Class BoxShadows
shadow-sm 1 shadow (subtle)
shadow 2 shadows (default)
shadow-md / shadow-lg / shadow-xl / shadow-2xl Increasing blur/spread
shadow-inner Inset shadow
shadow-none Empty list

Position #

Class Properties
inset-0 top=0, right=0, bottom=0, left=0
inset-x-4 left=16, right=16
inset-y-2 top=8, bottom=8
top-4, right-4, bottom-4, left-4 Individual inset
inset-s-4, inset-e-4 Logical start/end inset
start-4, end-4 Individual logical inset

Transform #

Class Property
scale-125 scaleX=1.25, scaleY=1.25
scale-x-150 scaleX=1.5
scale-y-75 scaleY=0.75
rotate-45 rotateDegrees=45
translate-x-4 translateX=16
translate-y-2 translateY=8
skew-x-12 skewX=12
skew-y-6 skewY=6

Gradient #

'bg-gradient-to-r from-red-500 to-blue-600'
'bg-gradient-to-tl from-amber-400 via-orange-500 to-red-600'

Directions: to-r, to-l, to-t, to-b, to-tr, to-tl, to-br, to-bl

Variants #

Prefix any class with a variant to scope it:

Variant Trigger
dark: Applies when Theme.of(context).brightness == Brightness.dark
light: Applies when Theme.of(context).brightness == Brightness.light
high-contrast: Applies when MediaQueryData.highContrast == true
normal-contrast: Applies when high contrast is inactive
motion-safe: Applies when motion preference is noPreference
motion-reduce: Applies when motion preference is reduce or disabled
motion-disabled: Applies only when motion preference is disabled
sm: Applies at min-width: 640px
md: Applies at min-width: 768px
lg: Applies at min-width: 1024px
xl: Applies at min-width: 1280px
2xl: Applies at min-width: 1536px
hover: WidgetState.hovered
focus: WidgetState.focused
active: / pressed: WidgetState.pressed
disabled: WidgetState.disabled
selected: WidgetState.selected
error: WidgetState.error
dragged: WidgetState.dragged
scrolledUnder: WidgetState.scrolledUnder

Resolution order (Material contexts): base → disabled → pressed → hover → focus → selected → error → dragged → scrolledUnder.

Chained compound variants: combine multiple prefix types with :.

'dark:hover:text-white'      // dark mode + hover
'light:md:bg-primary'        // light mode + md breakpoint
'dark:lg:focus:border-error' // dark + lg + focus
'dark:high-contrast:hover:border-black'
'motion-reduce:duration-0'

Compound variants match only when ALL conditions are met. WidgetState conditions re-map to simple keys for Material widget resolution.

Additional information #

1
likes
150
points
233
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

Tailwind-like utility classes for Flutter. Apply text styles, padding, margins, colors, and borders via concise string expressions.

Repository (GitHub)
View/report issues
Contributing

License

MIT (license)

Dependencies

analyzer, flutter, vector_math

More

Packages that depend on dacs