Back to Posts

How to Add Text Over Images in Flutter: Complete Guide

14 min read
<div style="text-align: center;"> <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDMwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPCEtLSBCYWNrZ3JvdW5kIGltYWdlIC0tPgogIDxyZWN0IHdpZHRoPSIzMDAiIGhlaWdodD0iMjAwIiBmaWxsPSIjMjE5NkYzIi8+CiAgPCEtLSBPdmVybGF5IHRleHQgLS0+CiAgPHJlY3QgeD0iNTAiIHk9IjgwIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjQwIiByeD0iMTAiIGZpbGw9IndoaXRlIiBvcGFjaXR5PSIwLjgiLz4KICA8dGV4dCB4PSIxNTAiIHk9IjEwNSIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjE2IiBmaWxsPSIjMjEyMTIxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5UZXh0IE92ZXIgSW1hZ2U8L3RleHQ+Cjwvc3ZnPg==" alt="Text Over Image Example" width="300" /> </div>

Adding text over images is a common requirement in Flutter applications, whether for creating banners, hero sections, or simply enhancing the visual appeal of your UI. This guide will walk you through various techniques to achieve this effect, from basic implementations to advanced styling options.

Basic Implementation Using Stack

The most straightforward way to overlay text on an image is using the Stack widget:

Stack(
  children: [
    Image.network(
      'https://example.com/image.jpg',
      width: double.infinity,
      height: 200,
      fit: BoxFit.cover,
    ),
    Positioned(
      bottom: 16,
      left: 16,
      right: 16,
      child: Text(
        'Your Text Here',
        style: TextStyle(
          color: Colors.white,
          fontSize: 24,
          fontWeight: FontWeight.bold,
        ),
      ),
    ),
  ],
)
<div style="text-align: center;"> <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDMwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPCEtLSBCYXNpYyBpbWFnZSB3aXRoIHRleHQgLS0+CiAgPHJlY3Qgd2lkdGg9IjMwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IiMyMTk2RjMiLz4KICA8dGV4dCB4PSIxNTAiIHk9IjE3MCIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjI0IiBmaWxsPSJ3aGl0ZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+WW91ciBUZXh0IEhlcmU8L3RleHQ+Cjwvc3ZnPg==" alt="Basic Text Over Image" width="300" /> </div>

Adding Background Overlay

To improve text readability, you can add a semi-transparent background:

Stack(
  children: [
    Image.network(
      'https://example.com/image.jpg',
      width: double.infinity,
      height: 200,
      fit: BoxFit.cover,
    ),
    // Semi-transparent black overlay
    Container(
      color: Colors.black.withOpacity(0.5),
    ),
    Positioned(
      bottom: 16,
      left: 16,
      right: 16,
      child: Text(
        'Your Text Here',
        style: TextStyle(
          color: Colors.white,
          fontSize: 24,
          fontWeight: FontWeight.bold,
        ),
      ),
    ),
  ],
)
<div style="text-align: center;"> <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDMwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPCEtLSBCYWNrZ3JvdW5kIGltYWdlIHdpdGggb3ZlcmxheSAtLT4KICA8cmVjdCB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iIzIxOTZGMyIvPgogIDxyZWN0IHdpZHRoPSIzMDAiIGhlaWdodD0iMjAwIiBmaWxsPSIjMDAwMDAwIiBvcGFjaXR5PSIwLjUiLz4KICA8dGV4dCB4PSIxNTAiIHk9IjE3MCIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjI0IiBmaWxsPSJ3aGl0ZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+WW91ciBUZXh0IEhlcmU8L3RleHQ+Cjwvc3ZnPg==" alt="Text with Background Overlay" width="300" /> </div>

Gradient Overlay

For a more sophisticated look, use a gradient overlay:

Stack(
  children: [
    Image.network(
      'https://example.com/image.jpg',
      width: double.infinity,
      height: 200,
      fit: BoxFit.cover,
    ),
    // Gradient overlay
    Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            Colors.transparent,
            Colors.black.withOpacity(0.7),
          ],
        ),
      ),
    ),
    Positioned(
      bottom: 16,
      left: 16,
      right: 16,
      child: Text(
        'Your Text Here',
        style: TextStyle(
          color: Colors.white,
          fontSize: 24,
          fontWeight: FontWeight.bold,
        ),
      ),
    ),
  ],
)
<div style="text-align: center;"> <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDMwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPCEtLSBCYWNrZ3JvdW5kIGltYWdlIHdpdGggZ3JhZGllbnQgLS0+CiAgPHJlY3Qgd2lkdGg9IjMwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IiMyMTk2RjMiLz4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZCIgeDE9IjAiIHkxPSIwIiB4Mj0iMCIgeTI9IjIwMCI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6I3RyYW5zcGFyZW50Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzAwMDAwMDtzdG9wLW9wYWNpdHk6MC43Ii8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogIDwvZGVmcz4KICA8cmVjdCB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0idXJsKCNncmFkKSIvPgogIDx0ZXh0IHg9IjE1MCIgeT0iMTcwIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMjQiIGZpbGw9IndoaXRlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5Zb3VyIFRleHQgSGVyZTwvdGV4dD4KPC9zdmc+" alt="Text with Gradient Overlay" width="300" /> </div>

