CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-fasthtml

The fastest way to create HTML apps - a next-generation Python web framework for building fast, scalable web applications with minimal code

Pending
Overview
Eval results
Files

css-styling.mddocs/

CSS Framework Integration

Built-in PicoCSS integration with enhanced components and styling utilities for rapid UI development.

Capabilities

PicoCSS Integration

FastHTML includes built-in support for PicoCSS, a minimal CSS framework that provides beautiful default styling with minimal markup.

picocss: str
"""PicoCSS CDN URL for including the framework."""

picolink: list
"""PicoCSS link and style elements for HTML head."""

picocondcss: str
"""PicoCSS conditional CDN URL with dark/light theme support."""

picocondlink: list
"""PicoCSS conditional link elements with theme switching."""

def set_pico_cls():
    """Set PicoCSS classes for Jupyter notebook display."""

Enhanced PicoCSS Components

Pre-built components that leverage PicoCSS styling with additional FastHTML functionality.

def Card(*c, **kw):
    """
    PicoCSS card component.
    
    Creates an article element with header and footer sections,
    styled as a card using PicoCSS classes.
    
    Args:
        *c: Card content (header, body, footer elements)
        **kw: Additional attributes and styling
        
    Returns:
        Article element styled as card
    """

def Group(*c, **kw):
    """
    PicoCSS form group.
    
    Creates a form group container for organizing related
    form elements with proper spacing and alignment.
    
    Args:
        *c: Form elements to group
        **kw: Additional attributes
        
    Returns:
        Div element with form group styling
    """

def Search(*c, **kw):
    """
    PicoCSS search input.
    
    Creates a search input field with PicoCSS styling
    and search-specific attributes.
    
    Args:
        *c: Content (usually none for input)
        **kw: Input attributes (placeholder, name, etc.)
        
    Returns:
        Search input element
    """

def Grid(*c, **kw):
    """
    PicoCSS grid container.
    
    Creates a CSS grid container for responsive layouts
    using PicoCSS grid system.
    
    Args:
        *c: Grid items
        **kw: Grid attributes and styling
        
    Returns:
        Div element with grid styling
    """

def DialogX(*c, **kw):
    """
    Enhanced dialog component.
    
    Creates a modal dialog with PicoCSS styling
    and enhanced functionality.
    
    Args:
        *c: Dialog content
        **kw: Dialog attributes and options
        
    Returns:
        Dialog element with enhanced styling
    """

def Container(*c, **kw):
    """
    PicoCSS container.
    
    Creates a responsive container with proper max-width
    and centering using PicoCSS classes.
    
    Args:
        *c: Container content
        **kw: Container attributes
        
    Returns:
        Div element with container styling
    """

def PicoBusy(*c, **kw):
    """
    PicoCSS busy indicator.
    
    Creates a loading spinner or busy indicator
    using PicoCSS styling.
    
    Args:
        *c: Content (usually none)
        **kw: Styling attributes
        
    Returns:
        Element with busy indicator styling
    """

Style and Script Enhancement

Enhanced style and script elements with additional functionality for CSS and JavaScript management.

def Style(*c, **kw):
    """
    Enhanced style tag.
    
    Creates HTML style element with enhanced functionality
    for CSS management and processing.
    
    Args:
        *c: CSS content
        **kw: Style attributes
        
    Returns:
        Style element with enhanced functionality
    """

def StyleX(*c, **kw):
    """
    Style tag with CSS file loading.
    
    Creates style element that can load CSS from external
    files or include inline styles.
    
    Args:
        *c: CSS content or file references
        **kw: Style attributes and loading options
        
    Returns:
        Style element with file loading capability
    """

def Script(*c, **kw):
    """
    Enhanced script tag.
    
    Creates HTML script element with enhanced functionality
    for JavaScript management.
    
    Args:
        *c: JavaScript content
        **kw: Script attributes (src, type, etc.)
        
    Returns:
        Script element with enhanced functionality
    """

def ScriptX(*c, **kw):
    """
    Script tag with file loading.
    
    Creates script element that can load JavaScript from
    external files or include inline scripts.
    
    Args:
        *c: JavaScript content or file references
        **kw: Script attributes and loading options
        
    Returns:
        Script element with file loading capability
    """

