CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-flet

Flet is a rich User Interface framework to quickly build interactive web, desktop and mobile apps in Python without prior knowledge of web technologies.

Pending
Overview
Eval results
Files

theming-styling.mddocs/

Theming and Styling

This document covers Flet's comprehensive theming and styling system, including themes, colors, typography, and visual effects for creating beautiful, consistent user interfaces.

Import

import flet as ft

Core Theming

Theme

class Theme(Control):
    """Application theme configuration."""
    
    def __init__(
        self,
        color_scheme_seed: str = None,
        color_scheme: ColorScheme = None,
        text_theme: TextTheme = None,
        primary_swatch: str = None,
        primary_color: str = None,
        primary_color_dark: str = None,
        primary_color_light: str = None,
        accent_color: str = None,
        canvas_color: str = None,
        card_color: str = None,
        dialog_background_color: str = None,
        disabled_color: str = None,
        divider_color: str = None,
        focus_color: str = None,
        highlight_color: str = None,
        hint_color: str = None,
        hover_color: str = None,
        indicator_color: str = None,
        secondary_header_color: str = None,
        selected_row_color: str = None,
        splash_color: str = None,
        unselected_widget_color: str = None,
        font_family: str = None,
        use_material3: bool = True,
        visual_density: VisualDensity = None,
        page_transitions: PageTransitionsTheme = None,
        scrollbar_theme: ScrollbarTheme = None,
        tabs_theme: TabsTheme = None,
        tooltip_theme: TooltipTheme = None,
        banner_theme: BannerTheme = None,
        bottom_app_bar_theme: BottomAppBarTheme = None,
        bottom_navigation_bar_theme: BottomNavigationBarTheme = None,
        bottom_sheet_theme: BottomSheetTheme = None,
        button_theme: ButtonTheme = None,
        card_theme: CardTheme = None,
        checkbox_theme: CheckboxTheme = None,
        chip_theme: ChipTheme = None,
        data_table_theme: DataTableTheme = None,
        dialog_theme: DialogTheme = None,
        divider_theme: DividerTheme = None,
        elevated_button_theme: ElevatedButtonTheme = None,
        floating_action_button_theme: FloatingActionButtonTheme = None,
        list_tile_theme: ListTileTheme = None,
        navigation_bar_theme: NavigationBarTheme = None,
        navigation_rail_theme: NavigationRailTheme = None,
        outlined_button_theme: OutlinedButtonTheme = None,
        popup_menu_theme: PopupMenuTheme = None,
        progress_indicator_theme: ProgressIndicatorTheme = None,
        radio_theme: RadioTheme = None,
        slider_theme: SliderTheme = None,
        snack_bar_theme: SnackBarTheme = None,
        switch_theme: SwitchTheme = None,
        text_button_theme: TextButtonTheme = None,
        **kwargs
    )

Key Parameters:

  • color_scheme_seed (str, optional): Seed color for Material 3 color scheme generation
  • color_scheme (ColorScheme, optional): Custom color scheme
  • text_theme (TextTheme, optional): Typography theme
  • use_material3 (bool, optional): Use Material Design 3 (default: True)
  • font_family (str, optional): Default font family
  • Component themes for customizing individual control appearance

Example:

page.theme = ft.Theme(
    color_scheme_seed=ft.colors.GREEN,
    use_material3=True
)

# Or with custom color scheme
page.theme = ft.Theme(
    color_scheme=ft.ColorScheme(
        primary=ft.colors.BLUE,
        secondary=ft.colors.GREEN,
        background=ft.colors.WHITE,
        surface=ft.colors.GREY_50
    )
)
page.update()

ColorScheme

