# Bringing CSS "float" to Flutter text rendering

When displaying text in your Flutter app, you may notice that Flutter's text rendering capabilities are lacking some features commonly used in web pages, such as CSS `float`, which is used to place an image or other element on the left or right side of the text, allowing the text to wrap around it.

For example, let's say we're starting with some rich text, and we want to add a drop-cap for the first letter, and float a couple images in the text.

![float_column.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1657383611570/7TY59QsY_.png align="left")

To accomplish this, we could resort to using a package such as `webview_flutter` to display the text in a platform native web view using HTML and CSS, but that comes with its own complications and limitations — and after all, we are writing a Flutter app, not a web app — it would be better if the text and floated items could be rendered with widgets!

## FloatColumn to the rescue

We can accomplish our goal with the help of the `float_column` package, whose only dependency is Flutter, so it works seamlessly on all Flutter platforms: Android, iOS, Linux, macOS, Web, and Windows.

This is the code we're starting with — basically, just some rich text:

```dart
Text.rich(
  TextSpan(
    children: [
      TextSpan(text: '“This is what you shall do...'),
      ...
    ],
  ),
),
```

## First, let's add the drop cap

1. Import the `float_column` package.

2. Wrap the `Text.rich` in a `FloatColumn` widget.

3. Add a `WidgetSpan` and `Floatable` for the drop cap widget.

    The `float: FCFloat.start` causes the child `DropCap` widget to float at the start of the text so the text can wrap around it.

4. Remove the '“T' from the TextSpan.

```dart
// 1. Import the `float_column` package.
import 'package:float_column/float_column.dart';

// 2. Wrap the `Text.rich` in a `FloatColumn` widget.
FloatColumn(
  children: [
    Text.rich(
      TextSpan(
        children: [

          // 3. Add a `WidgetSpan` and `Floatable` for the drop cap widget.
          WidgetSpan(
            child: Floatable(
              float: FCFloat.start,
              child: DropCap('“T', height: 3),
          ),

          // 4. Remove the '“T' from the TextSpan.
          TextSpan(text: 'his is what you shall do...'),
        ],
      ),
    ),
  ],
)
```

Which gives us this:

![Simulator Screen Shot - iPhone SE (3rd generation) - 2022-07-09 at 11.02.37.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1657386243830/b_XvI0SdC.png align="left")

## Next, let's add the floating images

This involves adding a `WidgetSpan` and `Floatable` for each image widget.

For the first image, we're setting `float: FCFloat.end`. Because the current text direction is left-to-right (LTR), the image is floated to the right side of the text. If the current text direction was RTL it would float to the left side.  The possible `FCFloat` values are `none`, `left`, `right`, `start`, and `end`.

We're also setting `clear: FCClear.both` for both images. Like the CSS `clear` property, this makes sure the floating widget is placed below floating widgets on both sides. The possible `FCClear` values are `none`, `left`, `right`, `start`, `end`, and `both`.

The `clearMinSpacing` property provides a way to add or subtract additional spacing in relation to the cleared position. A positive value moves the widget down, and a negative value moves it up.

```dart
import 'package:float_column/float_column.dart';

FloatColumn(
  children: [
    Text.rich(
      TextSpan(
        children: [
          WidgetSpan(
            child: Floatable(
              float: FCFloat.start,
              child: DropCap('“T', height: 3),
          ),

          // Add a `WidgetSpan` and `Floatable` for each floating image:

          WidgetSpan(
            child: Floatable(
              float: FCFloat.end,
              clear: FCClear.both,
              clearMinSpacing: 16,
              maxWidthPercentage: 0.33,
              padding: EdgeInsetsDirectional.only(start: 8),
              child: Img(name: 'walt.jpg', title: 'Walt Whitman'),
            ),
          ),

          WidgetSpan(
            child: Floatable(
              float: FCFloat.start,
              clear: FCClear.both,
              clearMinSpacing: 60,
              maxWidthPercentage: 0.33,
              padding: EdgeInsetsDirectional.only(end: 12),
              child: Img(name: 'jeremy.jpg', title: 'Photo by...'),
            ),
          ),

          TextSpan(text: 'his is what you shall do...'),
        ],
      ),
    ),
  ],
)
```
Which accomplishes our goal:

![Simulator Screen Shot - iPhone SE (3rd generation) - 2022-07-09 at 10.14.54 copy.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1657388970590/Z9QscN2KI.png align="left")

## Try it out with Flutter Web:

[ronjb.github.io/float_column](https://ronjb.github.io/float_column)

For the complete source code for this example (with some tweaks so it looks good on screens of any size), see:

[github.com/ronjb/float_column/example/lib/pages/basic_ltr.dart](https://github.com/ronjb/float_column/blob/main/example/lib/pages/basic_ltr.dart)

And for info about the `float_column` package see:

%[https://pub.dev/packages/float_column]