CSS Utility Functions

Utility functions for CSS processing and variable management.

def replace_css_vars(css_str: str, variables: dict) -> str:
    """
    Replace CSS variables in string.
    
    Substitutes CSS custom properties with actual values
    for dynamic styling.
    
    Args:
        css_str: CSS string containing variables
        variables: Dictionary of variable name/value pairs
        
    Returns:
        str: CSS string with variables replaced
    """

def loose_format(template: str, **kwargs) -> str:
    """
    Flexible string formatting for CSS templates.
    
    Args:
        template: String template with placeholders
        **kwargs: Values to substitute
        
    Returns:
        str: Formatted string
    """

def double_braces(s: str) -> str:
    """
    Add double braces to string for template processing.
    
    Args:
        s: String to process
        
    Returns:
        str: String with double braces added
    """

def undouble_braces(s: str) -> str:
    """
    Remove double braces from string.
    
    Args:
        s: String with double braces
        
    Returns:
        str: String with double braces removed
    """

Media Query Utilities

Functions for handling responsive design and theme switching.

def light_media() -> str:
    """
    Light mode media query CSS.
    
    Returns CSS media query for light color scheme preferences.
    
    Returns:
        str: CSS media query for light mode
    """

def dark_media() -> str:
    """
    Dark mode media query CSS.
    
    Returns CSS media query for dark color scheme preferences.
    
    Returns:
        str: CSS media query for dark mode
    """

Usage Examples

Basic PicoCSS Integration

from fasthtml.common import *

app, rt = fast_app(pico=True)  # Enable PicoCSS

@rt('/')
def homepage():
    return Html(
        Head(
            Title("PicoCSS Demo"),
            Meta(charset="utf-8"),
            Meta(name="viewport", content="width=device-width, initial-scale=1"),
            *picolink  # Include PicoCSS stylesheets
        ),
        Body(
            Container(
                H1("PicoCSS with FastHTML"),
                P("This page uses PicoCSS for beautiful default styling."),
                
                # PicoCSS automatically styles these elements
                Button("Primary Button", cls="primary"),
                Button("Secondary Button", cls="secondary"),
                Button("Contrast Button", cls="contrast"),
                
                # Form with PicoCSS styling
                Form(
                    Group(
                        Label("Name:", for_="name"),
                        Input(type="text", name="name", placeholder="Enter your name")
                    ),
                    Group(
                        Label("Email:", for_="email"),
                        Input(type="email", name="email", placeholder="Enter your email")
                    ),
                    Button("Submit", type="submit")
                )
            )
        )
    )

Card Components and Layouts

from fasthtml.common import *

app, rt = fast_app(pico=True)

@rt('/cards')
def card_demo():
    return Titled("Card Components",
        Container(
            H1("PicoCSS Card Examples"),
            
            Grid(
                # Basic card
                Card(
                    Header(H3("Basic Card")),
                    P("This is a basic card with header and content."),
                    Footer(Small("Card footer"))
                ),
                
                # Card with image
                Card(
                    Header(
                        Img(src="https://picsum.photos/300/150", alt="Card image")
                    ),
                    H4("Image Card"),
                    P("A card with an image header."),
                    Footer(
                        Button("Action", cls="secondary")
                    )
                ),
                
                # Feature card
                Card(
                    Header(
                        H3("Feature Card"),
                        P("Premium feature", cls="badge")
                    ),
                    Ul(
                        Li("Feature one"),
                        Li("Feature two"),
                        Li("Feature three")
                    ),
                    Footer(
                        Button("Get Started", cls="primary"),
                        Button("Learn More", cls="secondary")
                    )
                ),
                
                style="grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1rem;"
            )
        )
    )

Forms with PicoCSS Styling

from fasthtml.common import *

app, rt = fast_app(pico=True)

