Style properties are passed as keyword arguments to element functions. PythonNative also provides a StyleSheet utility for creating reusable styles and a theming system via context.
Pass style props directly to components:
pn.Text("Hello", color="#FF3366", font_size=24, bold=True)
pn.Button("Tap", background_color="#FF1E88E5", color="#FFFFFF")
pn.Column(pn.Text("Content"), background_color="#FFF5F5F5")Create reusable named styles with StyleSheet.create():
import pythonnative as pn
styles = pn.StyleSheet.create(
title={"font_size": 28, "bold": True, "color": "#333"},
subtitle={"font_size": 14, "color": "#666"},
container={"padding": 16, "spacing": 12, "alignment": "fill"},
)
# Apply with dict unpacking
pn.Text("Welcome", **styles["title"])
pn.Column(
pn.Text("Subtitle", **styles["subtitle"]),
**styles["container"],
)Merge multiple style dicts with StyleSheet.compose():
base = {"font_size": 16, "color": "#000"}
highlight = {"color": "#FF0000", "bold": True}
merged = pn.StyleSheet.compose(base, highlight)
# Result: {"font_size": 16, "color": "#FF0000", "bold": True}Flatten a style or list of styles into a single dict:
pn.StyleSheet.flatten([base, highlight])
pn.StyleSheet.flatten(None) # returns {}Pass hex strings (#RRGGBB or #AARRGGBB) to color props:
pn.Text("Hello", color="#FF3366")
pn.Button("Tap", background_color="#FF1E88E5", color="#FFFFFF")Text and Button accept font_size, color, bold, and text_align:
pn.Text("Title", font_size=24, bold=True, text_align="center")
pn.Text("Subtitle", font_size=14, color="#666666")All components support common layout properties:
pn.Text("Fixed size", width=200, height=50)
pn.View(child, flex=1, margin=8)
pn.Column(items, margin={"horizontal": 16, "vertical": 8})width,height— fixed dimensions in dp (Android) / pt (iOS)flex— flex grow factor within Column/Rowmargin— outer spacing (int for all sides, or dict)min_width,max_width,min_height,max_height— size constraintsalign_self— override parent alignment
Column (vertical) and Row (horizontal):
pn.Column(
pn.Text("Username"),
pn.TextInput(placeholder="Enter username"),
pn.Text("Password"),
pn.TextInput(placeholder="Enter password", secure=True),
pn.Button("Login", on_click=handle_login),
spacing=8,
padding=16,
alignment="fill",
)spacing=Nsets the gap between children in dp (Android) / points (iOS).
padding=16— all sidespadding={"horizontal": 12, "vertical": 8}— per axispadding={"left": 8, "top": 16, "right": 8, "bottom": 16}— per side
Cross-axis alignment: "fill", "center", "leading" / "start", "trailing" / "end".
PythonNative includes a built-in theme context with light and dark themes:
import pythonnative as pn
from pythonnative.style import DEFAULT_DARK_THEME
@pn.component
def themed_text(text: str = "") -> pn.Element:
theme = pn.use_context(pn.ThemeContext)
return pn.Text(text, color=theme["text_color"], font_size=theme["font_size"])
class MyPage(pn.Page):
def render(self):
return pn.Provider(pn.ThemeContext, DEFAULT_DARK_THEME,
pn.Column(
themed_text(text="Dark mode!"),
spacing=8,
)
)Both light and dark themes include:
primary_color,secondary_color— accent colorsbackground_color,surface_color— background colorstext_color,text_secondary_color— text colorserror_color,success_color,warning_color— semantic colorsfont_size,font_size_small,font_size_large,font_size_title— typographyspacing,spacing_large— layout spacingborder_radius— corner rounding
Wrap content in a ScrollView:
pn.ScrollView(
pn.Column(
pn.Text("Item 1"),
pn.Text("Item 2"),
# ... many items
spacing=8,
)
)