Layout

Section

A part of a page under its title and a line about it, kept to a readable width, with room above and below.

#layout#section#page#no-js

Demo

Preview

Pricing

One price per seat, monthly or yearly. No card needed to start.

Free
Team
Business

Ready when you are

Set up takes five minutes.

Centred, kept narrow, on a tinted band.

Each section's heading names it, so screen readers can jump from one to the next.

Get it

It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.

$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/section.qwe
main.qwe
import ui/theme.qwe use theme_cssuse ui/section.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>

Example

The code of the preview above.

demos/section.qwe
view SectionDemoCell(label: str) =    <div style="padding: 16px; border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); background: var(--ui-subtle); font-size: 13px">{label}</div>view SectionDemo() =    <div.demo-stack>        <Section id="section-demo-pricing" title="Pricing" description="One price per seat, monthly or yearly. No card needed to start."                 spacing="sm" size="full" pad={false}                 actions={[<Button variant="outline" size="sm">Compare plans</Button>, <Button size="sm">Start free</Button>]}>            <Grid columns={3}>{for p in ["Free", "Team", "Business"] => <SectionDemoCell label={p}/>}</Grid>        </Section>        <Section id="section-demo-cta" title="Ready when you are" level={3} description="Set up takes five minutes."                 size="sm" align="center" tone="subtle" spacing="sm"                 actions={<Button href="https://quillolang.org/">Get started</Button>}>            <p style="margin: 0">Centred, kept narrow, on a tinted band.</p>        </Section>        <p.demo-note>Each section's heading names it, so screen readers can jump from one to the next.</p>    </div>

Source

ui/section.qwe
// Section: a part of a page under its own title, with a line about it, its content// kept to a readable width and room above and below it.////   <Section title="Pricing" description="One price per seat, monthly or yearly.">//       <PricingTable .../>//   </Section>//   <Section title="Get started" size="sm" align="center" tone="subtle"//            actions={<Button href="/signup">Sign up</Button>}> ... </Section>//// title: its heading, an <h2> (level: 1 to 4 for another). description: a line under it.// actions: HTML at the end of the title row (a button, a link).// size: how wide its content may be, "sm" (640px), "md" (860px), "lg" (1140px, the// default) or "full". spacing: the room above and below, "none", "sm", "md" (default)// or "lg". pad: side padding (16px, 24px on wider screens; true).// align: "start" (default) or "center", which centres the title and the text too.// tone: "plain" (default) or "subtle", a tinted band across the page.// id: the <section>'s id, for a link to it; its heading then names it for screen readers.import ui/theme.qwe use ui_clslet section_css = css`.ui-section { padding-block: 40px; color: var(--ui-fg); font: 15px/1.5 var(--ui-font); }.ui-section-none { padding-block: 0; }.ui-section-sm { padding-block: 20px; }.ui-section-lg { padding-block: 72px; }.ui-section-subtle { background: var(--ui-subtle); }.ui-section-in { width: 100%; max-width: 1140px; margin-inline: auto; padding-inline: 16px; }.ui-section-size-sm { max-width: 640px; }.ui-section-size-md { max-width: 860px; }.ui-section-size-full { max-width: none; }.ui-section-flush { padding-inline: 0; }@media (min-width: 640px) { .ui-section-in:not(.ui-section-flush) { padding-inline: 24px; } }.ui-section-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px 24px; margin-bottom: 20px; }.ui-section-title { margin: 0; font-size: 24px; font-weight: 650; line-height: 1.25; letter-spacing: -.01em; }.ui-section-desc { max-width: 60ch; margin: 6px 0 0; color: var(--ui-muted); }.ui-section-actions { display: flex; flex: none; flex-wrap: wrap; gap: 8px; padding-top: 2px; }.ui-section-center { text-align: center; }.ui-section-center .ui-section-head { flex-direction: column; align-items: center; }.ui-section-center .ui-section-desc { margin-inline: auto; }.ui-section-center .ui-section-actions { justify-content: center; }.ui-section-body > :first-child { margin-top: 0; }.ui-section-body > :last-child { margin-bottom: 0; }@media (max-width: 599px) { .ui-section-head { flex-direction: column; } .ui-section-title { font-size: 21px; } }`fn section_heading(level: int, id: str?, text: str) =    match level {        1 => <h1.ui-section-title id={id}>{text}</h1>        3 => <h3.ui-section-title id={id}>{text}</h3>        4 => <h4.ui-section-title id={id}>{text}</h4>        _ => <h2.ui-section-title id={id}>{text}</h2>    }view Section(title: str? = null, description: str? = null, level: int = 2, actions = null, size: str = "lg",             spacing: str = "md", pad: bool = true, align: str = "start", tone: str = "plain", id: str? = null,             class: str? = null, children) {    style global section_css    let hid = id != null && title != null ? `${id}-title` : null    <section class={ui_cls(["ui-section", spacing != "md" && `ui-section-${spacing}`, tone == "subtle" && "ui-section-subtle",                            align == "center" && "ui-section-center", class])}             id={id} aria-labelledby={hid}>        <div class={ui_cls(["ui-section-in", size != "lg" && `ui-section-size-${size}`, !pad && "ui-section-flush"])}>            {(title != null || description != null || actions != null) && <div.ui-section-head>                <div>                    {title != null && section_heading(level, hid, title)}                    {description != null && <p.ui-section-desc>{description}</p>}                </div>                {actions != null && <div.ui-section-actions>{actions}</div>}            </div>}            <div.ui-section-body>{children}</div>        </div>    </section>}
Thread
65Useful? Like it, or add to its thread below.

Thread 0 posts

On Section: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.