class ColorScheme(Control):
    """Color scheme definition for theming."""
    
    def __init__(
        self,
        brightness: Brightness = None,
        primary: str = None,
        on_primary: str = None,
        primary_container: str = None,
        on_primary_container: str = None,
        primary_fixed: str = None,
        primary_fixed_dim: str = None,
        on_primary_fixed: str = None,
        on_primary_fixed_variant: str = None,
        secondary: str = None,
        on_secondary: str = None,
        secondary_container: str = None,
        on_secondary_container: str = None,
        secondary_fixed: str = None,
        secondary_fixed_dim: str = None,
        on_secondary_fixed: str = None,
        on_secondary_fixed_variant: str = None,
        tertiary: str = None,
        on_tertiary: str = None,
        tertiary_container: str = None,
        on_tertiary_container: str = None,
        tertiary_fixed: str = None,
        tertiary_fixed_dim: str = None,
        on_tertiary_fixed: str = None,
        on_tertiary_fixed_variant: str = None,
        error: str = None,
        on_error: str = None,
        error_container: str = None,
        on_error_container: str = None,
        surface_dim: str = None,
        surface: str = None,
        surface_bright: str = None,
        surface_container_lowest: str = None,
        surface_container_low: str = None,
        surface_container: str = None,
        surface_container_high: str = None,
        surface_container_highest: str = None,
        on_surface: str = None,
        on_surface_variant: str = None,
        outline: str = None,
        outline_variant: str = None,
        shadow: str = None,
        scrim: str = None,
        inverse_surface: str = None,
        on_inverse_surface: str = None,
        inverse_primary: str = None,
        surface_tint: str = None,
        **kwargs
    )

Key Color Roles:

  • primary (str, optional): Primary brand color
  • secondary (str, optional): Secondary accent color
  • tertiary (str, optional): Tertiary accent color
  • error (str, optional): Error state color
  • surface (str, optional): Background surface color
  • on_primary (str, optional): Text/icon color on primary background
  • outline (str, optional): Border and outline color

TextTheme

class TextTheme(Control):
    """Typography theme configuration."""
    
    def __init__(
        self,
        display_large: TextStyle = None,
        display_medium: TextStyle = None,
        display_small: TextStyle = None,
        headline_large: TextStyle = None,
        headline_medium: TextStyle = None,
        headline_small: TextStyle = None,
        title_large: TextStyle = None,
        title_medium: TextStyle = None,
        title_small: TextStyle = None,
        label_large: TextStyle = None,
        label_medium: TextStyle = None,
        label_small: TextStyle = None,
        body_large: TextStyle = None,
        body_medium: TextStyle = None,
        body_small: TextStyle = None,
        **kwargs
    )

Typography Scale:

  • display_* - Largest text, for hero sections
  • headline_* - High-emphasis headers
  • title_* - Medium-emphasis headers
  • body_* - Body text content
  • label_* - Small text for labels and captions

ThemeMode

class ThemeMode(Enum):
    """Theme mode options."""
    SYSTEM = "system"  # Follow system theme
    LIGHT = "light"    # Light theme
    DARK = "dark"      # Dark theme

Example:

page.theme_mode = ft.ThemeMode.DARK
page.update()

Colors

Colors

class Colors:
    """Material Design color constants."""
    
    # Primary colors
    RED = "red"
    PINK = "pink"
    PURPLE = "purple"
    DEEP_PURPLE = "deeppurple"
    INDIGO = "indigo"
    BLUE = "blue"
    LIGHT_BLUE = "lightblue"
    CYAN = "cyan"
    TEAL = "teal"
    GREEN = "green"
    LIGHT_GREEN = "lightgreen"
    LIME = "lime"
    YELLOW = "yellow"
    AMBER = "amber"
    ORANGE = "orange"
    DEEP_ORANGE = "deeporange"
    BROWN = "brown"
    GREY = "grey"
    BLUE_GREY = "bluegrey"
    
    # Shades (50-900)
    RED_50 = "red50"
    RED_100 = "red100"
    # ... continuing through RED_900
    
    # Surface colors
    BACKGROUND = "background"
    SURFACE = "surface"
    SURFACE_VARIANT = "surfacevariant"
    ON_BACKGROUND = "onbackground"
    ON_SURFACE = "onsurface"
    ON_SURFACE_VARIANT = "onsurfacevariant"
    
    # Semantic colors
    PRIMARY = "primary"
    ON_PRIMARY = "onprimary"
    PRIMARY_CONTAINER = "primarycontainer"
    ON_PRIMARY_CONTAINER = "onprimarycontainer"
    SECONDARY = "secondary"
    ON_SECONDARY = "onsecondary"
    ERROR = "error"
    ON_ERROR = "onerror"
    
    # Special colors
    TRANSPARENT = "transparent"
    WHITE = "white"
    BLACK = "black"

CupertinoColors

