Skip to content

Text

Examples#

Live example

Custom text styles#

import flet as ft


def main(page: ft.Page):
    page.title = "Text custom styles"
    page.scroll = ft.ScrollMode.ADAPTIVE

    page.add(
        ft.Text("Size 10", size=10),
        ft.Text("Size 30, Italic", size=30, color=ft.Colors.PINK_600, italic=True),
        ft.Text(
            value="Size 40, w100",
            size=40,
            color=ft.Colors.WHITE,
            bgcolor=ft.Colors.BLUE_600,
            weight=ft.FontWeight.W_100,
        ),
        ft.Text(
            value="Size 50, Normal",
            size=50,
            color=ft.Colors.WHITE,
            bgcolor=ft.Colors.ORANGE_800,
            weight=ft.FontWeight.NORMAL,
        ),
        ft.Text(
            value="Size 60, Bold, Italic",
            size=50,
            color=ft.Colors.WHITE,
            bgcolor=ft.Colors.GREEN_700,
            weight=ft.FontWeight.BOLD,
            italic=True,
        ),
        ft.Text(
            value="Size 70, w900, selectable",
            size=70,
            weight=ft.FontWeight.W_900,
            selectable=True,
        ),
        ft.Text(
            value="Limit long text to 1 line with ellipsis",
            theme_style=ft.TextThemeStyle.HEADLINE_SMALL,
        ),
        ft.Text(
            value="Proin rutrum, purus sit amet elementum volutpat, nunc lacus vulputate orci, cursus ultrices neque dui quis purus. Ut ultricies purus nec nibh bibendum, eget vestibulum metus various. Duis convallis maximus justo, eu rutrum libero maximus id. Donec ullamcorper arcu in sapien molestie, non pellentesque tellus pellentesque. Nulla nec tristique ex. Maecenas euismod nisl enim, a convallis arcu laoreet at. Ut at tortor finibus, rutrum massa sit amet, pulvinar velit. Phasellus diam lorem, viverra vitae leo vitae, consequat suscipit lorem.",
            max_lines=1,
            overflow=ft.TextOverflow.ELLIPSIS,
        ),
        ft.Text(
            value="Limit long text to 2 lines and fading",
            theme_style=ft.TextThemeStyle.HEADLINE_SMALL,
        ),
        ft.Text(
            value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur quis nibh vitae purus consectetur facilisis sed vitae ipsum. Quisque faucibus sed nulla placerat sagittis. Phasellus condimentum risus vitae nulla vestibulum auctor. Curabitur scelerisque, nibh eget imperdiet consequat, odio ante tempus diam, sed volutpat nisl erat eget turpis. Sed viverra, diam sit amet blandit vulputate, mi tellus dapibus lorem, vitae vehicula diam mauris placerat diam. Morbi sit amet pretium turpis, et consequat ligula. Nulla velit sem, suscipit sit amet dictum non, tincidunt sed nulla. Aenean pellentesque odio porttitor sagittis aliquam. Name various at metus vitae vulputate. Praesent faucibus nibh lorem, eu pretium dolor dictum nec. Phasellus eget dui laoreet, viverra magna vitae, pellentesque diam.",
            max_lines=2,
        ),
        ft.Text(
            value="Limit the width and height of long text",
            theme_style=ft.TextThemeStyle.HEADLINE_SMALL,
        ),
        ft.Text(
            value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur quis nibh vitae purus consectetur facilisis sed vitae ipsum. Quisque faucibus sed nulla placerat sagittis. Phasellus condimentum risus vitae nulla vestibulum auctor. Curabitur scelerisque, nibh eget imperdiet consequat, odio ante tempus diam, sed volutpat nisl erat eget turpis. Sed viverra, diam sit amet blandit vulputate, mi tellus dapibus lorem, vitae vehicula diam mauris placerat diam. Morbi sit amet pretium turpis, et consequat ligula. Nulla velit sem, suscipit sit amet dictum non, tincidunt sed nulla. Aenean pellentesque odio porttitor sagittis aliquam. Name various at metus vitae vulputate. Praesent faucibus nibh lorem, eu pretium dolor dictum nec. Phasellus eget dui laoreet, viverra magna vitae, pellentesque diam.",
            width=700,
            height=100,
        ),
    )


ft.run(main)

custom-styles

Pre-defined theme text styles#

