flutter_html_css_stylesheet 0.2.0 copy "flutter_html_css_stylesheet: ^0.2.0" to clipboard
flutter_html_css_stylesheet: ^0.2.0 copied to clipboard

A flutter_html extension that resolves a CSS stylesheet and writes each element's winning declarations into its inline style, so extensions can read them.

example/example.md

Example #

flutter_html 3.0.0 reads a <style> block and then drops most of it. Its styleTree() collects every block, parseExternalCss() parses it, and each matching element takes the rule through declarationsToStyle(). That function knows 51 property names. Everything else is discarded at parse time, with no error and no warning, before any extension runs. This extension resolves the stylesheet itself and writes the result into each element's inline style="", where flutter_html and every companion extension already look.

import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html_css_border_radius/flutter_html_css_border_radius.dart';
import 'package:flutter_html_css_stylesheet/flutter_html_css_stylesheet.dart';

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          body: Html(
            data: '''
              <style>
                .card {
                  border-radius: 12px;
                  padding: 12px;
                  margin: 8px;
                  background-color: #e7f1ff;
                }
                .card p { color: #0d6efd; }
                #note { color: #6c757d !important; }
              </style>

              <div class="card">
                <p>Rounded, padded, and blue.</p>
                <p id="note" style="color: #dc3545">Grey, because the rule is important.</p>
              </div>
            ''',
            extensions: const [
              CssStylesheetHtmlExtension(), // must come first
              CssBorderRadiusHtmlExtension(),
            ],
          ),
        ),
      );
}

void main() => runApp(const ExampleApp());

Passing a stylesheet in #

A <link rel="stylesheet"> is never fetched. Read the file yourself and pass the text:

import 'package:flutter/services.dart' show rootBundle;

Future<Widget> buildCard() async {
  final css = await rootBundle.loadString('assets/app.css');
  return Html(
    data: '<div class="card">Card</div>',
    extensions: [CssStylesheetHtmlExtension(stylesheet: css)],
  );
}

The argument is read before the document's own <style> blocks, which is where a browser reads a <link> in <head>. A <style> rule of equal specificity therefore wins.

Set readStyleElements: false to use the argument alone.

The cascade #

Per property, an !important declaration wins first, then the inline style, then the higher specificity, then the later rule. The selector and specificity reference has the full tables.

What renders nothing #

Html(
  data: '<style>@media (min-width: 600px) { p { color: red } }</style><p>x</p>',
  extensions: [
    CssStylesheetHtmlExtension(
      onUnsupportedRule: (rule) => debugPrint('${rule.text}: ${rule.detail}'),
    ),
  ],
);

Without the callback that rule is dropped in silence. With it, each at-rule, pseudo-element and unevaluable pseudo-class is named once per document.

A @media block is also a defect in flutter_html itself. Its parseExternalCss() throws a LateInitializationError on one, and a TypeError on @keyframes, with no extension registered at all. This extension empties each <style> element after reading it, which is what keeps parseExternalCss() away from the at-rule. Set consumeStyleElements: false to leave flutter_html's own <style> handling in place, and then keep both at-rules out of the document.

Registration order #

Every extension that reads or writes the inline style acts at the preStyling step, and flutter_html runs them in registration order. List this one first:

Html(
  data: '<style>.card { border-width: 2px; border-style: solid }</style>'
      '<div class="card">Card</div>',
  extensions: const [
    CssStylesheetHtmlExtension(), // first
    CssBorderHtmlExtension(),     // then the border longhands resolve
  ],
);

Reverse those two and the border extension reads the style attribute before the rule arrives in it. It finds no border, returns, and flutter_html drops both longhands as usual. The text still renders. The border does not, and there is no error and no warning.

0
likes
160
points
47
downloads

Documentation

API reference

Publisher

verified publisherchaosworld.cc

Weekly Downloads

A flutter_html extension that resolves a CSS stylesheet and writes each element's winning declarations into its inline style, so extensions can read them.

Repository (GitLab)
View/report issues
Contributing

Topics

#flutter-html #css #html #extension #stylesheet

License

MPL-2.0 (license)

Dependencies

csslib, flutter, flutter_html, html

More

Packages that depend on flutter_html_css_stylesheet