class CupertinoColors:
    """iOS-style color constants."""
    
    SYSTEM_BLUE = "systemblue"
    SYSTEM_GREEN = "systemgreen"
    SYSTEM_INDIGO = "systemindigo"
    SYSTEM_ORANGE = "systemorange"
    SYSTEM_PINK = "systempink"
    SYSTEM_PURPLE = "systempurple"
    SYSTEM_RED = "systemred"
    SYSTEM_TEAL = "systemteal"
    SYSTEM_YELLOW = "systemyellow"
    SYSTEM_GREY = "systemgrey"
    SYSTEM_GREY2 = "systemgrey2"
    SYSTEM_GREY3 = "systemgrey3"
    SYSTEM_GREY4 = "systemgrey4"
    SYSTEM_GREY5 = "systemgrey5"
    SYSTEM_GREY6 = "systemgrey6"
    
    # Background colors
    SYSTEM_BACKGROUND = "systembackground"
    SECONDARY_SYSTEM_BACKGROUND = "secondarysystembackground"
    TERTIARY_SYSTEM_BACKGROUND = "tertiarysystembackground"
    
    # Label colors
    LABEL = "label"
    SECONDARY_LABEL = "secondarylabel"
    TERTIARY_LABEL = "tertiarylabel"
    QUATERNARY_LABEL = "quaternarylabel"

Color Utilities

def colors.with_opacity(opacity: float, color: str) -> str:
    """Create color with specified opacity."""
    # Returns color with alpha channel

# Usage examples:
semi_transparent_blue = ft.colors.with_opacity(0.5, ft.colors.BLUE)
fade_red = ft.colors.with_opacity(0.3, ft.colors.RED)

Visual Styling

TextStyle

class TextStyle(Control):
    """Text styling configuration."""
    
    def __init__(
        self,
        size: float = None,
        weight: FontWeight = None,
        italic: bool = None,
        color: str = None,
        bgcolor: str = None,
        decoration: TextDecoration = None,
        decoration_color: str = None,
        decoration_style: TextDecorationStyle = None,
        decoration_thickness: float = None,
        font_family: str = None,
        font_family_fallback: List[str] = None,
        letter_spacing: float = None,
        word_spacing: float = None,
        height: float = None,
        baseline: TextBaseline = None,
        foreground: Paint = None,
        background: Paint = None,
        shadow: List[BoxShadow] = None,
        **kwargs
    )

Parameters:

  • size (float, optional): Font size in logical pixels
  • weight (FontWeight, optional): Font weight (NORMAL, BOLD, W100-W900)
  • italic (bool, optional): Italic style
  • color (str, optional): Text color
  • decoration (TextDecoration, optional): Text decoration (UNDERLINE, OVERLINE, LINE_THROUGH)
  • font_family (str, optional): Font family name
  • letter_spacing (float, optional): Character spacing
  • shadow (List[BoxShadow], optional): Text shadows

Example:

ft.Text(
    "Styled Text",
    style=ft.TextStyle(
        size=24,
        weight=ft.FontWeight.BOLD,
        color=ft.colors.BLUE,
        decoration=ft.TextDecoration.UNDERLINE,
        font_family="Arial",
        letter_spacing=2
    )
)

ButtonStyle

class ButtonStyle(Control):
    """Button styling configuration."""
    
    def __init__(
        self,
        color: ControlStateProperty = None,
        bgcolor: ControlStateProperty = None,
        overlay_color: ControlStateProperty = None,
        shadow_color: ControlStateProperty = None,
        surface_tint_color: ControlStateProperty = None,
        elevation: ControlStateProperty = None,
        animation_duration: int = None,
        padding: ControlStateProperty = None,
        side: ControlStateProperty = None,
        shape: ControlStateProperty = None,
        text_style: ControlStateProperty = None,
        icon_color: ControlStateProperty = None,
        icon_size: ControlStateProperty = None,
        **kwargs
    )

Parameters:

  • Properties can be state-dependent using ControlStateProperty
  • States: DEFAULT, HOVERED, FOCUSED, PRESSED, DRAGGED, SELECTED, SCROLLED_UNDER, DISABLED

Example:

ft.ElevatedButton(
    "Custom Button",
    style=ft.ButtonStyle(
        color=ft.colors.WHITE,
        bgcolor=ft.colors.BLUE,
        elevation=8,
        padding=ft.padding.symmetric(horizontal=20, vertical=10),
        shape=ft.RoundedRectangleBorder(radius=20)
    )
)

