Media

Figure

An image (or anything) with a caption and a credit under it, as a figure with its figcaption.

#media#image#typography#no-js

Demo

Preview
Green hills under a blue sky
The valley at noon, from the north ridge.Photo: Ana Reis
Purple hills at sunset
Sunset, day one.
Dark hills under a full moon
The moon over camp.© Ben Lee
Mon12 km
Tue18 km
A figure can hold anything: here, a table.

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

Example

The code of the preview above.

demos/figure.qwe
// A picture drawn in SVG, so the demo needs no image files.fn figure_demo_pic(a: str, b: str, w: int = 800, h: int = 500) -> str {    let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${w} ${h}" width="${w}" height="${h}">`        + `<rect width="${w}" height="${h}" fill="${a}"/>`        + `<circle cx="${w * 0.72}" cy="${h * 0.3}" r="${h * 0.12}" fill="#fff" opacity=".8"/>`        + `<path d="M0 ${h * 0.7} Q ${w * 0.3} ${h * 0.45} ${w * 0.55} ${h * 0.68} T ${w} ${h * 0.6} V ${h} H 0 Z" fill="${b}"/></svg>`    `data:image/svg+xml,${url_encode(svg)}`}view FigureDemo() =    <div.demo-stack>        <Figure src={figure_demo_pic("#7cb7f0", "#2f6b3a")} alt="Green hills under a blue sky" width={800} height={500}                caption="The valley at noon, from the north ridge." credit="Photo: Ana Reis" credit_href="https://example.com/ana"/>        <div.demo-row style="align-items: flex-start">            <Figure src={figure_demo_pic("#f3a46b", "#5b3a5e")} alt="Purple hills at sunset" size="sm" caption="Sunset, day one."/>            <Figure src={figure_demo_pic("#1d2b53", "#0f1a33")} alt="Dark hills under a full moon" size="sm" align="center"                    caption="The moon over camp." credit="© Ben Lee"/>        </div>        <Figure size="sm" align="right" caption="A figure can hold anything: here, a table.">            <table style="border-collapse: collapse; width: 100%">                <tr><td style="padding: 4px 8px; border: 1px solid var(--ui-border)">Mon</td><td style="padding: 4px 8px; border: 1px solid var(--ui-border)">12 km</td></tr>                <tr><td style="padding: 4px 8px; border: 1px solid var(--ui-border)">Tue</td><td style="padding: 4px 8px; border: 1px solid var(--ui-border)">18 km</td></tr>            </table>        </Figure>    </div>

Source

ui/figure.qwe
// Figure: an image with a caption under it, and a credit for whose it is, as a// <figure> with its <figcaption>, so the caption belongs to the image.////   <Figure src="/img/bridge.jpg" alt="The bridge at dusk" caption="The 25 de Abril bridge, seen from Alcântara."/>//   <Figure src="/img/lab.jpg" alt="..." caption="The lab in 1962" credit="Photo: NASA" credit_href="https://images.nasa.gov"/>//   <Figure caption="Monthly sales"><BarChart .../></Figure>//// src, alt: the image; without src the children are the figure's content (a chart,// a table, a code block). caption: the text under it; credit: who made it, smaller,// after the caption; credit_href makes the credit a link.// size: "sm" (up to 320px wide), "md" (560px, default), "lg" (as wide as it can be).// align: "left" (default), "center" or "right": where it sits and how the caption// is aligned. width, height: the image's own pixels, so the page does not jump as// it loads. lazy (true): loaded when scrolled near.import ui/theme.qwe use ui_clslet figure_css = css`.ui-figure { display: grid; gap: 8px; max-width: 560px; margin: 0; font: 14px/1.4 var(--ui-font); color: var(--ui-fg); }.ui-figure-sm { max-width: 320px; }.ui-figure-lg { max-width: none; }.ui-figure-center { margin-left: auto; margin-right: auto; text-align: center; }.ui-figure-right { margin-left: auto; text-align: right; }.ui-figure img { display: block; width: 100%; height: auto; border-radius: var(--ui-radius); background: var(--ui-subtle); }.ui-figure-body > :first-child { margin-top: 0; }.ui-figure-body > :last-child { margin-bottom: 0; }.ui-figure figcaption { font-size: 13px; color: var(--ui-muted); }.ui-figure-credit { display: inline-block; margin-left: 6px; font-size: 12px; color: var(--ui-muted); opacity: .85; }.ui-figure-credit a { color: inherit; }`view Figure(src: str? = null, alt: str = "", caption: str? = null, credit: str? = null, credit_href: str? = null,            size: str = "md", align: str = "left", width: int? = null, height: int? = null, lazy: bool = true,            class: str? = null, children) {    style global figure_css    <figure class={ui_cls(["ui-figure", size != "md" && `ui-figure-${size}`, align != "left" && `ui-figure-${align}`, class])}>        {src != null            ? <img src={src} alt={alt} width={width} height={height} loading={lazy ? "lazy" : null}/>            : <div.ui-figure-body>{children}</div>}        {(caption != null || credit != null) && <figcaption>            {caption}            {credit != null && <span.ui-figure-credit>                {credit_href != null ? <a href={credit_href} rel="noopener">{credit}</a> : credit}            </span>}        </figcaption>}    </figure>}
Thread
78Useful? Like it, or add to its thread below.

Thread 0 posts

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

No posts yet. The first one opens the thread.