flutter_html_css_color 0.2.0
flutter_html_css_color: ^0.2.0 copied to clipboard
A flutter_html extension that corrects the CSS colours flutter_html 3.0.0 mis-reads or drops: 8-digit hex, hsl(), the space-separated syntax, hwb() and 148 named colours.
Example #
flutter_html 3.0.0 mis-reads or drops most of the CSS colour syntax. An
8-digit #rrggbbaa is read as a Dart 0xAARRGGBB literal, so the channels come out one
place along. The space-separated syntax of CSS Color 4 is dropped. hsl() in that syntax
renders black. hwb(), rebeccapurple, transparent and currentColor are dropped.
This extension parses the colour tokens of the inline style itself and writes them back in
the one syntax flutter_html reads without loss.
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html_css_color/flutter_html_css_color.dart';
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
body: Html(
data: '''
<div style="background-color: hsl(210 40% 96%);
border: 2px solid #33415580;
padding: 12px;">
A card tinted with the syntax flutter_html renders black.
</div>
<p style="color: #ff000080;">
Half-transparent red. Without this extension, opaque navy.
</p>
<p style="color: rebeccapurple;">
A named colour csslib does not know.
</p>
<p style="color: #1f2937; border-bottom: 1px solid currentColor;">
A rule in the same colour as the text.
</p>
<p style="text-shadow: 1px 1px 2px transparent;">
Without this extension, this line throws.
</p>
''',
extensions: const [CssColorHtmlExtension()],
),
),
);
}
void main() => runApp(const ExampleApp());
What it corrects #
#rrggbbaaand#rgba, whichflutter_htmlreads as a Dart ARGB literal.rgb(r g b),rgb(r g b / a)and a percentage channel, which it drops.- An out-of-range channel such as
rgb(300, -20, 0), which wraps instead of clamping. hsl()andhsla()in the space-separated form or with an angle unit, which render black.- A hue outside 0 to 360, which throws an assertion.
hwb(), which it drops.rebeccapurple,transparentandcurrentColor, which it drops, andaliceblue, whichcsslibholds as five hex digits and renders as a saturated blue.!importanton any of those declarations.
The correction reaches color, background-color, border and its four sides,
text-decoration-color and text-shadow.
Behaviour #
The extension rewrites the element's inline style attribute at the preStyling step,
before flutter_html parses it. Each colour it understands is written back as
rgba(r, g, b, a). Everything else in the attribute is copied through unchanged,
including a declaration in a property this package does not handle.
That ordering is why two values stop throwing. text-shadow: 1px 1px 2px transparent
throws a null-check error inside flutter_html, in a release build as well as a debug
one, and hsl(400, 100%, 50%) throws an assertion. Neither value reaches the parser once
it has been rewritten.
flutter_html's own cascade does the rest. The extension writes no Style field and
walks no subtree, so an inherited colour reaches a descendant exactly as it does for a
colour flutter_html reads by itself.
A value the extension cannot parse is left alone, byte for byte. oklch(), lab(),
calc() and var() are all in that group, and the element renders exactly as it would
without the extension.
currentColor resolves to the nearest inline color on the element or on an ancestor. In
color itself the keyword is left alone, because a dropped color declaration already
leaves the inherited colour in place, which is what CSS asks for.
The extension reads the inline style="" attribute only. It does not parse <style>
blocks or stylesheets.
Pairing with other extensions #
List this extension before
flutter_html_css_border_radius.
That package reads border out of the inline style at the same step, with a colour parser
of its own that knows six keywords and no hsl().
Html(
data: '<div style="border: 2px solid hsl(0 100% 50%); border-radius: 8px">C</div>',
extensions: const [
CssColorHtmlExtension(), // must come first
CssBorderRadiusHtmlExtension(),
],
);
Order against a utility-class extension does not matter, which is measured against
flutter_html_bootstrap 0.1.1. Neither that package nor
flutter_html_vuetify 0.1.0 suppresses a colour declaration: both count
color, background-color, border, text-decoration-color and text-shadow as
renderable. Both also emit the legacy rgba(r, g, b, a) form, which needs no correction.