Border and BorderSide

class BorderSide(Control):
    """Border side styling."""
    
    def __init__(
        self,
        width: float = None,
        color: str = None,
        stroke_align: float = None,
        **kwargs
    )

class Border(Control):
    """Border styling for all sides."""
    
    def __init__(
        self,
        top: BorderSide = None,
        right: BorderSide = None,
        bottom: BorderSide = None,
        left: BorderSide = None,
        **kwargs
    )
    
    @staticmethod
    def all(width: float = None, color: str = None) -> "Border":
        """Create border on all sides."""
    
    @staticmethod
    def symmetric(vertical: BorderSide = None, horizontal: BorderSide = None) -> "Border":
        """Create symmetric borders."""

Example:

ft.Container(
    content=ft.Text("Bordered content"),
    border=ft.border.all(2, ft.colors.BLUE),
    padding=20
)

BorderRadius

class BorderRadius(Control):
    """Border radius styling."""
    
    def __init__(
        self,
        top_left: float = None,
        top_right: float = None,
        bottom_left: float = None,
        bottom_right: float = None,
        **kwargs
    )
    
    @staticmethod
    def all(radius: float) -> "BorderRadius":
        """Uniform radius on all corners."""
    
    @staticmethod
    def circular(radius: float) -> "BorderRadius":
        """Circular border radius."""
    
    @staticmethod
    def horizontal(left: float = None, right: float = None) -> "BorderRadius":
        """Horizontal border radius."""
    
    @staticmethod
    def vertical(top: float = None, bottom: float = None) -> "BorderRadius":
        """Vertical border radius."""
    
    @staticmethod
    def only(
        top_left: float = None,
        top_right: float = None,
        bottom_left: float = None,
        bottom_right: float = None
    ) -> "BorderRadius":
        """Specific corner radius."""

BoxDecoration

class BoxDecoration(Control):
    """Box decoration with background, border, shadows, and gradients."""
    
    def __init__(
        self,
        color: str = None,
        image: DecorationImage = None,
        border: Border = None,
        border_radius: BorderRadiusValue = None,
        box_shadow: List[BoxShadow] = None,
        gradient: Gradient = None,
        blend_mode: BlendMode = None,
        shape: BoxShape = None,
        **kwargs
    )

BoxShadow

class BoxShadow(Control):
    """Box shadow effect."""
    
    def __init__(
        self,
        spread_radius: float = None,
        blur_radius: float = None,
        color: str = None,
        offset: OffsetValue = None,
        blur_style: ShadowBlurStyle = None,
        **kwargs
    )

Example:

ft.Container(
    content=ft.Text("Shadow container"),
    padding=20,
    decoration=ft.BoxDecoration(
        color=ft.colors.WHITE,
        border_radius=10,
        box_shadow=[
            ft.BoxShadow(
                spread_radius=1,
                blur_radius=15,
                color=ft.colors.BLUE_GREY_300,
                offset=ft.Offset(0, 0),
            )
        ]
    )
)

Gradients and Effects

LinearGradient

class LinearGradient(Control):
    """Linear gradient effect."""
    
    def __init__(
        self,
        begin: AlignmentValue = None,
        end: AlignmentValue = None,
        colors: List[str] = None,
        stops: List[float] = None,
        tile_mode: GradientTileMode = None,
        rotation: float = None,
        **kwargs
    )

Parameters:

  • begin (AlignmentValue, optional): Gradient start alignment
  • end (AlignmentValue, optional): Gradient end alignment
  • colors (List[str], optional): List of gradient colors
  • stops (List[float], optional): Color stop positions (0.0-1.0)
  • rotation (float, optional): Gradient rotation in radians

RadialGradient

class RadialGradient(Control):
    """Radial gradient effect."""
    
    def __init__(
        self,
        center: AlignmentValue = None,
        radius: float = None,
        colors: List[str] = None,
        stops: List[float] = None,
        tile_mode: GradientTileMode = None,
        focal: AlignmentValue = None,
        focal_radius: float = None,
        **kwargs
    )

SweepGradient

