Styling functions and keywords
Goal
You want one particular thing on the page to be bold, or red, or bigger, or spaced out, without touching the rest of the site.
Before you start
A theme handles the overall look (use one first). Helpers are for the details: they wrap a single piece of content and return it styled.
The smallest version
Wrap a piece of content in a styling function to style it, and wrap the result in another styling function to combine effects:
from drafter import *
from dataclasses import dataclass
@dataclass
class State:
warnings: int
@route
def index(state: State) -> Page:
return Page(state, [
bold("This line is bold.\n"),
italic("This one is italic.\n"),
change_color("This one is crimson.\n", "crimson"),
bold(change_color("Warnings: " + str(state.warnings) + "\n", "darkorange")),
Button("Add a warning", "warn")
])
@route
def warn(state: State) -> Page:
state.warnings = state.warnings + 1
return index(state)
start_server(State(0))
The helpers, by what you want
| You want | Reach for |
|---|---|
| Emphasis | bold, italic, underline, strikethrough, monospace |
| Size | small_font, large_font, change_text_size |
| Color | change_color, change_background_color |
| Alignment | change_text_align, float_left, float_right |
| Spacing and boxes | change_margin, change_padding, change_border, change_width, change_height |
| Fonts and text shape | change_text_font, change_text_decoration, change_text_transform |
Color names come from the standard HTML color list, and safe font names from the font list.
Recipe: style components, not just text
Helpers accept any component, not only text. A button can be large and
green, and a whole group of content can get a border when you wrap it
in a Div:
from drafter import *
from dataclasses import dataclass
@dataclass
class State:
accepted: bool
@route
def index(state: State) -> Page:
notice = Div(
bold("Field trip on Friday!\n"),
"Bring a raincoat and a snack.\n"
)
return Page(state, [
change_padding(change_border(notice, "2px solid steelblue"), "12px"),
"\n",
large_font(change_background_color(Button("Sounds fun!", "accept"), "lightgreen"))
])
@route
def accept(state: State) -> Page:
state.accepted = True
return Page(state, [
"See you Friday!"
])
start_server(State(False))
Recipe: style keywords on any component
Every component also accepts style_ keyword arguments directly, one
per CSS property. The part after style_ is the CSS property name with
underscores instead of hyphens, so style_background_color sets
background-color:
from drafter import *
from dataclasses import dataclass
@dataclass
class State:
presses: int
@route
def index(state: State) -> Page:
return Page(state, [
Text("Big red button protocol.\n", style_font_size="20px"),
Button("Do not press", "press",
style_background_color="crimson",
style_color="white",
style_padding="10px")
])
@route
def press(state: State) -> Page:
state.presses = state.presses + 1
return Page(state, [
"Pressed " + str(state.presses) + " times. Naturally.\n",
Button("Back", "index")
])
start_server(State(0))
Helpers and keywords do the same job. Helpers read better when you make
one or two changes, while keywords keep everything in one place when a
component needs several. Keyword arguments suit this situation well
because every style_ setting is optional.
Common problems
- The style did not apply: check you are showing the wrapped result.
bold("hi")returns styled content; it does not change"hi"in place. - A color or size seems ignored: the value may be invalid CSS. Use a
named color and include units on sizes
(
"20px", not20). - The theme overrides your style: themes apply many rules of their
own. Your inline styles usually win, but when one does not, try
making the same change with a
style_keyword, or pick a quieter theme. - A keyword seems misspelled: remember the underscore rule.
style_background_color, notstyle_backgroundcolor.
Understand it
Styling changes presentation only, and leaves state and routes untouched. The three tiers are described on Change the appearance.
See another example
Finish and test an app applies a theme plus targeted helpers to a finished project.
Look it up
Styling functions lists every helper with its exact signature and CSS effect.
Fix a problem
Styles are invisible to most tests by design, so cosmetic changes do
not break them. See Test a feature for
assert_style when you do want to check one. For display oddities,
start at Troubleshooting.