import flet as ft


def main(page: ft.Page):
    page.title = "Text theme styles"
    page.scroll = ft.ScrollMode.ADAPTIVE

    page.add(
        ft.Text("Display Large", theme_style=ft.TextThemeStyle.DISPLAY_LARGE),
        ft.Text("Display Medium", theme_style=ft.TextThemeStyle.DISPLAY_MEDIUM),
        ft.Text("Display Small", theme_style=ft.TextThemeStyle.DISPLAY_SMALL),
        ft.Text("Headline Large", theme_style=ft.TextThemeStyle.HEADLINE_LARGE),
        ft.Text("Headline Medium", theme_style=ft.TextThemeStyle.HEADLINE_MEDIUM),
        ft.Text("Headline Small", theme_style=ft.TextThemeStyle.HEADLINE_SMALL),
        ft.Text("Title Large", theme_style=ft.TextThemeStyle.TITLE_LARGE),
        ft.Text("Title Medium", theme_style=ft.TextThemeStyle.TITLE_MEDIUM),
        ft.Text("Title Small", theme_style=ft.TextThemeStyle.TITLE_SMALL),
        ft.Text("Label Large", theme_style=ft.TextThemeStyle.LABEL_LARGE),
        ft.Text("Label Medium", theme_style=ft.TextThemeStyle.LABEL_MEDIUM),
        ft.Text("Label Small", theme_style=ft.TextThemeStyle.LABEL_SMALL),
        ft.Text("Body Large", theme_style=ft.TextThemeStyle.BODY_LARGE),
        ft.Text("Body Medium", theme_style=ft.TextThemeStyle.BODY_MEDIUM),
        ft.Text("Body Small", theme_style=ft.TextThemeStyle.BODY_SMALL),
    )


ft.run(main)

text-theme-styles

Font with variable weight#

import flet as ft


def main(page: ft.Page):
    page.fonts = {
        "RobotoSlab": "https://github.com/google/fonts/raw/main/apache/robotoslab/RobotoSlab%5Bwght%5D.ttf"
    }

    def handle_slider_change(e):
        text.weight = f"w{int(e.control.value)}"  # noqa
        text.update()

    page.add(
        text := ft.Text(
            "This is rendered with Roboto Slab",
            size=30,
            font_family="RobotoSlab",
            weight=ft.FontWeight.W_100,
        ),
        ft.Slider(
            min=100,
            max=900,
            divisions=8,
            label="Weight = {value}",
            width=500,
            on_change=handle_slider_change,
        ),
    )


ft.run(main)

variable-font-weight

Basic rich text example#

import flet as ft


def main(page: ft.Page):
    page.add(
        ft.Text("Plain text with default style"),
        ft.Text("Selectable plain text with default style", selectable=True),
        ft.Text(
            value="Some text",
            selectable=True,
            size=30,
            spans=[
                ft.TextSpan(
                    text="here goes italic",
                    style=ft.TextStyle(italic=True, size=20, color=ft.Colors.GREEN),
                    spans=[
                        ft.TextSpan(
                            text="bold and italic",
                            style=ft.TextStyle(weight=ft.FontWeight.BOLD),
                        ),
                        ft.TextSpan(
                            text="just italic",
                            spans=[
                                ft.TextSpan("smaller italic", ft.TextStyle(size=15))
                            ],
                        ),
                    ],
                )
            ],
        ),
        ft.Text(
            disabled=False,
            spans=[
                ft.TextSpan(
                    text="underlined and clickable",
                    style=ft.TextStyle(decoration=ft.TextDecoration.UNDERLINE),
                    on_click=lambda e: print(f"Clicked span: {e.control.uid}"),
                    on_enter=lambda e: print(f"Entered span: {e.control.uid}"),
                    on_exit=lambda e: print(f"Exited span: {e.control.uid}"),
                ),
                ft.TextSpan(text=" "),
                ft.TextSpan(
                    text="underlined red wavy",
                    style=ft.TextStyle(
                        decoration=ft.TextDecoration.UNDERLINE,
                        decoration_color=ft.Colors.RED,
                        decoration_style=ft.TextDecorationStyle.WAVY,
                    ),
                    on_enter=lambda e: print(f"Entered span: {e.control.uid}"),
                    on_exit=lambda e: print(f"Exited span: {e.control.uid}"),
                ),
                ft.TextSpan(text=" "),
                ft.TextSpan(
                    text="overlined blue",
                    style=ft.TextStyle(
                        decoration=ft.TextDecoration.OVERLINE, decoration_color="blue"
                    ),
                ),
                ft.TextSpan(text=" "),
                ft.TextSpan(
                    text="overlined and underlined",
                    style=ft.TextStyle(
                        decoration=ft.TextDecoration.OVERLINE
                        | ft.TextDecoration.UNDERLINE
                    ),
                ),
                ft.TextSpan(text=" "),
                ft.TextSpan(
                    text="line through thick",
                    style=ft.TextStyle(
                        decoration=ft.TextDecoration.LINE_THROUGH,
                        decoration_thickness=3,
                    ),
                ),
            ],
        ),
    )

    def handle_link_highlight(e: ft.Event[ft.TextSpan]):
        e.control.style.color = ft.Colors.BLUE
        e.control.update()

    def handle_link_unhighlight(e: ft.Event[ft.TextSpan]):
        e.control.style.color = None
        e.control.update()

    page.add(
        ft.Text(
            disabled=False,
            spans=[
                ft.TextSpan(
                    text="Go to Google",
                    style=ft.TextStyle(decoration=ft.TextDecoration.UNDERLINE),
                    url="https://google.com",
                    on_enter=handle_link_highlight,
                    on_exit=handle_link_unhighlight,
                )
            ],
        ),
    )


