Skip to content

[web] Enhancing Flutter Web's text editing system by using Platform Views #120613

@htoor3

Description

@htoor3

Objective

One of our core goals is to make Flutter Web feel more idiomatic and natural on the web. A key part of this is to align the behavior of our text inputs to be more consistent with how text inputs behave on the web. This has major implications given how many impactful features branch out of a simple text box (spellcheck, autofill, etc) that web users are conditioned to expect to work. So when text inputs don’t work on Flutter Web apps exactly the way they do elsewhere on the web, it has a glaring impact on UX.

Problems

Clashing styles

We currently delegate all of the rendering of text inputs to the framework rather than the browser.

  • When an <input> element is created, we apply CSS to make these elements and aspects of these elements (content, selection caret, selection highlight, etc) invisible. By resetting the browser’s default styling, we enable Flutter to have full control over the look and feel of our text inputs.
  • This has the potential to cause some issues via a “clashing” of styles. The styles used to hide our text inputs don’t always work consistently across every combination of browsers and platforms, which can lead to strange rendering behavior. For example, in [Web][iOS]: Text field selection with obscuredText: true has grey selection #99918, iOS Safari does not support ::selection pseudoelement styles, which is the method we use to make browser selection transparent. This leads to a clash of styles that creates two overlapping selections, which makes inputs not feel quite right in Flutter Web apps on iOS Safari.

Lazily rendered inputs

We don’t render <input> elements immediately. They are created “as needed” when the user initially focuses on any given text input. They also cease to exist when you blur.

  • This causes some complexity with autofill functionality. Without all of the inputs rendered immediately, we can’t leverage the browser’s native behavior to autofill multiple inputs on a page. Custom logic has been added to enable autofill to work in Flutter apps today.
  • Recreating the browser-native autofill behavior is no simple task. This added complexity can create difficulties in the maintenance and debugging of autofill issues.

Related issues

Solution

The above problems highlight an interesting relationship between Flutter and the browser. In some instances, we are fighting against the browser (e.g. hiding <input> els) and in other instances we’re adding a lot of complexity to our text editing system in order to enable browser-native behavior to work (autofill).

An alternative approach might be to work with the browser to leverage its native behavior as much as we can within the context of Flutter apps.

Platform Views

One way this could be accomplished is by using platform views. Platform views allow you to embed native views in a Flutter app. In the context of Flutter Web, we could use platform views to eagerly render <input> elements.

Additionally, we would need the browser to take responsibility from the framework for the styling of certain aspects of the input:

  • Content
  • Selection highlight
  • Selection caret
  • Context menus / mobile toolbars

Benefits

  • By aligning the functionality of our text inputs more closely with the browser, we can better achieve idiomatic behavior of Flutter Web text inputs and all of the baked-in features that browsers provide for these inputs.
  • We can greatly simplify our codebase (especially in engine) by leveraging pre-existing browser features (e.g. autofill) rather than trying to recreate them. A simplified codebase can help us improve our velocity, maintain our code more effectively, and debug issues more efficiently.
  • We can fix browser-specific rendering issues for text inputs, some of which have no known workarounds in our current system. By delegating the styling of content, carets, selections, and context menus to the browser, we can achieve a more native experience on a multitude of platforms.

Tradeoffs

  • The framework does a great job of giving devs the ability to customize text inputs, potentially to a greater degree than the browser allows. Delegating styling responsibilities to the browser comes at the expense of losing this greater degree of customizability.

Potential issues / Unknowns

  • Platform views are performance-optimized and will disappear outside of the viewport. If <input> elements disappear outside of the viewport, this will break autofill functionality.
  • Could platform views cause performance issues in CanvasKit due to interleaving of <input>elements between <canvas> sheets? Is a page with many inputs feasible when taking into account this performance cost?
  • Can we rewrite the text editing system in a way that continues to integrate well with the Framework’s code philosophy of being platform-agnostic?
  • How will this work when semantics are enabled? Will this solution play well with semantics mode?
  • Password autofill is currently broken for inputs within the shadowDOM in Chrome - but platform views need to be rendered within <slot>s and have to exist in the shadowDOM

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: fidelityMatching the OEM platforms bettera: text inputEntering text in a text field or keyboard related problemsc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterengineflutter/engine related. See also e: labels.platform-webWeb applications specificallyteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions