Layout

Masonry

Cards of different heights packed into columns, each filled from the top, on CSS columns alone.

#layout#grid#card#no-js

Demo

Preview

Grocery list

Eggs, oat milk, lemons, basil, the good olive oil, bread for Saturday.

Idea

A tiny app that turns a photo of a receipt into a shared bill.

Reading

Finished the second chapter. The part about tides was the best so far, worth reading twice before the meeting on Thursday, where it will come up.

Call back

Dentist, before noon.

Trip

Trains from Lisbon leave on the hour. Book the 09:00 and the 17:00 back; a day pass is cheaper than two singles.

Quote

“Make it work, make it right, make it fast.”

Garden

Move the tomatoes into the sun. Water the ferns on Monday and Thursday, and feed the lemon tree once this month.

Gift

A record player for Ana's birthday, the green one.

Passwords

Rotate the API keys on the first of the month.

Nine cards of different heights in three columns, each filled from the top.

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

Example

The code of the preview above.

demos/masonry.qwe
let masonry_demo_notes = [    { title: "Grocery list", text: "Eggs, oat milk, lemons, basil, the good olive oil, bread for Saturday." },    { title: "Idea", text: "A tiny app that turns a photo of a receipt into a shared bill." },    { title: "Reading", text: "Finished the second chapter. The part about tides was the best so far, worth reading twice before the meeting on Thursday, where it will come up." },    { title: "Call back", text: "Dentist, before noon." },    { title: "Trip", text: "Trains from Lisbon leave on the hour. Book the 09:00 and the 17:00 back; a day pass is cheaper than two singles." },    { title: "Quote", text: "“Make it work, make it right, make it fast.”" },    { title: "Garden", text: "Move the tomatoes into the sun. Water the ferns on Monday and Thursday, and feed the lemon tree once this month." },    { title: "Gift", text: "A record player for Ana's birthday, the green one." },    { title: "Passwords", text: "Rotate the API keys on the first of the month." }]view MasonryDemo() =    <div.demo-stack>        <Masonry id="masonry-demo-notes" width={200}>            {for n in masonry_demo_notes => <Card title={n.title} padding="sm"><p style="margin: 0; font-size: 14px">{n.text}</p></Card>}        </Masonry>        <p.demo-note>Nine cards of different heights in three columns, each filled from the top.</p>    </div>

Source

ui/masonry.qwe
// Masonry: cards of different heights packed into columns, each column filled// from the top (a photo wall, a board of notes), on the browser's own CSS columns,// so it needs no script. Items read down each column, then the next.////   <Masonry> {for n in notes => <Card title={n.title}>{n.text}</Card>} </Masonry>//   <Masonry columns={4} width={180} gap="sm"> {for p in photos => <img src={p.src} alt={p.alt}/>} </Masonry>//// columns: at most this many columns (3). width: the narrowest a column may be, in// pixels (220): fewer columns fit when it is narrow, and one on a phone.// gap: pixels (16, the default) or "none", "xs" (4), "sm" (8), "md" (16), "lg" (24), "xl" (32),// between the columns and between the cards in one. id: the grid's id.import ui/theme.qwe use ui_clslet masonry_css = css`.ui-masonry { columns: var(--ui-masonry-min, 220px) var(--ui-masonry-cols, 3); column-gap: var(--ui-masonry-gap, 16px); min-width: 0; }.ui-masonry > *, .ui-masonry > quillo-raw > * { display: block; break-inside: avoid; margin: 0 0 var(--ui-masonry-gap, 16px); width: 100%; }.ui-masonry > img, .ui-masonry > quillo-raw > img { height: auto; }`fn masonry_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"    }view Masonry(columns: int = 3, width: int = 220, gap = 16, id: str? = null, class: str? = null, children) {    style global masonry_css    <div class={ui_cls(["ui-masonry", class])} id={id}         style={`--ui-masonry-cols: ${columns}; --ui-masonry-min: ${width}px; --ui-masonry-gap: ${masonry_gap(gap)}`}>        {children}    </div>}
Thread
67Useful? Like it, or add to its thread below.

Thread 0 posts

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

No posts yet. The first one opens the thread.