ft.run(main)

rich-text-basic

Rich text with borders and stroke#

import flet as ft


def main(page: ft.Page):
    page.add(
        ft.Stack(
            controls=[
                ft.Text(
                    spans=[
                        ft.TextSpan(
                            text="Greetings, planet!",
                            style=ft.TextStyle(
                                size=40,
                                weight=ft.FontWeight.BOLD,
                                foreground=ft.Paint(
                                    color=ft.Colors.BLUE_700,
                                    stroke_width=6,
                                    style=ft.PaintingStyle.STROKE,
                                ),
                            ),
                        ),
                    ],
                ),
                ft.Text(
                    spans=[
                        ft.TextSpan(
                            text="Greetings, planet!",
                            style=ft.TextStyle(
                                size=40,
                                weight=ft.FontWeight.BOLD,
                                color=ft.Colors.GREY_300,
                            ),
                        ),
                    ],
                ),
            ]
        )
    )


ft.run(main)

rich-text-border-stroke

Rich text with gradient#

import flet as ft


def main(page: ft.Page):
    page.add(
        ft.Text(
            spans=[
                ft.TextSpan(
                    text="Greetings, planet!",
                    style=ft.TextStyle(
                        size=40,
                        weight=ft.FontWeight.BOLD,
                        foreground=ft.Paint(
                            gradient=ft.PaintLinearGradient(
                                begin=(0, 20),
                                end=(150, 20),
                                colors=[ft.Colors.RED, ft.Colors.YELLOW],
                            )
                        ),
                    ),
                ),
            ],
        )
    )


ft.run(main)

rich-text-gradient

Text #

Bases: ConstrainedControl

Display text.

It consists of two sources combined to produce the final text: value and spans.

animate_offset #

animate_offset: AnimationValue | None = None

Enables implicit animation of the offset property.

More information here.

animate_opacity #

animate_opacity: AnimationValue | None = None

Enables implicit animation of the opacity property.

More information here.

animate_position #

animate_position: AnimationValue | None = None

Enables implicit animation of the positioning properties (left, right, top and bottom).

More information here.

animate_rotation #

animate_rotation: AnimationValue | None = None

Enables implicit animation of the rotate property.

More information here.

animate_scale #

animate_scale: AnimationValue | None = None

Enables implicit animation of the scale property.

More information here.

animate_size #

animate_size: AnimationValue | None = None

TBD

aspect_ratio #

aspect_ratio: Number | None = None

TBD

badge #

badge: BadgeValue | None = None

A badge to show on top of this control.

bgcolor #

bgcolor: ColorValue | None = None

The text's background color.

bottom #

bottom: Number | None = None

The distance that the child's bottom edge is inset from the bottom of the stack.

Note

Effective only if this control is a descendant of one of the following: Stack control, Page.overlay list.

col #

col: ResponsiveNumber = 12

If a parent of this control is a ResponsiveRow, this property is used to determine how many virtual columns of a screen this control will span.

