Next: , Previous: , Up: API  


1.13 (hygguile components glass)

1.13.1 Procedures

Procedure: glass-panel content KEY: #:washes #:drift? #:accent #:tag #:attributes #:position #:frost #:tint #:rounding #:border #:shadow #:clip? #:padding #:classes #:content-classes

Create a frosted glass surface, with colour washes behind it if you want them.

The frost is the panel’s own translucent tint plus hg-frost, the framework’s rounded frost layer (see hygguile-extras.css): whatever sits behind the panel arrives blurred and coloured through it, so the panel reads as a pane of glass rather than an opaque card. How strong the frost is is the panel’s to say with frost, or a page’s in markup the component did not build: it is written as --hg-frost-blur, and four rems stand until something says otherwise.

The frost is not a backdrop-filter on the surface itself, and that is the point of the layer. A browser paints a filtered backdrop in the element’s square box and ignores its radius, which leaves a square patch of frost at every rounded corner; neither the radius nor a clip path on that element stops it, and clipping the surface would trap whatever it is meant to let out of its own corner. The layer therefore paints the frost, clips itself to the surface’s own radius, and leaves the surface free.

The surface never clips. The decorations (the washes and the accent) are wrapped in their own rounded clip layer, which is what keeps those oversized discs inside the glass, and that layer is a plain element, which browsers clip to its radius reliably.

The layer that holds the content does not clip unless the panel asks it to with clip?, and that default is deliberate. That layer’s edge falls exactly on the content’s own edge – the surface’s padding is on the surface – so a clip there shaves whatever sits flush with it by a device pixel: the left arc of a line’s first glyph, the stroke of a table’s first cell. Clipping is a knob a panel reaches for, not a tax every panel pays.

The washes are the wallpaper trick: a few oversized, heavily blurred discs of colour thrown across the panel, each described by glass-wash. They are decoration, so they are hidden from assistive technology and never take a pointer event, and the content sits in a positioned layer of its own above them. With drift? the discs move very slowly, out of phase with one another, so the glass has something to frost without ever stealing attention; left alone they are still, which is the calmer default for a panel that is often just a bit of background. Either way the drift stops for anyone who asks for less motion: prefers-reduced-motion turns the animation off in the stylesheet.

The layer the discs ride in wears the panel’s own rounding and clips, and that is still not enough for a blurred disc: a browser draws a filter’s blur in the square box the blur reaches, so without a clip of its own the wash leaves a faint square of ink beside each rounded corner. The layer’s class names that clip, and a clip has to name a radius, so it carries the framework’s default rounding as its own default. A panel that rounds its glass differently says so in --hg-glass-clip, on the panel or on any ancestor of the layer. See hygguile-extras.css for the whole story, and for the measurements that leave an explicit clip as the only cure.

A panel with no decorations has no layers, and then there is nothing to sit above: the content is the panel’s own children and no layer is added. That is what lets this one component be a <header>, a <ul> or a <div> without leaving an extra element inside, which a <ul> may not legally hold. A panel that does have decorations gets its decorations in a rounded <div> of their own and its content in a second one.

content

The panel’s contents.

washes

A list of glass-wash descriptors, or the empty list (the default) for a plain frosted panel.

drift?

A boolean; #t lets the washes drift.

accent

An optional decorative node drawn inside the clipped surface, above the washes and below the content: a hairline of gradient along the top edge, for instance.

tag

The element the surface is built from. Defaults to div; a bar wants header and a menu wants ul.

attributes

Extra attributes for the surface, as pairs of name and value.

position

List of symbols saying how the surface is placed. Defaults to (relative), which is what gives the washes something to be absolute against. A surface pinned some other way – (sticky top-0) for a bar – passes its own, or the empty list to place itself with the layout classes alone.

frost

How strong the frost is: a number of rems, or any CSS length as a string. Defaults to #f, which declares nothing and leaves the strength to the stylesheet’s own 4rem – the value Olive’s backdrop-blur-md would set. A pane that wants a gentler or heavier glass than the framework’s own passes its own, and carries no style attribute at all when it does not.

tint

List of symbols representing the frosted tint. Defaults to (bg-stone-100/75 dark:bg-onyx-900/75).

rounding

List of symbols representing the corner rounding. Defaults to (rounded-3xl).

border

List of symbols representing the border, or the empty list for none. Defaults to a two-pixel hairline in the stone ramp.

shadow

List of symbols representing the shadow, or the empty list for none. Defaults to (shadow-lg).

clip?

Whether the panel hides its content’s overflow, in the layer holding the content. Defaults to false: the washes are oversized but it is the layer they are painted in that keeps them inside the glass, so the content layer has no work to do unless a panel hands it some. Leaving it open is what keeps a line’s first glyph whole – that layer’s edge is the content’s own edge – and it keeps a surface free to let a child escape, a bar holding a dropdown being the case worth naming. The surface itself never carries overflow-hidden, whichever way clip? is set.

padding

List of symbols representing the padding classes. Defaults to (p-6 sm:p-8).

classes

Extra classes for the surface itself. A colour utility here replaces the corresponding default rather than piling onto it (see override-classes), so a surface can recolour its own glass.

content-classes

Extra classes for the layer holding the content, when a layer is added, so a panel can lay its contents out without reaching for the surface – a (flex flex-col gap-6) hero, for instance, spaces its rows with it.

(glass-panel (list (h1 "Hygguile"))
             #:washes (list (glass-wash '(bg-naples-yellow-500/75
                                          w-96 h-96 left-4 top-4)
                                        #:delay -6))
             #:frost 3
             #:drift? #t)

(glass-panel (list (nav-link "Home" #:href "/"))
             #:tag 'header
             #:position '(sticky top-0)
             #:rounding '()
             #:border '()
             #:padding '(px-4 py-4))
Procedure: glass-wash classes KEY: #:delay #:pace #:distance

Describe one colour wash for glass-panel.

A wash is a description, not markup: it says what the disc is made of and when it sets off, and the panel supplies the rest. The classes given here are read by Olive the way any other utility classes are, so the size (w-96), the place inside the panel (left-4 top-4) and the colour (bg-naples-yellow-500/75) are all just names. The panel adds the mechanics – the absolute positioning, the heavy blur, the rounding, the fact that the disc is decoration and never takes a pointer event – and decides whether it drifts at all, so one wash can stand still on one panel and move on another.

classes

List of symbols: the disc’s size, position and colour.

delay

A number of seconds, or any CSS time as a string. A negative delay starts the disc part way through its cycle, which is how several washes are kept out of phase with one another; #f (the default) leaves it in step with the rest.

pace

How long one drift takes: a number of seconds or any CSS time as a string, emitted as the disc’s --hg-blob-duration, which is what the stylesheet reads for the pace and is where its own default sits. Omitted, a panel drifts at that default. This is what lets one panel breathe slowly and another wander on a short leash, without a second stylesheet or a new class.

distance

How far the disc travels: a pair of lengths – horizontally and vertically – or a single length, which moves it along the horizontal axis and leaves the stylesheet’s own upward drift in place. A bare number counts as rems, so '(2 -1) travels 2rems right and 1rem up. Omitted, the disc travels as far as the stylesheet’s default.

(glass-wash '(bg-china-rose-500/50 w-72 h-72 right-4 top-4)
            #:delay -14 #:pace 40 #:distance '(3 -2))

Next: (hygguile components icon), Previous: (hygguile components fly-out), Up: API