monowind 0.3.3 is faster, blends opacity and translucent colors the way the browser does, and fixes a long list of layout and interaction bugs. The core package has less code than 0.3.2, and its CDN bundle is 7.5% smaller.
Faster
Measured against 0.3.2 in Chromium (medians, ms):
| measure | 0.3.2 | 0.3.3 |
|---|---|---|
| prose page (300 paragraphs), until interactive | 306 | 182 |
| boxes page (300 boxes), until interactive | 226 | 173 |
| faded boxes page, until interactive | 259 | 192 |
| prose relayout (CPU) | 88 | 65 |
| prose hover (CPU) | 97 | 74 |
| popover fading over a page, CPU per frame | 75–88 | 12–16 |
| the same, frames in a 1 s fade | 15–17 | 62–66 |
| 150 boxes fading at once, CPU per frame | 143 | 52 |
- A page load runs one layout instead of two.
- Style recalculation takes about half the time: only elements with a transition get the settling pass, and two style rules that kept Chromium from sharing styles between elements are gone.
- An
opacityor border-color transition repaints each frame instead of laying the page out again, and a frame lays out at most once. - Shade glyphs (
░▒▓) no longer defeat Chromium's style cache: pages full of them restyle a third faster.
Opacity and translucent colors
- Translucent colors (
bg-white/10,text-white/60) andopacity-*blend into the cells beneath them, as the browser composites them. Abg-white/10card on abg-slate-800panel now tints the slate; in 0.3.2 it showed white over the host's background. - An
opacity-*element fades as a whole, as in a browser: on a white page, abg-blue-600 text-white opacity-50button shows white text on a light blue fill. - A background of any alpha hides the glyph beneath it, and a color at zero alpha paints nothing.
- Where nothing opaque lies beneath, translucent colors and faded elements keep their alpha, and the browser composites them over whatever is behind the host: an image, a gradient, the page.
- Color emoji fade with their element, in Safari too.
- Every CSS color space blends:
lab(),lch(),oklab(),oklch(), andcolor()'sdisplay-p3,a98-rgb,prophoto-rgb,rec2020andxyz(0.3.2 misreaddisplay-p3as sRGB).
Fixes
- Shade glyphs (
░▒▓, in scrollbar tracks, shadows and the blocks theme) draw once, at the density the font draws them. They were two to three times darker and banded row by row. - Sticky: a sticky element inside a fixed element, a popover or a dialog sticks to the right scroller; a sticky span inside a scrolling paragraph sticks; a sticky heading among text runs moves its native element with it.
- Flex: reversed rows and columns and
wrap-reversematch the browsers for every alignment keyword, positioned children included (startstays put whereflex-startflips). w-fitcontributes its full width: aw-fitlabel in a flex row, a float, a positioned box or a table cell no longer wraps at its longest word.- Tables: a positioned child of a table sits where a row in its place would start, margins included.
- Stacking in text mode: a
z-*on an element no longer lifts its children's native elements, so clicks and selections land on the element the grid shows. - An element that stops being a box (a responsive
block md:inline) drops its engine positioning. - An
align-middleinline-flex text box lands on its row; a multicol's overflow columns can be scrolled to; gap rules on overflowing tracks meet the border correctly. - An outer inline element's background paints under its inner inline elements; a span inside a padded inline element no longer inherits that padding.
- Text ending on an inline box that doesn't fit its line no longer gains an empty last line (or crashes beside a float).
- The
*-safealignment classes (justify-center-safe,items-end-safe, …) align as their keyword; they used to align to the start. - Transitions: easing comes from the browser itself (
linear(),steps(…, jump-start)and delays included); removing an element mid-transition no longer keeps the host laying out every frame; the host's theme colors follow a background transition to its end. - An inline viewport-unit
min-/max-size wins over a class'scalc()value, as the cascade has it. - A host inside
display: nonewaits instead of laying out with zero-width cells; a removed host stops listening to window events and listens again when put back.
Vite plugin
0.3.2 pre-bundled a linked monowind (from a workspace or npm link), so the dev server kept serving the engine from before an edit. A linked engine is now served as is; an installed one is still pre-bundled.
Components
- Item parts (
Item,ItemText,ItemIndicator,ItemGroup,ItemGroupLabel) read the nearest listbox, select or combobox root in React, Vue and Svelte alike, so aSelectIteminside aListboxRootworks. - The error for an item part outside a list root, or for an item's text or indicator outside its
Item, names where the part belongs. - Vue: a bare boolean attribute sets its prop, as in HTML:
<MenuTrigger as-child>,<MenuItem disabled>,<SelectRoot multiple>(in 0.3.2 they read as false). Every part's type carries its declared props and its element's attributes. - React:
ItemTextandItemIndicatorare typed as thespans they render, and every part's type carries itsdisplayName.
Dependencies
@sveltejs/vite-plugin-svelte7.3.1 (a dev dependency of@monowind/ui-svelteand the Svelte example).- The StyleX example moves to
@stylexswc/unplugin0.19.0.
Upgrading from 0.3.2
- Shades look lighter. Scrollbar tracks, box-shadow rings and
░▒▓borders show the font's own density, no longer the doubled one. - Reversed flex layouts may move where they used
start/end(place-*utilities) orbaseline: they now sit where the browsers put them. - Vue types: a part rejects a prop name that is neither declared nor an attribute of its element (0.3.2 accepted any name).
- Wide-gamut screens: a blend clips each color to sRGB first, as browsers do on an sRGB screen, so on a wide-gamut display a translucent color outside sRGB comes out a little duller than the browser's own blend.
- 〰 ㊗ 〽 🈂 take two cells, on the grid and in
clusterWidthandtextCells, as the East Asian Wide table has them. - A selection's first frame: a selection a script makes, or one a key extends into the host, can show the browser's own highlight for one frame before the grid's.
- Fades: the main thread spends far less per frame, so fades run at two and a half to four times the frame rate. A fade over opaque cells costs the browser more paint per frame (about 17 ms against 2 when 150 boxes fade at once; under 2 ms for a popover).
- Overflowing content aligns to the start, as in 0.3.2: a flex line, grid item or positioned box larger than its container sits at the start edge whatever its alignment, where browsers center or end it past that edge.