Skip to content

Tailwind, for Flutter

Style maps Tailwind utility classes straight to Flutter widget properties — the same UI, with a fraction of the code.
Same card · two ways

One responsive, dark-aware card — built both ways. Drag the preview across the 640px breakpoint, and toggle the site theme, to watch it adapt.

Lines changed: 19 additions & 67 deletions
main.dartPlain Flutter
import 'package:flutter/material.dart';

const avatarUrl =
    'https://images.unsplash.com/photo-1501196354995-cbb51c65aaea'
    '?auto=format&fit=facearea&facepad=4&w=256&h=256&q=80';

const shadowLg = <BoxShadow>[
  BoxShadow(
    color: Color(0x1A000000),
    blurRadius: 12.12,
    spreadRadius: -3,
    offset: Offset(0, 10),
  ),
  BoxShadow(
    color: Color(0x1A000000),
    blurRadius: 4.33,
    spreadRadius: -4,
    offset: Offset(0, 4),
  ),
];

class ContactCard extends StatelessWidget {
  const ContactCard({super.key});
  @override
  Widget build(BuildContext context) {
    final dark = Theme.brightnessOf(context) == Brightness.dark;
    final wide = MediaQuery.sizeOf(context).width >= 640;

    final avatar = SizedBox.square(
      dimension: 64,
      child: ClipOval(child: Image.network(avatarUrl, fit: BoxFit.cover)),
    );

    final align = wide ? TextAlign.start : TextAlign.center;
    final text = Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: wide
          ? CrossAxisAlignment.start
          : CrossAxisAlignment.stretch,
      children: [
        Text(
          'Andrew Alfred',
          textAlign: align,
          style: TextStyle(
            fontSize: 16,
            height: 24 / 16,
            fontWeight: FontWeight.w500,
            color: dark ? const Color(0xFFFFFFFF) : const Color(0xFF101828),
          ),
        ),
        Text(
          'Sent you a new message',
          textAlign: align,
          style: TextStyle(
            fontSize: 14,
            height: 20 / 14,
            color: dark ? const Color(0xFF99A1AF) : const Color(0xFF6A7282),
          ),
        ),
      ],
    );

    return Container(
      width: double.infinity,
      constraints: const BoxConstraints(maxWidth: 384),
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        color: dark ? const Color(0xFF1E2939) : const Color(0xFFFFFFFF),
        borderRadius: BorderRadius.circular(12),
        boxShadow: shadowLg,
        border: Border.all(
          color: dark ? const Color(0x1AFFFFFF) : const Color(0x0D000000),
          strokeAlign: BorderSide.strokeAlignOutside,
        ),
      ),
      child: Flex(
        direction: wide ? Axis.horizontal : Axis.vertical,
        mainAxisSize: MainAxisSize.min,
        spacing: wide ? 24 : 16,
        children: [avatar, text],
      ),
    );
  }
}
import 'package:flutter/material.dart';

const avatarUrl =
    'https://images.unsplash.com/photo-1501196354995-cbb51c65aaea'
    '?auto=format&fit=facearea&facepad=4&w=256&h=256&q=80';

const shadowLg = <BoxShadow>[
  BoxShadow(
    color: Color(0x1A000000),
    blurRadius: 12.12,
    spreadRadius: -3,
    offset: Offset(0, 10),
  ),
  BoxShadow(
    color: Color(0x1A000000),
    blurRadius: 4.33,
    spreadRadius: -4,
    offset: Offset(0, 4),
  ),
];

class ContactCard extends StatelessWidget {
  const ContactCard({super.key});
  @override
  Widget build(BuildContext context) {
    final dark = Theme.brightnessOf(context) == Brightness.dark;
    final wide = MediaQuery.sizeOf(context).width >= 640;

    final avatar = SizedBox.square(
      dimension: 64,
      child: ClipOval(child: Image.network(avatarUrl, fit: BoxFit.cover)),
    );

    final align = wide ? TextAlign.start : TextAlign.center;
    final text = Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: wide
          ? CrossAxisAlignment.start
          : CrossAxisAlignment.stretch,
      children: [
        Text(
          'Andrew Alfred',
          textAlign: align,
          style: TextStyle(
            fontSize: 16,
            height: 24 / 16,
            fontWeight: FontWeight.w500,
            color: dark ? const Color(0xFFFFFFFF) : const Color(0xFF101828),
          ),
        ),
        Text(
          'Sent you a new message',
          textAlign: align,
          style: TextStyle(
            fontSize: 14,
            height: 20 / 14,
            color: dark ? const Color(0xFF99A1AF) : const Color(0xFF6A7282),
          ),
        ),
      ],
    );

    return Container(
      width: double.infinity,
      constraints: const BoxConstraints(maxWidth: 384),
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        color: dark ? const Color(0xFF1E2939) : const Color(0xFFFFFFFF),
        borderRadius: BorderRadius.circular(12),
        boxShadow: shadowLg,
        border: Border.all(
          color: dark ? const Color(0x1AFFFFFF) : const Color(0x0D000000),
          strokeAlign: BorderSide.strokeAlignOutside,
        ),
      ),
      child: Flex(
        direction: wide ? Axis.horizontal : Axis.vertical,
        mainAxisSize: MainAxisSize.min,
        spacing: wide ? 24 : 16,
        children: [avatar, text],
      ),
    );
  }
}
main.dartStyle
import 'package:flutter/material.dart';
import 'package:style/style.dart';

const avatarUrl =
    'https://images.unsplash.com/photo-1501196354995-cbb51c65aaea'
    '?auto=format&fit=facearea&facepad=4&w=256&h=256&q=80';

class ContactCard extends StatelessWidget {
  const ContactCard({super.key});
  @override
  Widget build(BuildContext context) {
    return Style(
      'mx-auto flex max-w-sm flex-col items-center gap-4 rounded-xl bg-white'
      ' p-6 text-center shadow-lg ring-1 ring-black/5 sm:flex-row sm:gap-6'
      ' sm:text-left dark:bg-gray-800 dark:ring-white/10',
      children: [
        Style(
          'size-16 shrink-0 rounded-full object-cover',
          child: Image.network(avatarUrl),
        ),
        Style.empty(
          children: [
            Style(
              'text-base font-medium text-gray-900 dark:text-white',
              child: const Text('Andrew Alfred'),
            ),
            Style(
              'text-sm text-gray-500 dark:text-gray-400',
              child: const Text('Sent you a new message'),
            ),
          ],
        ),
      ],
    );
  }
}
import 'package:flutter/material.dart';
import 'package:style/style.dart';

const avatarUrl =
    'https://images.unsplash.com/photo-1501196354995-cbb51c65aaea'
    '?auto=format&fit=facearea&facepad=4&w=256&h=256&q=80';

class ContactCard extends StatelessWidget {
  const ContactCard({super.key});
  @override
  Widget build(BuildContext context) {
    return Style(
      'mx-auto flex max-w-sm flex-col items-center gap-4 rounded-xl bg-white'
      ' p-6 text-center shadow-lg ring-1 ring-black/5 sm:flex-row sm:gap-6'
      ' sm:text-left dark:bg-gray-800 dark:ring-white/10',
      children: [
        Style(
          'size-16 shrink-0 rounded-full object-cover',
          child: Image.network(avatarUrl),
        ),
        Style.empty(
          children: [
            Style(
              'text-base font-medium text-gray-900 dark:text-white',
              child: const Text('Andrew Alfred'),
            ),
            Style(
              'text-sm text-gray-500 dark:text-gray-400',
              child: const Text('Sent you a new message'),
            ),
          ],
        ),
      ],
    );
  }
}