Can be a number or a dictionary configured to have a different value for specific breakpoints, for example col={"sm": 6}.

This control spans the 12 virtual columns by default.

Dimensions
Breakpoint Dimension
xs <576px
sm ≥576px
md ≥768px
lg ≥992px
xl ≥1200px
xxl ≥1400px

color #

color: ColorValue | None = None

The text's foreground color.

data #

data: Any = skip_field()

Arbitrary data of any type.

disabled #

disabled: bool = False

Every control has disabled property which is False by default - control and all its children are enabled.

Note

The value of this property will be propagated down to all children controls recursively.

Example

For example, if you have a form with multiple entry controls you can disable them all together by disabling container:

ft.Column(
    disabled = True,
    controls=[
        ft.TextField(),
        ft.TextField()
    ]
)

enable_interactive_selection #

enable_interactive_selection: bool = True

Whether to enable user interface affordances for changing the text selection.

For example, setting this to True will enable features such as long-pressing to select text and show the cut/copy/paste menu, and tapping to move the text caret. On the other hand, when this is False, the text selection cannot be adjusted by the user, text cannot be copied.

Note

Has effect only when selectable is True.

expand #

expand: bool | int | None = None

Specifies whether/how this control should expand to fill available space in its parent layout.

More information here.

Note

Has effect only if the direct parent of this control is one of the following controls, or their subclasses: Column, Row, View, Page.

expand_loose #

expand_loose: bool = False

Allows the control to expand along the main axis if space is available, but does not require it to fill all available space.

More information here.

Note

If expand_loose is True, it will have effect only if:

  • expand is not None and
  • the direct parent of this control is one of the following controls, or their subclasses: Column, Row, View, Page.

font_family #

font_family: str | None = None

System or custom font family to render text with. See Fonts cookbook guide for instructions on how to import and use custom fonts in your application.

height #

height: Number | None = None

Imposed Control height in virtual pixels.

italic #

italic: bool = False

Whether to use italic typeface.

key #

key: (
    str | int | float | bool | ValueKey | ScrollKey | None
) = None

left #

left: Number | None = None

The distance that the child's left edge is inset from the left of the stack.

Note

Effective only if this control is a descendant of one of the following: Stack control, Page.overlay list.

max_lines #

max_lines: int | None = None

An optional maximum number of lines for the text to span, wrapping if necessary.

If the text exceeds the given number of lines, it will be truncated according to overflow.

If this is 1, text will not wrap. Otherwise, text will be wrapped at the edge of the box.

no_wrap #

no_wrap: bool | None = None

If False (default) the text should break at soft line breaks.

If True, the glyphs in the text will be positioned as if there was unlimited horizontal space.

Defaults to False.

offset #

offset: OffsetValue | None = None

Applies a translation transformation before painting the control.

The translation is expressed as an Offset scaled to the control's size. So, Offset(x=0.25, y=0), for example, will result in a horizontal translation of one quarter the width of this control.

Example

