This is heavily based on a previous proposal by Tab; the active work happening in OpenUI around popups, tabs, and accordions; and a work-in-progress proposal by Nicole Sullivan & Robert Flack.
The key feature here is that named toggles work in the same way as CSS counters:
<accordion>
<!-- Express initial states for a given toggle in html,
optionally with one of multiple states (e.g. `--card 3`)
-->
<card toggled="--card">
<tab>...</tab>
<content>...</content>
</card>
<card>
<tab>...</tab>
<content>...</content>
</card>
<card>
<tab>...</tab>
<content>...</content>
</card>
</accordion>
tab {
toggle: --card 2;
/* shorthand for:
* toggle-states: --card 2;
* toggle-set: --card;
*/
}
content:checked(--card) {
/* Toggles use counter scoping rules
* So this sees the toggle (and value) established
* by its previous sibling <tab>
*/
…
}
<accordion>
<card>
<content>...</content>
<tab>...</tab>
</card>
<card>
<tab>...</tab>
<content>...</content>
</card>
<card>
<tab>...</tab>
<content>...</content>
</card>
</accordion>
card {
toggle-states: --card 2;
}
tab {
/* toggle established by parent,
* so <tab> just opts into *manipulating*
* the toggle
*/
toggle-set: --card;
}
content:checked(--card) {
/* This time, the toggle comes from the parent
}
<details2>
<summary>...</>
<content>...</>
</details2>
<style>
details2 {
toggle-states: --show 2;
}
summary {
toggle-set: --show;
}
content {
display: none;
}
content:checked(--show) {
display: block;
}
<check-box></>
<style>
check-box {
toggle-self: 3 off on unknown;
/* toggle-self limits the toggle's scope
* to just the element itself.
* We *think* this is just a safety improvement,
* not actually a needed new ability.
*/
}
check-box:checked(self off) {...}
<tabs>
<card>
<tab>...</tab>
<content>...</content>
</card>
<card>
<tab>...</tab>
<content>...</content>
</card>
<card>
<tab>...</tab>
<content>...</content>
</card>
</tabs>
tabs {
toggle-group: --show 2;
/* -group establishes a scope for sub-counters,
* of which only one can be active at a time
* Same grammar as -states, so all sub-counters are identical.
*/
}
tab {
toggle-item: --show;
/* creates a sub-counter tied to the --show group */
/* because --show is a group, only one can be active */
}
content:checked(--show) {
/* sees the --show counter from its sibling */
}
<html toggle-scope="colors">
<button toggle-btn="colors">…</>
<section toggle-target="colors">…</>
<style>
[toggle-scope] {
toggle-states: attr(toggle-scope) [...];
/* toggles can be named by a string
* instead of a custom ident
*/
}
button {
toggle-set: attr(toggle-btn);
}
[toggle-target]:checked(attr(toggle-target)) {
/* Requires some magic here,
* but attr information *is* known
* during selector evaluation.
* Hopefully okay?
*/
}
The code here represents some of our early attempts, but we do not consider this use-case solved – or part of the current proposal.
<tabs>
<tab>...</tab>
<tab>...</tab>
<tab>...</tab>
<content>...</content>
<content>...</content>
<content>...</content>
</tabs>
<style>
/* tab-bar mode */
tabs {
display: grid;
grid-template-rows: auto 1fr;
counter-reset: tabs contents;
toggle-states: --tab group 2;
}
tabs::grid-cell(1 / 1) {
area-name: foo;
display: flex;
}
tab {
flow-into-grid-area: foo;
counter-increment: tabs;
toggle-set: --tab counter(tabs);
}
content {
grid-row: 2;
counter-increment: contents;
toggle-read: --tab counter(contents);
}
.radiogroup {
toggle-states: --radio group 2;
}
.radio {
toggle-set: --radio;
toggle-read: --radio;
}
Is this a potential solution?
tabs {
toggle-group: --show 2;
counter-reset: tabs contents;
}
tab {
toggle-item: --show counter(tabs);
/* toggle-item could generically allow named items,
* and accept counter() as one way to assign those names
*/
counter-increment: tabs;
}
content {
counter-increment: contents;
}
content:checked(--show counter(contents)) {
/* sees the --show counter from its sibling */
}
:checked()
the right syntax for a pseudo?