Layout

Columns

Children side by side, equal or weighted, that go one under another when their box is narrow.

#layout#grid#no-js

Demo

Preview
One
Two
Three
Twice as wide
Aside

Below, the same columns in a 400px-wide box: they stack, the last one first.

Image
Text

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/columns.qwe
main.qwe
import ui/theme.qwe use theme_cssuse ui/columns.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>

Example

The code of the preview above.

demos/columns.qwe
view ColumnsDemoCell(label: str) =    <div style="padding: 18px 12px; border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); background: var(--ui-subtle); text-align: center; font-size: 13px">{label}</div>view ColumnsDemo() =    <div.demo-stack>        <Columns class="columns-demo-equal">            <ColumnsDemoCell label="One"/><ColumnsDemoCell label="Two"/><ColumnsDemoCell label="Three"/>        </Columns>        <Columns widths={[2, 1]} gap="lg" class="columns-demo-weighted">            <ColumnsDemoCell label="Twice as wide"/><ColumnsDemoCell label="Aside"/>        </Columns>        <p.demo-note>Below, the same columns in a 400px-wide box: they stack, the last one first.</p>        <div style="width: 400px; max-width: 100%">            <Columns widths={[1, 2]} reverse={true} class="columns-demo-narrow">                <ColumnsDemoCell label="Image"/><ColumnsDemoCell label="Text"/>            </Columns>        </div>    </div>

Source

ui/columns.qwe
// Columns: its children side by side, each as wide as the others or as the weights// say, and one under another where there is no room. It measures its own width,// not the window's, so it works inside a card or a sidebar too.////   <Columns> <Card>...</Card> <Card>...</Card> <Card>...</Card> </Columns>//   <Columns widths={[2, 1]} gap="lg" stack="lg"> <article>...</article> <aside>...</aside> </Columns>//   <Columns widths={[1, 2]} reverse={true}> <img .../> <div>...</div> </Columns>//// widths: the columns' shares of the width, in order ([2, 1]: the first twice as wide;// [1, 1, 2] for three); left out, they share it equally, however many there are.// gap: pixels (16, the default) or "none", "xs" (4), "sm" (8), "md" (16), "lg" (24), "xl" (32).// align: "stretch" (default), "start", "center" or "end", down the row.// stack: when they go one under another: narrower than "sm" (480px), "md" (640px, the// default), "lg" (900px), or "none" (never). reverse: stacked, the last column comes// first (an image written last, shown first on a phone).import ui/theme.qwe use ui_clslet columns_css = css`.ui-columns { container-type: inline-size; min-width: 0; }.ui-columns-in {  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); grid-template-columns: var(--ui-columns-tpl, none);  gap: var(--ui-columns-gap, 16px); align-items: var(--ui-columns-align, stretch); min-width: 0;}.ui-columns-in > *, .ui-columns-in > quillo-raw > * { min-width: 0; }@container (max-width: 479px) {  .ui-columns-sm > .ui-columns-in { display: flex; flex-direction: column; }  .ui-columns-sm.ui-columns-reverse > .ui-columns-in { flex-direction: column-reverse; }  .ui-columns-sm > .ui-columns-in > *, .ui-columns-sm > .ui-columns-in > quillo-raw > * { flex: none; }}@container (max-width: 639px) {  .ui-columns-md > .ui-columns-in { display: flex; flex-direction: column; }  .ui-columns-md.ui-columns-reverse > .ui-columns-in { flex-direction: column-reverse; }  .ui-columns-md > .ui-columns-in > *, .ui-columns-md > .ui-columns-in > quillo-raw > * { flex: none; }}@container (max-width: 899px) {  .ui-columns-lg > .ui-columns-in { display: flex; flex-direction: column; }  .ui-columns-lg.ui-columns-reverse > .ui-columns-in { flex-direction: column-reverse; }  .ui-columns-lg > .ui-columns-in > *, .ui-columns-lg > .ui-columns-in > quillo-raw > * { flex: none; }}`fn columns_gap(gap) -> str =    match gap {        int as n => `${n}px`        float as n => `${n}px`        "none" => "0"        "xs" => "4px"        "sm" => "8px"        "lg" => "24px"        "xl" => "32px"        _ => "16px"    }fn columns_flex(v: str) -> str =    match v {        "start" => "flex-start"        "end" => "flex-end"        _ => v    }view Columns(widths: list? = null, gap = 16, align: str = "stretch", stack: str = "md", reverse: bool = false,             class: str? = null, children) {    style global columns_css    let tpl = widths == null ? "none" : widths | map((w) => `minmax(0, ${w}fr)`) | join(" ")    <div class={ui_cls(["ui-columns", stack != "none" && `ui-columns-${stack}`, reverse && "ui-columns-reverse", class])}         style={`--ui-columns-gap: ${columns_gap(gap)}; --ui-columns-align: ${columns_flex(align)}; --ui-columns-tpl: ${tpl}`}>        <div.ui-columns-in>{children}</div>    </div>}
Thread
79Useful? Like it, or add to its thread below.

Thread 0 posts

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

No posts yet. The first one opens the thread.