class SweepGradient(Control):
    """Sweep (conical) gradient effect."""
    
    def __init__(
        self,
        center: AlignmentValue = None,
        start_angle: float = None,
        end_angle: float = None,
        colors: List[str] = None,
        stops: List[float] = None,
        tile_mode: GradientTileMode = None,
        **kwargs
    )

Example:

ft.Container(
    width=200,
    height=200,
    gradient=ft.LinearGradient(
        begin=ft.alignment.top_center,
        end=ft.alignment.bottom_center,
        colors=[
            ft.colors.BLUE,
            ft.colors.BLUE_400,
            ft.colors.BLUE_100,
        ],
        stops=[0.1, 0.5, 0.9]
    )
)

Blur

class Blur(Control):
    """Blur effect."""
    
    def __init__(
        self,
        sigma_x: float = None,
        sigma_y: float = None,
        tile_mode: BlurTileMode = None,
        **kwargs
    )

ShaderMask

class ShaderMask(Control):
    """Shader mask effect for gradient text and icons."""
    
    def __init__(
        self,
        content: Control = None,
        shader: Gradient = None,
        blend_mode: BlendMode = None,
        **kwargs
    )

Example:

ft.ShaderMask(
    content=ft.Text(
        "Gradient Text",
        size=40,
        weight=ft.FontWeight.BOLD
    ),
    shader=ft.LinearGradient(
        colors=[ft.colors.PURPLE, ft.colors.BLUE, ft.colors.RED],
        begin=ft.alignment.top_left,
        end=ft.alignment.bottom_right
    ),
    blend_mode=ft.BlendMode.SRC_IN
)

Component Theming

ButtonTheme

class ButtonTheme(Control):
    """Global button theming."""
    
    def __init__(
        self,
        alignment_geometry: AlignmentGeometry = None,
        bar_height: float = None,
        button_color: str = None,
        color_scheme: ColorScheme = None,
        disabled_color: str = None,
        focus_color: str = None,
        height: float = None,
        highlight_color: str = None,
        hover_color: str = None,
        layout_behavior: ButtonBarLayoutBehavior = None,
        material_tap_target_size: MaterialTapTargetSize = None,
        min_width: float = None,
        padding: PaddingValue = None,
        shape: OutlinedBorder = None,
        splash_color: str = None,
        text_theme: ButtonTextTheme = None,
        **kwargs
    )

ElevatedButtonTheme

class ElevatedButtonTheme(Control):
    """Elevated button specific theming."""
    
    def __init__(
        self,
        style: ButtonStyle = None,
        **kwargs
    )

TextButtonTheme

class TextButtonTheme(Control):
    """Text button specific theming."""
    
    def __init__(
        self,
        style: ButtonStyle = None,
        **kwargs
    )

CheckboxTheme

class CheckboxTheme(Control):
    """Checkbox theming."""
    
    def __init__(
        self,
        fill_color: ControlStateProperty = None,
        check_color: ControlStateProperty = None,
        overlay_color: ControlStateProperty = None,
        splash_radius: float = None,
        material_tap_target_size: MaterialTapTargetSize = None,
        visual_density: VisualDensity = None,
        shape: OutlinedBorder = None,
        side: ControlStateProperty = None,
        **kwargs
    )

Layout and Spacing

Padding

class Padding(Control):
    """Padding specification."""
    
    def __init__(
        self,
        left: float = None,
        top: float = None,
        right: float = None,
        bottom: float = None,
        **kwargs
    )
    
    @staticmethod
    def all(value: float) -> "Padding":
        """Uniform padding on all sides."""
    
    @staticmethod
    def symmetric(vertical: float = None, horizontal: float = None) -> "Padding":
        """Symmetric padding."""
    
    @staticmethod
    def only(left: float = None, top: float = None, right: float = None, bottom: float = None) -> "Padding":
        """Specific side padding."""

Margin

class Margin(Control):
    """Margin specification (same API as Padding)."""
    pass

Alignment

class Alignment(Control):
    """Alignment specification."""
    
    def __init__(
        self,
        x: float,
        y: float,
        **kwargs
    )
    
    # Predefined alignments
    top_left = Alignment(-1, -1)
    top_center = Alignment(0, -1)
    top_right = Alignment(1, -1)
    center_left = Alignment(-1, 0)
    center = Alignment(0, 0)
    center_right = Alignment(1, 0)
    bottom_left = Alignment(-1, 1)
    bottom_center = Alignment(0, 1)
    bottom_right = Alignment(1, 1)