The following example displays container at 0, 0 top left corner of a stack as transform applies -1 * 100, -1 * 100 (offset * control's size) horizontal and vertical translations to the control:

import flet as ft

def main(page: ft.Page):
    page.add(
        ft.Stack(
            width=1000,
            height=1000,
            controls=[
                ft.Container(
                    bgcolor="red",
                    width=100,
                    height=100,
                    left=100,
                    top=100,
                    offset=ft.Offset(-1, -1),
                )
            ],
        )
    )

ft.run(main)

on_animation_end #

on_animation_end: (
    ControlEventHandler[ConstrainedControl] | None
) = None

Called when animation completes.

Can be used to chain multiple animations.

The data property of the event handler argument contains the name of the animation.

More information here.

on_selection_change #

on_selection_change: (
    EventHandler[TextSelectionChangeEvent[Text]] | None
) = None

Called when the user changes the selection of text (including the cursor location).

Note

Has effect only when selectable is True.

on_tap #

on_tap: ControlEventHandler[Text] | None = None

Called when the user taps on this selectable text.

Note

Has effect only when selectable is True.

opacity #

opacity: Number = 1.0

Defines the transparency of the control.

Value ranges from 0.0 (completely transparent) to 1.0 (completely opaque without any transparency).

overflow #

overflow: TextOverflow = CLIP

Defines how the text overflows.

page #

page: Page | PageView | None

The page (of type Page or PageView) to which this control belongs to.

parent #

parent: BaseControl | None

The direct ancestor(parent) of this control.

It defaults to None and will only have a value when this control is mounted (added to the page tree).

The Page control (which is the root of the tree) is an exception - it always has parent=None.

right #

right: Number | None = None

The distance that the child's right edge is inset from the right of the stack.

Note

Effective only if this control is a descendant of one of the following: Stack control, Page.overlay list.

rotate #

rotate: RotateValue | None = None

Transforms this control using a rotation around its center.

The value of rotate property could be one of the following types:

  • number - a rotation in clockwise radians. Full circle 360° is math.pi * 2 radians, 90° is pi / 2, 45° is pi / 4, etc.
  • Rotate - allows to specify rotation angle as well as alignment - the location of rotation center.
Example

For example:

ft.Image(
    src="https://picsum.photos/100/100",
    width=100,
    height=100,
    border_radius=5,
    rotate=Rotate(angle=0.25 * pi, alignment=ft.Alignment.CENTER_LEFT)
)

rtl #

rtl: bool = False

Whether the text direction of the control should be right-to-left (RTL).

scale #

scale: ScaleValue | None = None

Scales this control along the 2D plane. Default scale factor is 1.0, meaning no-scale.

Setting this property to 0.5, for example, makes this control twice smaller, while 2.0 makes it twice larger.

Different scale multipliers can be specified for x and y axis, by setting Control.scale property to an instance of Scale class. Either scale or scale_x and scale_y could be specified, but not all of them.

Example
ft.Image(
    src="https://picsum.photos/100/100",
    width=100,
    height=100,
    border_radius=5,
    scale=ft.Scale(scale_x=2, scale_y=0.5)
)

selectable #

selectable: bool | None = None

Whether the text should be selectable.

Defaults to False.

selection_cursor_color #

selection_cursor_color: ColorValue | None = None

The color of the cursor.

The cursor indicates the current text insertion point.

selection_cursor_height #

selection_cursor_height: Number | None = None

Defines how tall the cursor should be.

selection_cursor_width #

selection_cursor_width: Number = 2.0

Defines how thick the cursor should be.

The cursor will be drawn under the text. The cursor width will extend to the right of the boundary between characters for left-to-right text and to the left for right-to-left text. This corresponds to extending downstream relative to the selected position. Negative values may be used to reverse this behavior.

Note

Has effect only when selectable is True.

semantics_label #

semantics_label: str | None = None

An alternative semantics label for this text.

If present, the semantics of this control will contain this value instead of the actual text. This will overwrite any of the TextSpan.semantics_labels.

This is useful for replacing abbreviations or shorthands with the full text value:

Example
ft.Text("$$", semantics_label="Double dollars")

show_selection_cursor #

show_selection_cursor: bool = False

Whether to show cursor (blinking caret) when the text is selected.

Note

Has effect only when selectable is True.

size #

size: Number | None = None

Text size in virtual pixels.

Defaults to 14.

spans #

spans: list[TextSpan] | None = None

The list of TextSpan objects to build a rich text paragraph.

style #

style: TextStyle | None = None

The text's style.

text_align #

text_align: TextAlign = START

Text horizontal align.

theme_style #

theme_style: TextThemeStyle | None = None

Pre-defined text style.

tooltip #

tooltip: TooltipValue | None = None

The tooltip ot show when this control is hovered over.

top #

top: Number | None = None

The distance that the child's top edge is inset from the top of the stack.

Note

Effective only if this control is a descendant of one of the following: Stack control, Page.overlay list.

value #

value: str = ''

The text displayed.

visible #

visible: bool = True

Every control has visible property which is True by default - control is rendered on the page. Setting visible to False completely prevents control (and all its children if any) from rendering on a page canvas. Hidden controls cannot be focused or selected with a keyboard or mouse and they do not emit any events.

weight #

weight: FontWeight | None = None

Font weight.

Defaults to FontWeight.NORMAL.

width #

width: Number | None = None

Imposed Control width in virtual pixels.

before_event #

before_event(e: ControlEvent)

before_update #

before_update()

clean #

clean() -> None

did_mount #

did_mount()

init #

init()

is_isolated #

is_isolated()

update #

update() -> None

will_unmount #

will_unmount()