The ? marker puts a selector in dynamic observed mode.
Behavior
Section titled “Behavior”- if in the DOM on first compilation → generated
- if not in the DOM on first compilation → listens to the DOM
- if later added to the DOM → generated
- if later removed from the DOM → rule is deactivated
Writing Rule
Section titled “Writing Rule”The ? marker is written at the very end of the selector part, without a space. If a pseudo is present, it comes after the pseudo.
.toast? { background: #333; }#modal? { display: flex; }.btn:hover? { background: #1a50e0; }
/* wrong */.btn?:hover { background: #1a50e0; }.toast ? { background: #333; }The same rule applies after composition via &var(...):
--hovercard: :hover { transform: translateY(-2px); };--active: .is-active { box-shadow: 0 10px 26px rgba(22, 61, 120, 0.18); };
.card &var(--hovercard)? { opacity: 0.85; }.card &var(--active)? { opacity: 0.85; }These examples are evaluated as .card:hover? and .card.is-active? respectively.
Typical Usage
Section titled “Typical Usage”.toast? { background: #1a1a2e; color: #fff; padding: 8px 16px; border-radius: 6px;}If .toast is not in the DOM when the page opens, this rule is not generated. If .toast is later added via JavaScript, the rule is generated at that point.
When Should It Be Used?
Section titled “When Should It Be Used?”| Situation | Usage | Why | Example |
|---|---|---|---|
| Component to be added later via JavaScript | Use ? | May not be in the DOM on first open but can come later | .toast? { background: #333; } |
| Modal opened via Ajax / client-side render | Use ? | Modal or overlay may be added to DOM later | .modal? { display: flex; } |
| Notification classes that come based on state | Use ? | Which variant will come is not certain in advance | .toast-success? { ... } |
| Cards that multiply later via infinite scroll / filtering | Use ? | List items may grow over time | .product-card? { border: 1px solid #ddd; } |
| Utility/grid classes that are fixed on page open | Prefer ?! | Dynamic watching creates unnecessary cost | .col-4?! { grid-column: span 4; } |
| Static header/footer always in the DOM | Don't use Observed | Normal selector is more correct and cheaper | header { background: #fff; } |
Short note:
- If there's a chance of being added to the DOM later →
? - If only the initial snapshot matters →
?! - Don't use observed for static selectors that are always present
Usage Scenarios
Section titled “Usage Scenarios”Toast and Notification
Section titled “Toast and Notification”.notification? { background: #2060ff; color: #fff; padding: 12px 16px; }.toast-error? { background: #991b1b; color: #fff; padding: 8px 12px; }.toast-success? { background: #065f46; color: #fff; padding: 8px 12px; }Modal and Overlay
Section titled “Modal and Overlay”.modal? { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;}
.overlay? { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5);}Dynamic Class Generation With @for
Section titled “Dynamic Class Generation With @for”--variants: [info, success, warning, danger];
@for(v, var(--variants)) { .alert-${v}? { border-left: 4px solid var(--colors.${v}); padding: 12px 16px; border-radius: 4px; }}This pattern is suitable for variant components that can be added to the DOM later.
Conditional Dynamic Observed With @if
Section titled “Conditional Dynamic Observed With @if”--mode: wide;
@if(var(--mode) === 'wide') { #panel? { display: block; }}else { #panel? { display: none; }}The condition is resolved at compile time; only the true branch is carried to runtime.
Usage With lazy
Section titled “Usage With lazy”When lazy is on, when dynamic observed rules are compiled and when they activate may change. For the detailed behavior table, see the Performance page.