CSS Container Query Tester - Online @container Playground
Experiment with CSS container queries. Resize a container and see the styles change according to its size, not the viewport. Learn the new spec.
UD5 Toolkit
Live demo & compatibility test for CSS @container scroll-state() — detect stuck & snapped elements
Scroll down — when a sticky header gets stuck at top, the @container scroll-state(stuck: top) query activates.
This section introduces the concept of scroll-state container queries. The header above uses position: sticky; top: 0;.
When you scroll this container, the header will stick to the top edge. The container has container-type: scroll-state enabled.
The CSS @container scroll-state(stuck: top) rule detects this sticky state and applies highlight styles automatically — no JavaScript required (in supported browsers).
The scroll-state container query observes the scrollport for sticky-positioned descendants. When any position: sticky element becomes physically stuck to the specified edge, the query matches.
This is a boolean state query — it's either true or false. You can combine it with other container queries using and / or logic.
Key insight: the query fires for any sticky child inside the container, not just a specific one.
Imagine a table of contents sidebar: when a sticky header is active, you could dim non-relevant items or highlight the current section.
Another use case: sticky table headers that change appearance when "locked" — adding a shadow, changing background, or revealing action buttons.
Scroll-state queries bring these interactions to CSS, eliminating the need for complex IntersectionObserver setups.
As of late 2024, scroll-state container queries are available in Chrome Canary behind the Experimental Web Platform Features flag.
Safari and Firefox are actively working on implementation. This tool helps you test whether your current browser supports the feature natively.
For production, always provide a JavaScript fallback using IntersectionObserver or scroll event listeners.
Scroll-state container queries unlock new possibilities for state-driven styling without JavaScript. Combined with size container queries, they form a powerful responsive design toolkit.
Try the snap demo in the next column, and check the FAQ below for deeper insights.
Scroll to snap cards into place — @container scroll-state(snapped: block) detects when a child is aligned.
Sticky Detection
Snap Detection
Container Declaration
scroll-state container type. This enables purely CSS-driven reactions to scroll interactions without JavaScript.
chrome://flags/#enable-experimental-web-platform-features flag is enabled. Safari and Firefox have expressed interest and are tracking the specification, but native support is not yet available in stable releases. Use @supports (container-type: scroll-state) for feature detection.
stuck: top refers to the physical top edge regardless of writing mode. stuck: block-start is logical — it refers to the block-start edge, which depends on the writing mode (top in horizontal-tb, right in vertical-rl). For most English-language sites, they behave identically. Using logical properties (block-start, block-end, inline-start, inline-end) makes your styles more portable across different writing modes.
scroll-state(stuck: top) query matches if any sticky-positioned descendant inside the container is currently stuck to the top edge. You don't need to target a specific element — the query acts as a global state flag for the entire scroll container. This makes it perfect for patterns like "is any section header currently pinned?" to adjust a table of contents or toolbar.
scroll-state(snapped: block) detects whether the container's scroll position is currently aligned to a snap point in the block direction. For scroll-snap-type: y mandatory, the scroll position will always snap (so the query may always match once scrolling stops). For proximity snapping, the query only matches when close enough to a snap point. You can query snapped: x, snapped: y, snapped: block, snapped: inline, or snapped: both.
IntersectionObserver with a rootMargin that matches the sticky offset, or compare the sticky element's getBoundingClientRect().top against its container's top. For snap detection, listen to the scrollend event and check if scrollTop aligns with any child's offsetTop. Apply CSS classes (.is-stuck, .is-snapped) to replicate the container query behavior. This demo uses exactly this fallback approach for browsers without native support.
container-type: scroll-state size; (or use separate container names) to query both scroll state and dimensions. However, note that container-type: scroll-state alone does not enable size queries — you need to explicitly include size or inline-size. You can also nest containers: an outer container tracks size, while an inner one tracks scroll-state, giving you fine-grained control.
| Query Type | Syntax | Detects | Requires |
|---|---|---|---|
stuck: top |
@container scroll-state(stuck: top) |
Sticky element pinned to top edge | position: sticky; top: 0; on child |
stuck: bottom |
@container scroll-state(stuck: bottom) |
Sticky element pinned to bottom edge | position: sticky; bottom: 0; on child |
stuck: left / right |
@container scroll-state(stuck: left) |
Sticky element pinned horizontally | position: sticky; left: 0; on child + horizontal scroll |
snapped: block |
@container scroll-state(snapped: block) |
Child aligned to block-axis snap point | scroll-snap-type on container + scroll-snap-align on children |
snapped: inline |
@container scroll-state(snapped: inline) |
Child aligned to inline-axis snap point | Horizontal scroll-snap-type |
snapped: both |
@container scroll-state(snapped: both) |
Child aligned in both axes simultaneously | 2D scroll-snap-type |
Experiment with CSS container queries. Resize a container and see the styles change according to its size, not the viewport. Learn the new spec.
Add grid items beyond defined tracks and see how implicit rows/columns expand. Set sizes interactively. Master the grid.
Dynamically blend two colors using the CSS color‑mix() function in different color spaces. Copy the exact CSS snippet. No JS required.
Enter a URL and drag a slider to change the viewport width smoothly. See exactly where your layout breaks. No iframe limits.
A replica of the famous Flexbox Froggy game: solve alignment puzzles by writing CSS. Progress saved locally. Fun frontend learning.
Build the same layout with both Grid and Flexbox side by side. See the code differences and visual results.
Style the <progress> and <meter> elements with cross‑browser CSS. Adjust colors and sizes. Copy the final styles.
Use named grid lines instead of column numbers. See how they simplify placement. Visual, interactive learning.
Pick a color in the Display‑P3 space and get the CSS color() function. See the difference from sRGB. For modern design.
Grid of all 148 named CSS colors. Hover to see detail, click to copy the name or hex. Essential frontend reference.
Style an `<input type='range'>` with custom track and thumb. Cross‑browser CSS. Preview and copy the code.
Fetch a website's CSS and extract :root custom properties (‑‑color) to reveal its design token palette. For learning and inspiration.
Paste a list of hex colors and generate CSS custom properties for them. Create your design token file instantly.
Write modern CSS color functions like oklch(), lab(), hwb() and see the rendered color with fallback. Copy compatible code.
Set the number of lines and generate the CSS for multi‑line truncation using the standard line‑clamp and fallback. Quick copy.
Test the upcoming contrast‑color() CSS function. Get white or black automatically for a given background. See it live.
Paste your CSS and get a sorted list of all custom properties defined under :root with their values. Quick audit.
Pick a base color and generate a full palette of 10 shades (50 to 900) like Tailwind CSS. Copy as hex or hsl.
Paste a stylesheet and extract every unique color (hex, rgb, hsl) into a palette. Swatches displayed. Copy as JSON.
Enter a CSS selector and see its specificity broken down into A,B,C columns with a visual weight comparison. Learn specificity.
Enter a component name and generate a complete RTL test file with render, screen, and common assertions. Fast testing setup.
Design custom radio buttons and checkboxes using pure CSS. Choose sizes, colors, and animation. Copy the code.
Simulate the 7‑bag randomizer to see upcoming piece sequences. Practice your opening for competitive Tetris.
Test if your display supports HDR colors by rendering a gradient in Rec.2020 space. See what you're missing. Canvas based.
Generate a range of tints and shades from a single hex color. Ideal for data visualization, UI design systems, and Tailwind custom palette creation. Local tool.
See every HTML input type in one page. Check browser support and styling. Copy sample markup. Quick frontend reference.
See the Pantone Colors of the Year and popular palettes from past years. Get hex codes. Design inspiration.
Set a custom accent color for checkboxes, radios, range, and progress. See the browser’s rendering. Copy the CSS.
Virtually fold a digital paper and cut out shapes to see a snowflake unfold. Experiment with designs before real scissors. Pure creative fun.
Type a CSS color name like 'tomato' or 'mediumseagreen' and instantly get its hex code and preview. Complete named colors list.