ARKlight logoARKlight
Getting startedTutorialReferenceExamplesWhyChangelog

Tutorial

Tutorial overview
1. Pages and routes
2. State and actions
3. Styling and layout
4. Reusable components
5. Lists and conditionals

Styling and layout

No CSS file to write, and by default no @media breakpoints to hand-tune.

Two props on every component

class_name

renders as the HTML

class

attribute (avoiding the

class

keyword clash in Python);

style

takes a dict of CSS properties and renders as an inline

style

attribute. Built-in utility classes ship by default:

.nav

,

.card

,

.muted

,

.page

,

.hidden

.

Text("Careful now", class_name="muted")
Container(..., style={"background": "#f5f5ff", "padding": "1rem"})

Registering a class of your own

site.style(name, rules)

registers a new, reusable class from a plain

{css-property: value}

dict -- never a raw CSS string, the same boundary ARKlight holds everywhere else. Calling it again with a name already used overwrites that class's rules.

site = Site()
site.style("pull-quote", {"font-style": "italic", "border-left": "4px solid purple"})

@site.page("/")
def home():
    return Page(Text("A quote worth repeating.", class_name="pull-quote"))

Layout without @media

Page

never gets a

<head>

hook for a stylesheet of your own, and nothing in the default CSS is keyed to a viewport width, device class or browser engine. Layouts still adapt, but from the content's own available width, using plain flexbox/grid sizing keywords -- the technique goes by "intrinsic web design." Opt in with

class_name

, the same mechanism as

.card

above.

Class

What it does

.stack

Consistent vertical rhythm between block children

.cluster

A row of items that wraps as a group once it runs out of width

.sidebar

Two panels side-by-side once there's room, stacked when there isn't

.switcher

Children stay in a row until each would drop below a minimum width, then stack

.grid

An auto-filling card/tile grid with no explicit column count

.center

Constrains and horizontally centers content, with optional gutters

.reel

A horizontally-scrolling row that never wraps or overflows the page

.fluid-heading

Font size scales smoothly with available width via clamp()

The classic three columns

Container(
    Container(Heading("Fast"), Text("...", class_name="muted"), class_name="card"),
    Container(Heading("Simple"), Text("...", class_name="muted"), class_name="card"),
    Container(Heading("Portable"), Text("...", class_name="muted"), class_name="card"),
    class_name="switcher",
)
.switcher

keeps children in a row as long as each stays above

--ark-switcher-threshold

(default

30rem

), and stacks them the moment one would drop below it -- decided from the container's own measured width, never a device or browser.

Try it

  • Register a class with site.style and apply it to a Container on your page.
  • Swap the three cards above from .switcher to .grid and watch the column count become open-ended instead of fixed at three.

Need a real

@media

breakpoint anyway? It exists, but it's gated: see

experimental APIs

.

Previous: 2. State and actionsNext: 4. Reusable components
LicenseChangelogGitHubPyPI

ARKlight is GPLv3 with attribution terms; sites you build are yours. Your browser is still running JavaScript. We just made Python responsible for getting it there.