@rt('/forms')
def form_demo():
    return Titled("Form Components",
        Container(
            H1("PicoCSS Form Styling"),
            
            # Registration form
            Card(
                Header(H2("User Registration")),
                Form(
                    Grid(
                        Group(
                            Label("First Name:", for_="first_name"),
                            Input(type="text", name="first_name", required=True)
                        ),
                        Group(
                            Label("Last Name:", for_="last_name"),
                            Input(type="text", name="last_name", required=True)
                        )
                    ),
                    
                    Group(
                        Label("Email Address:", for_="email"),
                        Input(type="email", name="email", required=True)
                    ),
                    
                    Group(
                        Label("Password:", for_="password"),
                        Input(type="password", name="password", required=True)
                    ),
                    
                    Group(
                        Label("Country:", for_="country"),
                        Select(
                            Option("Select country...", value="", disabled=True, selected=True),
                            Option("United States", value="us"),
                            Option("Canada", value="ca"),
                            Option("United Kingdom", value="uk"),
                            Option("Other", value="other"),
                            name="country"
                        )
                    ),
                    
                    Group(
                        Label(
                            Input(type="checkbox", name="newsletter", value="yes"),
                            " Subscribe to newsletter"
                        )
                    ),
                    
                    Group(
                        Button("Create Account", type="submit", cls="primary"),
                        Button("Reset", type="reset", cls="secondary")
                    ),
                    
                    method="post",
                    action="/register"
                )
            ),
            
            # Search form
            Card(
                Header(H3("Search")),
                Form(
                    Group(
                        Search(
                            name="query",
                            placeholder="Search products...",
                            hx_get="/search",
                            hx_target="#search-results",
                            hx_trigger="keyup changed delay:300ms"
                        ),
                        Button("Search", type="submit", cls="primary")
                    ),
                    Div(id="search-results")
                )
            )
        )
    )

Responsive Grid Layouts

from fasthtml.common import *

app, rt = fast_app(pico=True)

