<!-- Source: https://scoped.svelte.page/examples/compound-selector -->

# Compound selectors

> A conditionally-added class gates a compound rule on the same child element, and the marker keeps the compound and combinator selectors alive.

**Source:** [https://scoped.svelte.page/examples/compound-selector](https://scoped.svelte.page/examples/compound-selector)

**Markdown mirror:** [https://scoped.svelte.page/examples/compound-selector.md](https://scoped.svelte.page/examples/compound-selector.md)

---

This mirror preserves the prose, implementation notes, and runnable Svelte source behind the live example page.

## FIG-001: compound selectors.

Toggling a conditionally-added class gates a compound rule (.page-rows.paged) on the same child element. The synthesized marker also keeps a descendant-combinator rule alive, so neither survives Svelte's unused-CSS pruning by accident.

**Metadata:** tag: `COMPOUND` | syntax: `scoped:class` | selector: `compound` | status: `passing`

### Source

#### CompoundSelector.svelte

Source file: [src/lib/examples/scoped-props/demos/CompoundSelector.svelte](https://github.com/humanspeak/svelte-scoped-props/blob/main/docs/src/lib/examples/scoped-props/demos/CompoundSelector.svelte)

```svelte
<script lang="ts">
    import type { ClassValue } from '@humanspeak/svelte-scoped-props/runtime'
    import ChildCard from './components/ChildCard.svelte'

    let paged = $state(true)
    let rowClass: ClassValue = $derived(['page-rows', { paged }])
</script>

<article class="scoped-proof passed dk-demo-shell">
    <label class="toggle-row">
        <input type="checkbox" bind:checked={paged} />
        <span>add <code>paged</code> from state</span>
    </label>

    <div class="render-grid">
        <div class="render-example rows-frame">
            <span class="example-label">Child component</span>
            <ChildCard scoped:class={rowClass} />
        </div>
    </div>

    <div class="comparison-grid">
        <div class="comparison-head">
            <span class="example-label">Source</span>
            <span class="example-label">Current result</span>
        </div>

        <div class="comparison-row">
            <div class="comparison-cell comparison-source">
                <span>Compound selector</span>
                <code>rowClass = ['page-rows', &#123; paged &#125;]</code>
                <code>.page-rows.paged &#123; … &#125;</code>
            </div>
            <div class="comparison-cell comparison-result">
                <span>Compound selector</span>
                <code>child-card page-rows{paged ? ' paged' : ''} svelte-parent svelte-child</code>
                <strong>{paged ? 'compound rule applies' : 'compound rule idle'}</strong>
            </div>
        </div>

        <div class="comparison-row">
            <div class="comparison-cell comparison-source">
                <span>Descendant combinator</span>
                <code>&lt;div class="rows-frame"&gt;</code>
                <code>.rows-frame .page-rows &#123; … &#125;</code>
            </div>
            <div class="comparison-cell comparison-result">
                <span>Descendant combinator</span>
                <code>rows-frame svelte-parent &gt; child-card page-rows svelte-parent</code>
                <strong>combinator rule applies</strong>
            </div>
        </div>
    </div>
</article>

<style>
    .page-rows {
        border-color: var(--proof-parent-border, purple);
        color: var(--proof-parent-ink, purple);
        background: var(--proof-parent-bg, pink);
    }

    /* Compound: both scoped classes must land on the same element. The
       conditionally-added `paged` class gates this rule on the child root. */
    .page-rows.paged {
        border-style: solid;
        background-image: repeating-linear-gradient(
            var(--proof-parent-bg, pink),
            var(--proof-parent-bg, pink) 18px,
            transparent 18px,
            transparent 20px
        );
    }

    /* Descendant combinator: a parent-owned frame wrapping the scoped child. */
    .rows-frame .page-rows {
        box-shadow: 0 0 0 2px var(--proof-parent-border, purple);
    }
</style>
```

#### ChildCard.svelte

Source file: [src/lib/examples/scoped-props/demos/components/ChildCard.svelte](https://github.com/humanspeak/svelte-scoped-props/blob/main/docs/src/lib/examples/scoped-props/demos/components/ChildCard.svelte)

```svelte
<script lang="ts">
    import type { ClassValue } from '@humanspeak/svelte-scoped-props/runtime'
    import { describeClass } from './classValue'

    type Props = {
        class?: ClassValue
        'scoped:class'?: ClassValue
    }

    let { class: className }: Props = $props()
    let classText = $derived(describeClass(className))
</script>

<div class={['child-card', className]}>
    Child receives <code>class="{classText}"</code>.
</div>

<style>
    .child-card {
        min-height: 116px;
        display: grid;
        place-items: center;
        padding: 18px;
        border: 2px dashed var(--proof-card-border, gray);
        border-radius: 6px;
        color: var(--proof-card-ink, black);
        text-align: center;
        background: var(--proof-card-bg, white);
    }

    code {
        padding: 2px 5px;
        border-radius: 4px;
        overflow-wrap: anywhere;
        background: var(--proof-code-bg, #eef2f7);
        color: var(--proof-code-ink, #111111);
        font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
        font-size: 0.95em;
    }
</style>
```