Advanced Text Styling

Text with Shadow

Text(
  'Your Text Here',
  style: TextStyle(
    color: Colors.white,
    fontSize: 24,
    fontWeight: FontWeight.bold,
    shadows: [
      Shadow(
        offset: Offset(2, 2),
        blurRadius: 3,
        color: Colors.black.withOpacity(0.5),
      ),
    ],
  ),
)

Multiple Text Lines with Different Styles

Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Text(
      'Main Title',
      style: TextStyle(
        color: Colors.white,
        fontSize: 28,
        fontWeight: FontWeight.bold,
        shadows: [
          Shadow(
            offset: Offset(2, 2),
            blurRadius: 3,
            color: Colors.black.withOpacity(0.5),
          ),
        ],
      ),
    ),
    SizedBox(height: 8),
    Text(
      'Subtitle or Description',
      style: TextStyle(
        color: Colors.white.withOpacity(0.9),
        fontSize: 16,
      ),
    ),
  ],
)

Responsive Text Overlay

To make your text overlay responsive:

LayoutBuilder(
  builder: (context, constraints) {
    return Stack(
      children: [
        Image.network(
          'https://example.com/image.jpg',
          width: constraints.maxWidth,
          height: constraints.maxHeight,
          fit: BoxFit.cover,
        ),
        Positioned(
          bottom: constraints.maxHeight * 0.1,
          left: constraints.maxWidth * 0.05,
          right: constraints.maxWidth * 0.05,
          child: Text(
            'Your Text Here',
            style: TextStyle(
              color: Colors.white,
              fontSize: constraints.maxWidth * 0.08,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ],
    );
  },
)

Interactive Text Overlay

Add interactivity to your text overlay:

Stack(
  children: [
    Image.network(
      'https://example.com/image.jpg',
      width: double.infinity,
      height: 200,
      fit: BoxFit.cover,
    ),
    Positioned(
      bottom: 16,
      left: 16,
      right: 16,
      child: Material(
        color: Colors.transparent,
        child: InkWell(
          onTap: () {
            // Handle tap
          },
          child: Container(
            padding: EdgeInsets.all(16),
            child: Text(
              'Tap Me!',
              style: TextStyle(
                color: Colors.white,
                fontSize: 24,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
        ),
      ),
    ),
  ],
)

Best Practices

  1. Contrast: Ensure sufficient contrast between text and background
  2. Readability: Use appropriate font sizes and weights
  3. Responsiveness: Make text size responsive to screen size
  4. Performance: Optimize image loading and caching
  5. Accessibility: Consider color blindness and other accessibility needs

Complete Example

Here's a complete example that combines multiple techniques:

class ImageWithTextOverlay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 300,
      child: Stack(
        children: [
          // Background image
          Image.network(
            'https://example.com/image.jpg',
            width: double.infinity,
            height: double.infinity,
            fit: BoxFit.cover,
          ),
          // Gradient overlay
          Container(
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                colors: [
                  Colors.transparent,
                  Colors.black.withOpacity(0.7),
                ],
              ),
            ),
          ),
          // Content
          Positioned(
            bottom: 32,
            left: 24,
            right: 24,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Main Title',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 32,
                    fontWeight: FontWeight.bold,
                    shadows: [
                      Shadow(
                        offset: Offset(2, 2),
                        blurRadius: 3,
                        color: Colors.black.withOpacity(0.5),
                      ),
                    ],
                  ),
                ),
                SizedBox(height: 8),
                Text(
                  'Subtitle or description text that provides additional context.',
                  style: TextStyle(
                    color: Colors.white.withOpacity(0.9),
                    fontSize: 16,
                  ),
                ),
                SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () {
                    // Handle button press
                  },
                  child: Text('Learn More'),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Conclusion

Adding text over images in Flutter is a powerful technique that can enhance your app's visual appeal and user experience. By using the Stack widget and various styling options, you can create beautiful and functional overlays that work well across different screen sizes and orientations.

Remember to:

  • Ensure text readability with proper contrast
  • Use appropriate styling for different contexts
  • Make your overlays responsive
  • Consider accessibility requirements
  • Optimize for performance

Happy coding!