@rt('/layout')
def layout_demo():
    return Titled("Grid Layouts",
        Container(
            H1("Responsive Grid Examples"),
            
            # Two-column layout
            Section(
                H2("Two Column Layout"),
                Grid(
                    Div(
                        H3("Main Content"),
                        P("This is the main content area with more detailed information."),
                        P("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
                    ),
                    Div(
                        H3("Sidebar"),
                        P("This is sidebar content."),
                        Ul(
                            Li("Navigation item 1"),
                            Li("Navigation item 2"),
                            Li("Navigation item 3")
                        )
                    ),
                    style="grid-template-columns: 2fr 1fr; gap: 2rem;"
                )
            ),
            
            # Three-column layout
            Section(
                H2("Three Column Layout"),
                Grid(
                    Card(
                        Header(H4("Column 1")),
                        P("First column content."),
                        Footer(Button("Action 1"))
                    ),
                    Card(
                        Header(H4("Column 2")),
                        P("Second column content."),
                        Footer(Button("Action 2"))
                    ),
                    Card(
                        Header(H4("Column 3")),
                        P("Third column content."),
                        Footer(Button("Action 3"))
                    ),
                    style="grid-template-columns: repeat(3, 1fr); gap: 1rem;"
                )
            ),
            
            # Responsive card grid
            Section(
                H2("Responsive Card Grid"),
                Grid(
                    *[Card(
                        Header(H4(f"Card {i}")),
                        P(f"Content for card {i}"),
                        Footer(Button(f"Action {i}", cls="outline"))
                    ) for i in range(1, 9)],
                    style="grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem;"
                )
            )
        )
    )

Custom Styling and Themes

from fasthtml.common import *

app, rt = fast_app(pico=True)

@rt('/custom-style')
def custom_styling():
    # Custom CSS variables
    custom_styles = Style("""
        :root {
            --primary-color: #ff6b6b;
            --secondary-color: #4ecdc4;
            --accent-color: #45b7d1;
        }
        
        .custom-card {
            border-left: 4px solid var(--primary-color);
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
        }
        
        .highlight-button {
            background: var(--accent-color);
            color: white;
            border: none;
            padding: 0.75rem 1.5rem;
            border-radius: 0.5rem;
            transition: all 0.3s ease;
        }
        
        .highlight-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
        }
        
        @media (prefers-color-scheme: dark) {
            .custom-card {
                background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
            }
        }
    """)
    
    return Html(
        Head(
            Title("Custom Styling"),
            Meta(charset="utf-8"),
            Meta(name="viewport", content="width=device-width, initial-scale=1"),
            *picolink,
            custom_styles
        ),
        Body(
            Container(
                H1("Custom Styling Example"),
                
                Card(
                    Header(H3("Custom Styled Card")),
                    P("This card uses custom CSS variables and styling."),
                    Footer(
                        Button("Custom Button", cls="highlight-button"),
                        Button("Regular Button", cls="outline")
                    ),
                    cls="custom-card"
                ),
                
                # Theme-aware styling
                Section(
                    H2("Theme-Aware Components"),
                    P("These components adapt to light/dark mode preferences."),
                    
                    Grid(
                        Card(
                            Header("🌞 Light Mode"),
                            P("Optimized for light backgrounds")
                        ),
                        Card(
                            Header("🌙 Dark Mode"),
                            P("Automatically adapts to dark mode")
                        ),
                        style="grid-template-columns: repeat(2, 1fr); gap: 1rem;"
                    )
                )
            )
        )
    )

Dynamic Styling with HTMX

from fasthtml.common import *

app, rt = fast_app(pico=True)

@rt('/dynamic-style')
def dynamic_styling():
    return Titled("Dynamic Styling",
        Container(
            H1("Dynamic Style Changes"),
            
            # Color theme switcher
            Card(
                Header(H3("Theme Switcher")),
                Group(
                    Button(
                        "Blue Theme",
                        hx_post="/set-theme/blue",
                        hx_target="#themed-content",
                        hx_swap="outerHTML"
                    ),
                    Button(
                        "Green Theme",
                        hx_post="/set-theme/green",
                        hx_target="#themed-content",
                        hx_swap="outerHTML"
                    ),
                    Button(
                        "Red Theme",
                        hx_post="/set-theme/red",
                        hx_target="#themed-content",
                        hx_swap="outerHTML"
                    )
                ),
                Div(id="themed-content",
                    P("Click a theme button to change the styling dynamically.")
                )
            ),
            
            # Dynamic CSS classes
            Card(
                Header(H3("Dynamic Classes")),
                Button(
                    "Toggle Highlight",
                    hx_post="/toggle-highlight",
                    hx_target="#highlight-demo",
                    hx_swap="outerHTML"
                ),
                Div(id="highlight-demo",
                    P("This content can be dynamically highlighted.", cls="normal")
                )
            )
        )
    )

@rt('/set-theme/{theme}', methods=['POST'])
def set_theme(theme: str):
    theme_styles = {
        'blue': 'background: #e3f2fd; color: #0d47a1; border: 2px solid #2196f3;',
        'green': 'background: #e8f5e8; color: #2e7d32; border: 2px solid #4caf50;',
        'red': 'background: #ffebee; color: #c62828; border: 2px solid #f44336;'
    }
    
    style = theme_styles.get(theme, '')
    
    return Div(
        P(f"Theme changed to {theme.title()}!"),
        P("This content now uses dynamic styling."),
        style=style + ' padding: 1rem; border-radius: 0.5rem; margin-top: 1rem;',
        id="themed-content"
    )

@rt('/toggle-highlight', methods=['POST'])
def toggle_highlight():
    return Div(
        P("This content is now highlighted!", 
          style="background: yellow; padding: 1rem; border-radius: 0.5rem;"),
        Button(
            "Remove Highlight",
            hx_post="/remove-highlight",
            hx_target="#highlight-demo",
            hx_swap="outerHTML"
        ),
        id="highlight-demo"
    )

@rt('/remove-highlight', methods=['POST'])
def remove_highlight():
    return Div(
        P("Highlight removed.", cls="normal"),
        Button(
            "Add Highlight",
            hx_post="/toggle-highlight",
            hx_target="#highlight-demo",
            hx_swap="outerHTML"
        ),
        id="highlight-demo"
    )

Install with Tessl CLI

npx tessl i tessl/pypi-python-fasthtml

docs

application-routing.md

authentication.md

css-styling.md

development-tools.md

form-handling.md

html-components.md

htmx-integration.md

index.md

javascript-integration.md

notifications.md

svg-components.md

tile.json