Layout

AspectRatio

Keeps what it holds at a shape (16/9, 4/3, 1): an image or a video fills a box of the right height.

#layout#image#media#no-js

Demo

Preview
16 / 9
4 / 3
1
A wide purple band, cut to fit

The last holds an image three times as wide as it is tall, cut to 3 / 2 (fit="cover").

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

Example

The code of the preview above.

demos/aspect_ratio.qwe
// A picture made of CSS, so the demo loads nothing.view AspectRatioDemoArt(label: str, from: str, to: str) =    <div style={`display: grid; place-items: center; background: linear-gradient(135deg, var(--ui-${from}-soft), var(--ui-${to}-soft)); color: var(--ui-muted); font-size: 13px`}>{label}</div>view AspectRatioDemo() =    <div.demo-stack>        <Grid columns={3} gap="md">            <AspectRatio ratio="16/9" round={true} class="aspect-ratio-demo-wide"><AspectRatioDemoArt label="16 / 9" from="accent" to="info"/></AspectRatio>            <AspectRatio ratio="4/3" round={true} class="aspect-ratio-demo-tv"><AspectRatioDemoArt label="4 / 3" from="success" to="warning"/></AspectRatio>            <AspectRatio ratio="1" round={true} class="aspect-ratio-demo-square"><AspectRatioDemoArt label="1" from="danger" to="accent"/></AspectRatio>        </Grid>        <div.demo-narrow>            <AspectRatio ratio="3/2" round={true} class="aspect-ratio-demo-img">                <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='100'%3E%3Crect width='300' height='100' fill='%235b4bdb'/%3E%3C/svg%3E" alt="A wide purple band, cut to fit"/>            </AspectRatio>        </div>        <p.demo-note>The last holds an image three times as wide as it is tall, cut to 3 / 2 (fit="cover").</p>    </div>

Source

ui/aspect_ratio.qwe
// AspectRatio: keeps what it holds at a shape: an image, a video, a map or an// <iframe> fills a box as wide as its container and as tall as the ratio says, so// the page does not jump as it loads.////   <AspectRatio ratio="16/9"><img src="/cover.jpg" alt="The team on stage"/></AspectRatio>//   <AspectRatio ratio="1" round={true}><img src={p.photo} alt={p.name}/></AspectRatio>//   <AspectRatio ratio="4/3"><iframe src={map_url} title="Where we are"></iframe></AspectRatio>//// ratio: "16/9" (the default), "4/3", "3/2", "21/9", "1", or a number (1.5 is 3/2).// fit: how an image or video fills the box, "cover" (the default, cut to fit) or// "contain" (whole, with room around it). round: the kit's corner radius, and// what is inside cut to it. children: one element; it fills the box.import ui/theme.qwe use ui_clslet aspect_ratio_css = css`.ui-ratio { position: relative; width: 100%; min-width: 0; aspect-ratio: var(--ui-ratio, 16 / 9); overflow: hidden; }.ui-ratio > *, .ui-ratio > quillo-raw > * { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; }.ui-ratio > :is(img, video), .ui-ratio > quillo-raw > :is(img, video) { display: block; object-fit: var(--ui-ratio-fit, cover); }.ui-ratio > iframe, .ui-ratio > quillo-raw > iframe { border: 0; }.ui-ratio-round { border-radius: var(--ui-radius); }`// The ratio as CSS: "16/9" and 1.5 are fine as they are; anything else is 16/9.fn aspect_ratio_css_value(ratio) -> str =    match ratio {        int as n => str(n)        float as n => str(n)        str as s if re.test(trim(s), "^\\d+(\\.\\d+)?\\s*(/\\s*\\d+(\\.\\d+)?)?$") => replace(trim(s), " ", "")        _ => "16/9"    }view AspectRatio(ratio = "16/9", fit: str = "cover", round: bool = false, class: str? = null, children) {    style global aspect_ratio_css    <div class={ui_cls(["ui-ratio", round && "ui-ratio-round", class])}         style={`--ui-ratio: ${aspect_ratio_css_value(ratio)}; --ui-ratio-fit: ${fit == "contain" ? "contain" : "cover"}`}>        {children}    </div>}
Thread
97Useful? Like it, or add to its thread below.

Thread 0 posts

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

No posts yet. The first one opens the thread.