Declarative container queries FTW!
A custom element as a ResizeObserver root. The easiest way to get working with ResizeObserver and creating container queries with JavaScript. Unlike many implementations, you can use any CSS length units, and mix them together.
Just import the watched-box.min.js module, like so:
import WatchedBox from './path/to/watched-box.min.js';
Then you can start wrapping your content in <watched-box> Custom Elements and defining width and height breakpoints:
<watched-box widthBreaks="70ch, 900px" heightBreaks="50vh, 60em">
</watched-box>
This will generate your classes, which take the following format (where a prefix is not supplied; see Props):
w-lte-[the width]w-gt-[the width]h-lte-[the height]h-gt-[the height]Depending on the aspect ratio, one of the following classes will also be appended (where a prefix is not supplied; see Props):
portraitlandscapesquareFinally, it is recommended you set watched-box to display: block by default in your CSS. You'll rarely be working with <watched-box> elements.
watched-box {
display: block;
}
A box with a width of 405px and a height of 9.5em.

<watched-box widthbreaks="405px" heightbreaks="9em" class="w-lte-405px h-gt-9em landscape"></watched-box>
### Multiple breaks for each dimension, using different units
A box with a width of `24ch` and a height of `120px`.

```html
<watched-box widthbreaks="9em, 800px" heightbreaks="405px, 10vh" class="w-gt-9em w-lte-800px h-lte-405px h-gt-10vh landscape"></watched-box>
Note that units are dynamically converted for comparison, meaning you can mix them. Where the context's value for 1em is 21px, <watched-box> is aware that 3.1em is longer than 63px (21px * 3, or 3em).

This one is more complex, and shows the power of <watched-box>. The element has the following CSS:
watched-box {
font-size: 20em;
width: 200px;
height: 200px;
}
Note the large 20em font-size. This is likely (depending on the context) to make 1em greater than 201px, eliciting the w-lte-1em class as below.
<watched-box widthbreaks="201px, 1em" heightbreaks="199px" class="w-lte-201px w-lte-1em h-gt-199px square"></watched-box>
Here's the same result, but with the prefix="wbx" prop/value supplied:
<watched-box widthbreaks="201px, 1em" heightbreaks="199px" prefix="wbx" class="wbx-w-lte-201px wbx-w-lte-1em wbx-h-gt-199px wbx-square"></watched-box>
Custom elements like <watched-box> take props as attributes. When the values change, <watched-box> reinitializes ResizeObserver observation.
| Name | Default | Description |
|---|---|---|
widthBreaks |
'1024px' |
{string} A comma-separated list of CSS length values (e.g. widthBreaks="20vw, 65ch, 300px, 900px") |
heightBreaks |
'768px' |
{string} A comma-separated list of CSS length values (e.g. heightBreaks="50vh, 800px, 9.25em, 200em") |
prefix |
null |
{string} A prefix for each generated class, for namespacing purposes (e.g. prefix="wbox") |
Obviously, <watched-box> doesn't write CSS for you (sorry to disappoint!). However, <watched-box> is just an element, and can be attributed and targeted with CSS however you like.
In the following example, I have created a specific <watched-box> and identified it with the class .grid. Imagining it has a 30ch width breakpoint, I can affect a .cell child element like so:
.grid.w-lte-30ch .cell {
/* styles for less-than-or-equal-to 30ch width */
}
.grid.w-gt-30ch .cell {
/* styles for over 30ch width */
}
Naturally, I can use negation too, if I wish:
.grid:not(.w-lte-30ch) .cell {
/* styles for less-than-or-equal-to 30ch width */
}
$ claude mcp add watched-box \
-- python -m otcore.mcp_server <graph>