When a component flips classes at runtime, a container query can stop matching even when the DOM and sizes look fine. The root cause is often containment eligibility: the browser first finds an eligible container ancestor, then checks the axis or name your query uses. If the container’s container-type no longer supports the axis you ask for, there is simply no valid target and the query fails.
Implementation
- Decide which axis your queries use. Width-based checks use the inline axis; height-based checks use the block axis. Use container-type: size when you need both axes, or container-type: inline-size when you only ever need inline-axis queries.
- If you need to target a specific wrapper to avoid accidental matches, use container-name. Remember that naming preserves which container the browser will consider, but it does not add axis support.
- When refactoring or toggling classes, inspect the container ancestor at the exact moment of the change: is there still a qualifying container, does it have the expected name (if you rely on names), and does it support the axis you query?
Expected behavior
- With container-type: size, both inline (width) and block (height) queries can match the same container.
- With container-type: inline-size, inline-axis queries continue to work but block-axis queries will report no eligible container.
- Name-only queries can still resolve a named container regardless of axis, but axis-based checks still require the appropriate container-type.
Limitations
- This diagnosis demonstrates container eligibility logic. It does not replace checking your real page for selector specificity, layout overrides, or browser rendering differences.
- If a query fails because the container is too small, or because the element moved to a different ancestor chain, the correct fix is not always changing container-type.
The article includes a compact deterministic fixture that reproduces the toggle, shows the failing state, and demonstrates both repairs: keep an appropriate container-type for axis queries or use container naming for targeting problems. Use the fixture’s diagnostics to separate container discovery issues from axis-eligibility problems.
Working example
export function createElement({ tag = 'div', width = 0, height = 0 } = {}) { return { tag, width, height, parent: null, children: [], containerType: 'normal', containerName: undefined, }; } export function appendChild(parent, child) { child.parent = parent; parent.children.push(child); } export function setContainerType(el, type) { el.containerType = type; } export function setContainerName(el, name) { el.containerName = name; } export function toggleContainerType(el, nextType) { setContainerType(el, nextType); } function compare(op, left, right) { switch (op) { case '>': return left > right; case '>=': return left >= right; case '<': return left < right; case '<=': return left <= right; default: throw new Error(`unsupported compare operator: ${op}`); } } function queryAxis(query) { if (query.kind === 'name-only') return null; if (query.axis) return query.axis; if (query.feature === 'width') return 'inline'; if (query.feature === 'height') return 'block'; return null; } export function findEligibleContainer(startEl, query) { let node = startEl.parent; const axis = queryAxis(query); while (node) { if (query.kind === 'name-only') { if (node.containerName === query.name) return node; } else if (axis) { if (node.containerType === 'size') return node; if (node.containerType === 'inline-size' && axis === 'inline') return node; } node = node.parent; } return null; } export function evaluateQuery(targetEl, query) { const container = findEligibleContainer(targetEl, query); if (!container) { return { matched: false, reason: 'no-eligible-container', container: null }; } if (query.kind === 'name-only') { return { matched: true, container }; } const axis = queryAxis(query); const size = axis === 'inline' ? container.width : container.height; return { matched: compare(query.compare, size, query.value), container, containerValue: size, }; } Read the full article: https://chriseugenerodriguez.com/blog/why-do-container-queries-stop-matching-when-you-switch-container-type-dynamically
