skip_ink_underline
A Flutter package that provides text underlines that intelligently skip descender letters (g, j, p, q, y), just like CSS text-decoration-skip: ink. Create beautiful, professional typography with a simple API and perfect auto defaults.
✨ Features
- 🎨 Intelligent skip ink - Automatically skips descender letters.
- ⚡ Simple API - Drop-in replacement for the
Textwidget. - 🎯 Professional defaults - Beautiful results without configuration.
- 🔧 Complete control - Fine-tune every aspect when needed.
- 📱 Cross-platform - Works on iOS, Android, Web, Windows, macOS, and Linux.
- 🎨 Per-character control - Customize skip ratios for each descender.
- 📏 Distance & thickness control - Perfect spacing and appearance.
🚀 Installation
Add the following to your package's pubspec.yaml file:
dependencies:
skip_ink_underline: ^1.0.0
Then run:
flutter pub get
💡 Quick Start
Basic Usage (Recommended)
import 'package:skip_ink_underline/skip_ink_underline.dart';
// Instead of Text widget with underline:
Text(
'Typography with g, j, p, q, y',
style: TextStyle(decoration: TextDecoration.underline),
)
// Use SkipInkText:
SkipInkText(
'Typography with g, j, p, q, y',
style: TextStyle(decoration: TextDecoration.underline),
)
That's it! The package uses professional auto defaults that work perfectly out of the box.
Advanced Usage
SkipInkText(
'Custom typography control',
style: TextStyle(
fontSize: 20,
decoration: TextDecoration.underline,
color: Colors.purple,
),
// Distance control
distance: 12, // Custom distance from baseline
autoDistance: false, // Disable auto calculation
// Thickness control
thickness: 2.5, // Custom thickness
autoThickness: false, // Disable auto calculation
// Skip padding control
leftSkip: 4, // Left gap around descenders
rightSkip: 6, // Right gap around descenders
autoSkipPadding: false, // Disable auto calculation
// Per-character control
gSkip: [0.1, 0.9], // Custom g skip ratios
pSkip: [0.0, 0.4], // Partial underline for p
ySkip: [0.25, 0.75], // Custom y skip ratios
// Additional options
underlineColor: Colors.purple,
minSegmentLength: 3,
)
📖 API Reference
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
text |
String |
required | The text to display. |
style |
TextStyle |
required | Text styling (decoration will be handled). |
skipInk |
bool |
true |
Enable skip ink behavior. |
distance |
double? |
null |
Manual distance from baseline. |
autoDistance |
bool |
true |
Use automatic distance calculation. |
thickness |
double? |
null |
Manual underline thickness. |
autoThickness |
bool |
true |
Use automatic thickness calculation. |
leftSkip |
double? |
null |
Left gap around descenders. |
rightSkip |
double? |
null |
Right gap around descenders. |
autoSkipPadding |
bool |
true |
Use automatic skip padding calculation. |
gSkip |
List<double>? |
null |
Custom skip ratios for 'g' left%, right%. |
jSkip |
List<double>? |
null |
Custom skip ratios for 'j' left%, right%. |
pSkip |
List<double>? |
null |
Custom skip ratios for 'p' left%, right%. |
qSkip |
List<double>? |
null |
Custom skip ratios for 'q' left%, right%. |
ySkip |
List<double>? |
null |
Custom skip ratios for 'y' left%, right%. |
underlineColor |
Color? |
null |
Custom underline color (default: text color). |
🎨 Examples
Comparison
// Standard Flutter underline
Text(
'Typography with g, j, p, q, y',
style: TextStyle(decoration: TextDecoration.underline),
)
// Skip ink underline
SkipInkText(
'Typography with g, j, p, q, y',
style: TextStyle(decoration: TextDecoration.underline),
)
Custom Styling
// Purple thick underline with custom spacing
SkipInkText(
'Beautiful purple typography',
style: TextStyle(
fontSize: 24,
color: Colors.purple,
decoration: TextDecoration.underline,
),
underlineColor: Colors.purple,
thickness: 3,
distance: 10,
autoThickness: false,
autoDistance: false,
)
Per-Character Control
// Custom skip ratios for each descender
SkipInkText(
'Custom skips for g, j, p, q, y',
style: TextStyle(decoration: TextDecoration.underline),
gSkip: [0.1, 0.9], // Almost full underline for g
pSkip: [0.0, 0.4], // Partial underline for p
ySkip: [0.25, 0.75], // Centered skip for y
)
🏗️ How It Works
The package uses Flutter's CustomPainter to draw intelligent underlines that:
- Analyze font metrics - Measures actual descender depths.
- Calculate skip zones - Determines where to break the underline.
- Render segments - Draws continuous underline segments between gaps.
- Optimize performance - Caches calculations and minimizes repaints.
🎯 Typography Best Practices
- ✅ Use auto mode for consistent, professional results.
- ✅ Enable skip ink for better readability.
- ✅ Match colors to your design system.
- ✅ Test on multiple sizes and orientations.
- ✅ Consider context - Headers vs. body text may need different settings.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository.
- Create your feature branch (
git checkout -b feature/amazing-feature). - Commit your changes (
git commit -m 'Add amazing feature'). - Push to the branch (
git push origin feature/amazing-feature). - Open a Pull Request.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Credits
Inspired by CSS text-decoration-skip: ink and modern typography best practices.
Made with ❤️ by MNBLabs
Libraries
- skip_ink_underline
- Skip ink underline for Flutter - like CSS text-decoration-skip: ink