flutter_html_css_size_constraints

pub version pipeline license GitLab

A flutter_html extension that renders the CSS max-width, min-width, max-height and min-height properties. flutter_html 3.0.0 reads width and height but drops these four, and there is no error and no warning. A percentage throws under an IntrinsicHeight or an IntrinsicWidth; pass resolvePercentages: false there.

Features

  • The extension wraps an element in a ConstrainedBox when one of the four declarations resolves.
  • The wrapper sits outside flutter_html's own box, so a max-width clamps a width that flutter_html did parse.
  • A min-* beats a conflicting max-*, as in CSS.
  • px, the other absolute lengths, %, the viewport units, em and rem resolve.

Getting started

dependencies:
  flutter_html: ^3.0.0
  flutter_html_css_size_constraints: ^0.2.0

Usage

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

Html(
  data: '<div style="max-width: 320px;">Card</div>',
  extensions: const [CssSizeConstraintsHtmlExtension()],
);

Before you register it

This extension matches on the inline style, never on the tag name, so it cannot make flutter_html render a tag that has no renderer. A TagExtension does that. List this extension before every TagExtension. flutter_html builds an element with the first extension in the list that matches it. List the TagExtension first and this extension never runs: the element renders without its constraint, and there is no error and no warning.

Html(
  data: '<v-card style="max-width: 320px;">Card</v-card>',
  extensions: [
    const CssSizeConstraintsHtmlExtension(), // must come first
    TagExtension(tagsToExtend: const {'v-card'}, child: const Text('Card')),
  ],
);

List this extension before flutter_html_css_percent_size, which renders a percentage width and height. Neither order is CSS. Measured on <div style="width: 50%; max-width: 100px"> in a containing block of 784 logical pixels: 50 with this extension first, 392 with it second. CSS says 100. First keeps the clamp and errs small. Second loses the max-width, with no error and no warning.

Another extension at the building step delegates the element the same way this one does, so both run in either order. This extension refuses to build a node it is already building, which stops the two from recursing until the stack runs out. List this one first: a companion with no guard of its own runs twice when listed first, and builds one wasted wrapper. Released flutter_html_css_interaction 0.1.0 has no guard. Its 0.1.1 adds one.

Order against a utility-class extension does not matter, because this extension reads the inline style after a utility-class extension expands every class.

Released flutter_html_bootstrap 0.1.1 and flutter_html_vuetify 0.1.0 do not recognise CssSizeConstraintsHtmlExtension. Both still suppress the classes this extension could render, and report them through FlutterError. Write the four properties into an inline style attribute until a release of theirs lists it.

Limitations

  • A percentage inserts a LayoutBuilder, which cannot do dry layout, so it throws under any intrinsic measurement. Pass resolvePercentages: false there. Every other unit still renders.
  • A percentage resolves against the incoming constraints, so a percentage max-height or min-height normally resolves to nothing: Flutter heights are unbounded.
  • vw, vh, vmin and vmax resolve to nothing when no MediaQuery is in scope. There is no error and no warning.
  • em resolves against the element's own font size; rem against rootFontSize, whose null default is flutter_html's root font size of 14, not the browser's 16.
  • flutter_html 3.0.0 drops a font-size written in rem at parse time, so em on that element follows the inherited size. flutter_html_css_font_size will close this gap.
  • Only the inline style is read. <style> blocks and stylesheets are not.

doc/units.md carries the full unit table, the units that do not resolve such as calc(), and the reasoning behind each basis.

Additional information

Issues and merge requests go to the GitLab repository.

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