Animation and Transforms

Animation

class Animation(Control):
    """Animation configuration."""
    
    def __init__(
        self,
        duration: int = None,
        curve: AnimationCurve = None,
        **kwargs
    )

AnimationCurve

class AnimationCurve(Enum):
    """Animation curve types."""
    LINEAR = "linear"
    EASE = "ease"
    EASE_IN = "easeIn"
    EASE_OUT = "easeOut"
    EASE_IN_OUT = "easeInOut"
    BOUNCE_IN = "bounceIn"
    BOUNCE_OUT = "bounceOut"
    ELASTIC_IN = "elasticIn"
    ELASTIC_OUT = "elasticOut"

Transform

class Rotate(Control):
    """Rotation transform."""
    
    def __init__(
        self,
        angle: float,
        alignment: Alignment = None,
        **kwargs
    )

class Scale(Control):
    """Scale transform."""
    
    def __init__(
        self,
        scale: float = None,
        scale_x: float = None,
        scale_y: float = None,
        alignment: Alignment = None,
        **kwargs
    )

class Offset(Control):
    """Position offset."""
    
    def __init__(
        self,
        x: float,
        y: float,
        **kwargs
    )

Theming Best Practices

Custom App Theme

def create_app_theme():
    return ft.Theme(
        color_scheme_seed=ft.colors.DEEP_PURPLE,
        use_material3=True,
        text_theme=ft.TextTheme(
            body_large=ft.TextStyle(
                font_family="Roboto",
                size=16
            )
        ),
        elevated_button_theme=ft.ElevatedButtonTheme(
            style=ft.ButtonStyle(
                padding=ft.padding.symmetric(horizontal=20, vertical=12),
                shape=ft.RoundedRectangleBorder(radius=8)
            )
        )
    )

# Apply theme
page.theme = create_app_theme()
page.update()

Dark Mode Support

def create_dark_theme():
    return ft.Theme(
        color_scheme=ft.ColorScheme(
            brightness=ft.Brightness.DARK,
            primary=ft.colors.BLUE_200,
            secondary=ft.colors.AMBER_200,
            surface=ft.colors.GREY_900,
            background=ft.colors.BLACK,
            on_primary=ft.colors.BLACK,
            on_surface=ft.colors.WHITE
        )
    )

# Toggle theme mode
def toggle_theme(e):
    page.theme_mode = (
        ft.ThemeMode.DARK 
        if page.theme_mode == ft.ThemeMode.LIGHT 
        else ft.ThemeMode.LIGHT
    )
    page.update()

Component Styling

# Consistent button styling
def create_primary_button(text, on_click):
    return ft.ElevatedButton(
        text,
        style=ft.ButtonStyle(
            bgcolor=ft.colors.PRIMARY,
            color=ft.colors.ON_PRIMARY,
            elevation=4,
            padding=ft.padding.symmetric(horizontal=24, vertical=12),
            shape=ft.RoundedRectangleBorder(radius=8)
        ),
        on_click=on_click
    )

# Styled containers
def create_card(content):
    return ft.Container(
        content=content,
        padding=20,
        border_radius=12,
        bgcolor=ft.colors.SURFACE,
        shadow=ft.BoxShadow(
            spread_radius=1,
            blur_radius=10,
            color=ft.colors.with_opacity(0.1, ft.colors.BLACK)
        )
    )

Responsive Typography

def get_responsive_text_size(base_size, page_width):
    if page_width < 600:
        return base_size * 0.8
    elif page_width < 1200:
        return base_size
    else:
        return base_size * 1.2

# Usage
title_size = get_responsive_text_size(24, page.window_width)
ft.Text(
    "Responsive Title",
    size=title_size,
    weight=ft.FontWeight.BOLD
)

This covers Flet's comprehensive theming and styling system, enabling you to create beautiful, consistent, and professional-looking applications with full control over visual appearance and user experience.

Install with Tessl CLI

npx tessl i tessl/pypi-flet

docs

advanced-features.md

charts-visualization.md

events-interaction.md

index.md

layout-navigation.md

theming-styling.md

ui-controls.md

utilities-platform.md

tile.json