actual-css 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@
10
10
  * geometry and states. switch.css is imported after this file.
11
11
  *
12
12
  * Public hooks:
13
- * --choice-control-offset
13
+ * --choice-control-nudge
14
14
  * --choice-border
15
15
  * --choice-bg
16
16
  * --choice-mark
@@ -42,45 +42,89 @@
42
42
  cursor: pointer;
43
43
  }
44
44
 
45
- /* Optical alignment: nudge the control down so it sits visually centered with
46
- the first line of label text, not flush with the top of the line-box. Every
47
- inline choice runs the same formula — center the control's own block size on
48
- the first line box, then drop it 0.0625em so it reads level with the
49
- cap-height rather than the em-box. A checkbox and a switch therefore stay
50
- level with each other under any line-height or --choice-control-size, which
51
- a per-control constant cannot do (a taller switch and a shorter checkbox
52
- need different offsets to land on the same optical line).
53
-
54
- The constants are what the formula yields at the default 1.5 line-height:
55
- 0.25em (4px) for a checkbox, 0.1875em (3px) for the taller switch track.
56
- They serve browsers without lh units. Multi-line labels still keep the
57
- control at the top thanks to align-items: flex-start.
58
-
59
- --choice-control-offset stays fallback-only rather than declared here, so an
60
- override placed anywhere up the tree — :root included — reaches the control
61
- instead of losing to a component-level declaration. */
45
+ /* Optical alignment: the control reads level with the first line's cap height,
46
+ not with the top of its line box. Every inline choice runs the same formula
47
+ over its own block size, so a checkbox and a taller switch stay level with
48
+ each other under any line-height or --choice-control-size — something a
49
+ per-control constant cannot do.
50
+
51
+ Three tiers, each the best the engine can express:
52
+
53
+ - `cap` unit: exact, and the only font-independent answer. Where the cap
54
+ center sits inside a line box depends on the font's ascent/descent/cap
55
+ ratios, so no constant can serve both Segoe UI and Roboto — the same rule
56
+ was a pixel high on Windows and two pixels low on Android. Baseline
57
+ alignment puts the control's border-box bottom on the text baseline, and
58
+ one inset drops it by half the difference between its own height and the
59
+ cap height. Both classed controls synthesize that baseline from their
60
+ border box because their mark and knob are out of flow.
61
+ - `lh` only: center the control on the line box, which is within a pixel of
62
+ the cap center for the usual UI faces.
63
+ - neither: the constants that formula yields at the default 1.5
64
+ line-height, 0.1875em for a checkbox and 0.125em for the switch track.
65
+
66
+ --choice-control-nudge adds to whichever tier applies, rather than replacing
67
+ it: the derived value is exact now, so a design has a correction to make,
68
+ not a formula to restate — and one number cannot stand in for three
69
+ different references anyway. It stays fallback-only rather than declared
70
+ here, so an override placed anywhere up the tree — :root included — reaches
71
+ the control instead of losing to a component-level declaration. */
62
72
  .choice > :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) {
63
73
  flex: 0 0 auto;
64
- margin-block-start: var(--choice-control-offset, 0.25em);
74
+ margin-block-start: calc(0.1875em + var(--choice-control-nudge, 0px));
65
75
  }
66
76
 
67
77
  .choice > .switch {
68
78
  flex: 0 0 auto;
69
- margin-block-start: var(--choice-control-offset, 0.1875em);
79
+ margin-block-start: calc(0.125em + var(--choice-control-nudge, 0px));
70
80
  }
71
81
 
72
82
  @supports (margin-block-start: 1lh) {
73
83
  .choice > :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) {
74
- margin-block-start: var(
75
- --choice-control-offset,
76
- calc((1lh - var(--choice-control-size)) / 2 + 0.0625em)
84
+ margin-block-start: calc(
85
+ (1lh - var(--choice-control-size)) /
86
+ 2 +
87
+ var(--choice-control-nudge, 0px)
88
+ );
89
+ }
90
+
91
+ .choice > .switch {
92
+ margin-block-start: calc(
93
+ (1lh - var(--switch-block-size)) /
94
+ 2 +
95
+ var(--choice-control-nudge, 0px)
96
+ );
97
+ }
98
+ }
99
+
100
+ @supports (margin-block-start: 1cap) {
101
+ .choice {
102
+ align-items: baseline;
103
+ }
104
+
105
+ /* Baseline alignment owns the block position now; the tier above would only
106
+ grow the row. An unclassed native input keeps the UA's own baseline, which
107
+ is already tuned for text — the formula below describes the framework's
108
+ geometry and would not fit it. */
109
+ .choice > :is(input[type="checkbox"], input[type="radio"]) {
110
+ margin-block-start: 0;
111
+ }
112
+
113
+ /* inset-block-start rides the `position: relative` these controls already
114
+ carry for their mark and knob. */
115
+ .choice > :is(.check, .radio) {
116
+ inset-block-start: calc(
117
+ (var(--choice-control-size) - 1cap) /
118
+ 2 +
119
+ var(--choice-control-nudge, 0px)
77
120
  );
78
121
  }
79
122
 
80
123
  .choice > .switch {
81
- margin-block-start: var(
82
- --choice-control-offset,
83
- calc((1lh - var(--switch-block-size)) / 2 + 0.0625em)
124
+ inset-block-start: calc(
125
+ (var(--switch-block-size) - 1cap) /
126
+ 2 +
127
+ var(--choice-control-nudge, 0px)
84
128
  );
85
129
  }
86
130
  }
@@ -56,8 +56,6 @@
56
56
 
57
57
  position: relative;
58
58
  display: inline-grid;
59
- align-items: center;
60
- justify-content: start;
61
59
  inline-size: var(--switch-width);
62
60
  block-size: var(--switch-block-size);
63
61
  margin: 0;
@@ -76,9 +74,17 @@
76
74
  against the track is what makes the knob legible. */
77
75
  .switch::before {
78
76
  content: "";
77
+ /* Out of flow like the checkbox mark, so the track carries no in-flow item
78
+ and the switch synthesizes its baseline from its own border box. A knob
79
+ laid out as a grid item makes the baseline the knob's bottom edge instead,
80
+ which is what .choice measures its cap-height offset from. The inset is
81
+ the same --switch-knob-margin on both axes: it resolves against the
82
+ padding box, so the border is already out of the way. */
83
+ position: absolute;
84
+ inset-block-start: var(--switch-knob-margin);
85
+ inset-inline-start: var(--switch-knob-margin);
79
86
  inline-size: var(--switch-knob-size);
80
87
  block-size: var(--switch-knob-size);
81
- margin-inline: var(--switch-knob-margin);
82
88
  border-radius: var(--radius-full);
83
89
  background: var(--switch-knob);
84
90
  transition: