flutter_html_css_color

pub version pipeline license GitLab

A flutter_html extension that corrects the CSS colours flutter_html 3.0.0 reads wrong. An 8-digit hex renders a different colour, space-separated hsl() renders black, and rgb(255 0 0), hwb(), rebeccapurple and transparent are dropped. There is no error and no warning.

Features

Declaration flutter_html alone With this extension
color: #ff000080 0xFF000080, opaque navy 0x80FF0000
color: #f008 0x00FFF008, invisible 0x88FF0000
color: rgb(255 0 0 / 0.5) dropped 0x80FF0000
color: hsl(0 100% 50%) 0xFF000000 0xFFFF0000
color: hsl(400, 100%, 50%) assertion error in debug 0xFFFFAA00
color: rebeccapurple dropped 0xFF663399
color: aliceblue 0xFF0F08FF, a blue 0xFFF0F8FF
text-shadow: 1px 1px 2px transparent null-check error 0x00000000
border: 2px solid currentColor 0xFF000000 the element's color

Every number is measured against flutter_html 3.0.0 and pinned by a test. csslib 1.0.2 holds aliceblue as five hex digits.

One rewrite of the style attribute covers color, background-color, border and its four sides, text-decoration, text-decoration-color and text-shadow, plus border-color, the border-*-color longhands and outline for the sibling that renders them.

Getting started

dependencies:
  flutter_html: ^3.0.0
  flutter_html_css_color: ^0.2.0

Usage

import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html_css_color/flutter_html_css_color.dart';

Html(
  data: '''
    <div style="background-color: hsl(210 40% 96%);
                color: rebeccapurple;">
      A card flutter_html cannot colour
    </div>
  ''',
  extensions: const [CssColorHtmlExtension()],
);

parseCssColorValue reads one colour value without an Html widget. Pass its currentColor argument when the value can be currentcolor.

Before you register it

List this extension before flutter_html_css_border_radius. Both act at the preStyling step, where flutter_html runs every extension that matches in registration order. That package reads border from the inline style with a colour parser of its own, which knows six colour names 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(),
  ],
);

Measured on that snippet against its version 0.1.1: listed first the clip's border is 0xFFFF0000, listed second 0xFF000000.

Order against flutter_html_css_border does not matter. It folds border-color into a border shorthand at the same step, passing the colour token through, so either order hands flutter_html an rgba(). Measured on border-color: hsl(0 100% 50%): 0xFFFF0000 both ways. Without it those longhands stay dropped.

Order against a TagExtension does not matter, which is measured. It builds its own widget, which reads no Style.

flutter_html_bootstrap 0.1.1 and flutter_html_vuetify 0.1.0 need no entry for this extension: neither suppresses a colour declaration, and both write the legacy rgba(r, g, b, a) form. Bootstrap is measured, Vuetify read from its source.

Limitations

  • lab(), lch(), oklab(), oklch(), color(), color-mix(), calc() and var() stay dropped. This package carries no colour engine beyond sRGB.
  • border: 2px solid with no colour renders black. CSS asks for the element's own colour. This extension replaces a colour token and never adds one.
  • currentColor resolves against the nearest inline color on the element or an ancestor, and is left alone when there is none. In color itself it is always left alone.
  • text-shadow whose colour is a word that is not a CSS colour name still throws inside flutter_html. Only a value this package parses reaches the parser corrected.
  • A <style> block and an external stylesheet are not read. flutter_html_css_stylesheet writes those declarations into the inline style first.

The measurement table records every case.

Additional information

Issues and merge requests go to the GitLab repository.

CI, publishing and Renovate are described in CONTRIBUTING.md.