clairity.css 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,12 +20,6 @@ CLASSES - Here is where we first deviate from the classless CSS directive. We'll
20
20
  // #containers -
21
21
  // -------------------------------------------------------------------------- */
22
22
 
23
- /* this doesn't work because some items aren't full width, like asides
24
- body > *:not(.fluid) {
25
- margin-inline: var(--m);
26
- }
27
- */
28
-
29
23
  /* for constraining width to a reasonable line length - keep in sync
30
24
  with sectioning children of the body element in components.css */
31
25
  .readable {
@@ -38,52 +32,43 @@ body > *:not(.fluid) {
38
32
  ._100vw, [class~="100vw"] {
39
33
  width: 100vw;
40
34
  max-width: 100vw; /* still has horizontal scrollbar issues */
41
- margin-inline: calc(50% - 50vw - var(--xs));/*neg. margin if needed*/
35
+ margin-inline: calc(50% - 50vw); /* neg. margin where necessary */
42
36
  }
43
37
 
44
- /* #100dvi - dynamic full width of the viewport */
38
+ /* #100dvi - full dynamic viewport width - unfortunately doesn't account for
39
+ scrollbars, so its utility for full-bleed breakouts is severely limited
40
+ ...........................................................................*/
45
41
  ._100dvi, [class~="100dvi"] {
46
42
  width: 100dvi;
47
43
  max-width: 100dvi; /* still has horizontal scrollbar issues */
48
- margin-inline: calc(50% - 50dvi - var(--xs));/*neg margin if needed*/
44
+ margin-inline: calc(50% - 50dvi); /* neg. margin where necessary */
49
45
  }
50
46
 
51
47
 
52
48
  /* -----------------------------------------------------------------------------
53
- // #grid helpters -
49
+ // #grid - subgrid is ff 71+ & safari 16+ only, chrome/edge in dev - 20230423
54
50
  // -------------------------------------------------------------------------- */
55
51
 
56
- /* .subgrid extends grid into descendents - firefox 71+ & safari 16+ only, no
57
- chrome/edge yet - EXPERIMENTAL
52
+ /* .subgrid extends grid into descendents - EXPERIMENTAL
58
53
  ...........................................................................*/
59
54
  .subgrid {
60
- grid-column: padded; /* place subgrid on the parent grid */
61
- display: inherit; /* inherits grid, otherwise no subgrid */
62
- grid-template-columns: subgrid; /* only subgrid columns */
63
- gap: inherit; /* inherit parent grid gap */
64
- max-width: unset; /* let parent grid dictate width */
55
+ grid-column: padded; /* place subgrid on the parent grid */
56
+ display: inherit; /* inherits grid, otherwise no subgrid */
57
+ grid-template-columns: subgrid; /* only subgrid columns */
58
+ gap: inherit; /* inherit parent grid gap */
59
+ max-width: unset; /* let parent grid dictate width */
65
60
  }
66
61
 
67
- /* HACK: chrome & edge do not yet support subgrid as of 20221001 */
68
- @supports not (grid-template-columns: subgrid) {
69
- .subgrid { display: contents; }
70
- .subgrid :first-child { /* TODO: this breaks some layouts, like banner images */
71
- /*grid-column-start: 2;*/ /* TODO: fix right side guttering too */
72
- }}
73
-
74
62
  /* span the full width of the grid
75
63
  .......................................................................... */
76
64
  .full {
77
- /*grid-column: full;*/
78
- grid-column: 1 / -1;
79
- max-width: none; /* remove other width restrictions */
65
+ grid-column: 1 / -1; /* more foolproof than `full` grid area */
66
+ /*max-width: none;*/ /* interferes with .full in .subgrid */
80
67
  }
81
68
 
82
69
  /* span all but the 1st & last grid columns
83
70
  .......................................................................... */
84
- .padded {
85
- grid-column: 2 / -2;
86
- }
71
+ .padded { grid-column: 2 / -2; } /* 1st/last columns are typically padding */
87
72
 
88
73
 
89
74
  /* -----------------------------------------------------------------------------
@@ -132,27 +117,14 @@ body > *:not(.fluid) {
132
117
 
133
118
 
134
119
  /* -----------------------------------------------------------------------------
135
- // #colors - provide a set of utility color classes where the --color variable
136
- // is employed - EXPERIMENTAL
120
+ // #colors - semantic classes for setting the --color variable - EXPERIMENTAL
137
121
  // -------------------------------------------------------------------------- */
138
122
 
139
- /* semantic colors for states */
123
+ /* semantic colors for icon states */
140
124
  .valid { --color: var(--valid); }
141
125
  .invalid { --color: var(--invalid); }
142
126
  .unknown { --color: var(--unknown); }
143
127
 
144
- .red { --color: var(--error); }
145
- .orange { --color: var(--error); }
146
- .yellow { --color: var(--warning); }
147
- .lime { --color: var(--error); }
148
- .green { --color: var(--success); }
149
- .aqua { --color: var(--error); }
150
- .blue { --color: var(--info); }
151
- .indigo { --color: var(--error); }
152
- .purple { --color: var(--error); }
153
- .violet { --color: var(--error); }
154
- .magenta { --color: var(--error); }
155
-
156
128
 
157
129
  /* -----------------------------------------------------------------------------
158
130
  // #backgrounds -
@@ -160,79 +132,27 @@ body > *:not(.fluid) {
160
132
 
161
133
  /* https://css-tricks.com/background-patterns-simplified-by-conic-gradients/ */
162
134
  .checkerboard {
163
- background: repeating-conic-gradient(var(--neutral) 0% 25%,
164
- transparent 0% 50%) 50% / 20px 20px;
135
+ background: repeating-conic-gradient(var(--neutral) 0% 25%,
136
+ transparent 0% 50%) 50% / 20px 20px;
165
137
  }
166
138
 
167
- /* -----------------------------------------------------------------------------
168
- // #spacing -
169
- // -------------------------------------------------------------------------- */
170
-
171
- /* for inserting an icon using the background-blend-mode technique */
172
- .icon {
173
- display: inline-block;
174
- padding-right: var(--inline-padding);
175
- background-size: var(--text-icon);
176
- background-position: var(--center-right);
177
- background-blend-mode: lighten, normal;
178
- }
179
-
180
- /* leading space for inline ::before elements, typically icons */
181
- .leading {
182
- padding-left: var(--inline-padding);
183
- }
184
-
185
- /* trailing space for inline ::after elements, typically icons */
186
- .trailing {
187
- padding-right: var(--inline-padding);
188
- }
189
139
 
190
140
  /* -----------------------------------------------------------------------------
191
141
  // #layout -
192
142
  // -------------------------------------------------------------------------- */
193
143
 
194
- /* a grid with columns of width var(--column)
195
- // .......................................................................... */
196
- .grid {
197
- display: grid;
198
- grid-template-columns: [full-start] repeat(auto-fit,
199
- minmax(var(--column), 1fr)) [full-end];
200
- column-gap: var(--m);
201
- container-type: none; /* containment clashes with grid on safari */
202
- }
203
-
204
144
  /* main content placement in the holy grail 3-column grid
145
+ // firefox is not forgiving with :has() rules, so this must be separated out
205
146
  // .......................................................................... */
206
- /* firefox is not forgiving with :has() rules, so this must be separated out */
207
147
  .dual-aside { grid-column: 2 / -2; }
208
148
 
209
149
 
210
- /* a basic flex container
211
- ............................................................................ */
212
- .flex {
213
- --flex-break: 100rem; /* TODO/TEMP - a bit of a magical number */
214
- display: flex;
215
- flex-wrap: wrap;
216
- gap: var(--m);
217
- }
218
-
219
- /* flex all the children of .flex to single column below --flex-break */
220
- :where(.flex) > * { /* [0000] specificity */
221
- flex-grow: 1;
222
- flex-basis: calc((var(--flex-break) - 100%) * 999);
223
- }
224
-
225
- .flex > :where(.column, .main) {
226
- /*flex: 1 1 auto;*/
227
- }
228
-
229
-
230
150
  /* -----------------------------------------------------------------------------
231
151
  // #breaks - #br #wbr #hr - line breaks and the horizontal rule
232
152
  // -------------------------------------------------------------------------- */
233
153
 
234
- /* #hr #section - the sectioning horizontal rule - [0011] specificity */
235
- hr.section {
154
+ /* #sectioning - a significant break between sections */
155
+ .sectioning {
236
156
  height: 3rem;
237
157
  margin: auto;
238
158
  width: unset;
@@ -247,9 +167,26 @@ hr.section {
247
167
 
248
168
 
249
169
  /* -----------------------------------------------------------------------------
250
- // #icons - convenience classes for icons defined in icons.css - EXPERIMENTAL
170
+ // #icons - helper classes for icons - EXPERIMENTAL
251
171
  // -------------------------------------------------------------------------- */
252
172
 
173
+ /* for inserting an icon using the background-blend-mode technique */
174
+ .icon {
175
+ display: inline-block;
176
+ padding-right: var(--inline-padding);
177
+ background-size: var(--text-icon);
178
+ background-position: var(--center-right);
179
+ background-blend-mode: lighten, normal;
180
+ }
181
+
182
+ /* leading/trailing space for inline ::before elements, typically icons
183
+ // TODO: investigate using :has() for this on the parent of .icon
184
+ // ........................................................................... */
185
+ .leading { padding-left: var(--inline-padding); }
186
+ .trailing {padding-right: var(--inline-padding); }
187
+
188
+ /* convenience classes for icons defined in icons.css
189
+ // ........................................................................... */
253
190
  .i-burger { --icon: var(--i-burger); }
254
191
  .i-check { --icon: var(--i-check); }
255
192
  .i-chevron { --icon: var(--i-chevron); }
@@ -265,7 +202,8 @@ hr.section {
265
202
  .i-user-circle { --icon: var(--i-user-circle); }
266
203
  .i-user-off { --icon: var(--i-user-off); }
267
204
 
268
- /* #unadorned removes a ::before or ::after icon - [0011] specificity */
205
+ /* removes a ::before or ::after icon - [0011] specificity
206
+ // ........................................................................... */
269
207
  .unadorned::before, .unadorned::after {
270
208
  content: unset;
271
209
  }
@@ -9,22 +9,22 @@
9
9
  // -------------------------------------------------------------------------- */
10
10
 
11
11
  /* #body - auto-grid by default - overrides base.css default body definition.
12
- set --columns to the number of columns desired */
12
+ set --columns to the number of columns desired
13
+ // .......................................................................... */
13
14
  body {
14
15
  display: grid;
15
16
  grid-template-columns: [full-start] var(--padding, var(--m))
16
17
  [padded-start] repeat(var(--columns, auto-fit),
17
18
  minmax(var(--grid), 1fr)) [padded-end]
18
19
  var(--padding, var(--m)) [full-end];
19
- column-gap: var(--gap); /* flexible between 400 - 800px */
20
+ column-gap: var(--gap); /* --gap is fluid between 400 - 800px */
20
21
  max-width: unset;
21
22
  }
22
23
 
23
24
  /* some containers should span full or padded width by default if in the grid */
24
- :where(:not(.grid)) > main { grid-column: padded; }
25
- nav, header, footer {
26
- grid-column: full;
27
- }
25
+ :where(:not(.grid)) > main { grid-column: padded; }
26
+ nav, header, footer { grid-column: full; }
27
+
28
28
 
29
29
  /* the top header typically should sit flush to the top of the page and use
30
30
  padding; TODO: this seems to be over-specified */
@@ -39,11 +39,39 @@ footer {
39
39
  grid-auto-rows: min-content; /* don't unnecessarily expand rows */
40
40
  column-gap: var(--m);
41
41
  container-type: unset; /* safari doesn't like contain with grid */
42
- padding-inline: var(--padding, var(--m)); /* flexible padding */
42
+ /*padding-inline: var(--padding, var(--m));*/ /* flexible padding */
43
43
  }
44
44
 
45
45
  footer > p { grid-column: 1 / -1; } /* take up a whole row in the grid */
46
46
 
47
+ /* HACK: because .100dvi uses a negative margin hack to break out of the parent
48
+ container and extra negative margin to compensate for the vertical scrollbar,
49
+ the content needs more padding on narrower screens to stay visible */
50
+ body > footer:last-of-type:is(._100dvi, [class~="100dvi"]) {
51
+ margin-inline: calc(50% - 50dvi - var(--s));
52
+ padding-inline: var(--m) var(--s); /* asymmetric due to neg. margin;
53
+ centers because --m is twice --s & --s used above */
54
+ }
55
+
56
+ /* a basic flex container
57
+ // .......................................................................... */
58
+ .flex {
59
+ --flex-break: 100rem; /* TODO/TEMP - a bit of a magical number */
60
+ display: flex;
61
+ flex-wrap: wrap;
62
+ gap: var(--m);
63
+ }
64
+
65
+ /* flex all the children of .flex to single column below --flex-break */
66
+ :where(.flex) > * { /* [0000] specificity */
67
+ flex-grow: 1;
68
+ flex-basis: calc((var(--flex-break) - 100%) * 999);
69
+ }
70
+
71
+ .flex > :where(.column, .main) {
72
+ /*flex: 1 1 auto;*/
73
+ }
74
+
47
75
 
48
76
  /* -----------------------------------------------------------------------------
49
77
  // #headings -
@@ -53,13 +81,15 @@ header:not(.banner) {
53
81
  display: flex;
54
82
  flex-wrap: wrap;
55
83
  justify-content: space-between;
84
+ align-items: baseline; /* make sure flexed text lines up visually*/
56
85
  }
57
86
 
58
87
  header :where(h1,h2,h3,h4,h5,h6) {
59
88
  }
60
89
 
61
- header :where(p) {
62
- flex: 1 0 100%;
90
+ /* use <span>, not <p>, for text that sits alongside a heading within a header*/
91
+ header :where(p, .subtitle) {
92
+ flex: 1 0 100%; /* flex to a full row, forcing a line wrap*/
63
93
  }
64
94
 
65
95
 
@@ -91,7 +121,8 @@ header :where(p) {
91
121
  grid-column: unset;
92
122
  flex-direction: column;
93
123
  flex-grow: 1; /* take up the whole role if orphaned */
94
- flex-basis: calc((40vw - 100%) * 999);
124
+ /* flex-basis unnecessary? seems to wrap weirdly at larger viewport widths */
125
+ /*flex-basis: calc((40vw - 100%) * 999);*/
95
126
  align-items: start; /* some items will float otherwise */
96
127
  row-gap: var(--s); /* add some vertical spacing */
97
128
  justify-content: start;
@@ -139,7 +170,7 @@ header :where(p) {
139
170
 
140
171
 
141
172
  /* -----------------------------------------------------------------------------
142
- // #icons - svg icons
173
+ // #i #icons - standalone svg icons
143
174
  // -------------------------------------------------------------------------- */
144
175
 
145
176
  i[class^='i-'] {
@@ -165,6 +196,7 @@ i[class^='i-'] {
165
196
  grid-template-areas: "banner";
166
197
  place-items: center;
167
198
  align-self: flex-start;
199
+ max-width: unset; /* override header max-width in cosmetic.css */
168
200
  height: var(--banner-height);
169
201
  /*max-height: var(--banner-max-height);*/
170
202
  /*background-color: var(--primary-transparent);*/ /* bg color was meant
@@ -179,21 +211,28 @@ i[class^='i-'] {
179
211
  /* banner #content - constrain content width with a css variable set on parent*/
180
212
  .banner .content {
181
213
  width: var(--content-width);
214
+ max-width: 100dvi; /* don't let content overflow viewport */
182
215
  z-index: 0; /* safari uses source order otherwise */
183
216
  }
184
217
 
185
218
  /* banner grid */
186
219
  .banner > * { grid-area: banner; }
187
220
  .banner > nav {
188
- place-self: start center;
221
+ place-self: flex-start center;
189
222
  width: var(--line-length);
223
+ max-width: 100dvi; /* make sure nav doesn't go off-screen */
190
224
  }
191
225
  .banner nav menu { /*flex: auto;*/ }
192
226
 
227
+ /* TODO: use fluid padding on non-hero children rather than container query? */
228
+ @container (width <= 50rem) {
229
+ .banner > :not(img, .hero) { padding-inline: var(--s); }
230
+ }
231
+
193
232
  .banner > img, .hero {
194
233
  height: min(var(--banner-height), var(--banner-max-height));
195
234
  width: 100%;
196
- max-width: none;
235
+ max-width: none; /* TODO: should this be broken out separately?*/
197
236
  z-index: -1;
198
237
  }
199
238
 
@@ -316,6 +355,7 @@ body > nav a, body > header > nav a {
316
355
  outline: none;
317
356
  border: none;
318
357
  width: var(--height); /* form icons are square */
358
+ max-width: 100cqi;
319
359
  min-width: 0;
320
360
  padding: 0;
321
361
  cursor: pointer; /* unconventional usage for 'clickable' */
@@ -563,7 +603,7 @@ button.tertiary, .tertiary.button { /* [0011] / [0020] specificity */
563
603
  // .......................................................................... */
564
604
 
565
605
  /* TODO: the main form grid should inline elements rather than forcing it here
566
- .bottons inlines/wraps multiple buttons where necessary - [0010] specificity*/
606
+ .buttons inlines/wraps multiple buttons where necessary - [0010] specificity*/
567
607
  .buttons {
568
608
  list-style: none;
569
609
  display: flex; /* overwrite display: grid; */
@@ -584,11 +624,12 @@ form .buttons { max-width: var(--field-max) }
584
624
  .roomy.buttons { gap: var(--ml); }
585
625
 
586
626
  /* fix buttons floating and getting squished at smaller screen widths */
587
- @container (max-width: 28rem) {
627
+ @container (width <= 28rem) {
588
628
  form { max-width: unset; }
589
629
  form .buttons {
590
- max-width: unset;
591
- grid-column: -1/1;
630
+ max-width: unset; /* don't constrain width in narrow confines */
631
+ grid-column: -1/1; /* span the entire grid for more room */
632
+ justify-content: flex-end; /* end-align looks more natural than start*/
592
633
  }
593
634
  label { font-size: var(--small); }
594
635
  }
@@ -658,6 +699,18 @@ nav:has(.toggle[aria-expanded=false]) > menu {
658
699
  [rel~="external"].button:hover::after { background-color: var(--foreground); }
659
700
 
660
701
 
702
+ /* #button_to - a rails class set on forms that look like buttons - minimize the
703
+ // form width while maximizing the button within to that form width
704
+ // .......................................................................... */
705
+ .button_to {
706
+ width: min-content;
707
+ /*HACK: an inline-size container-type make forms zero-width, so make it normal*/
708
+ container-type: normal;
709
+ }
710
+ .button_to > [type="submit"] {
711
+ width: max-content;
712
+ }
713
+
661
714
 
662
715
  /* -----------------------------------------------------------------------------
663
716
  // #selectmenu - Open UI replacement to the standard select element -
@@ -732,7 +785,7 @@ selectmenu::part(listbox) {
732
785
  margin-top: auto; /* make sure buttons are at the bottom */
733
786
  }
734
787
 
735
- @container (min-width: 35rem) {
788
+ @container (width >= 35rem) {
736
789
  /*.card { flex-direction: row; }*/ /* interferes with single-card section */
737
790
  .card > img, .cards > article > img {
738
791
  max-height: var(--width);
@@ -745,19 +798,6 @@ selectmenu::part(listbox) {
745
798
  }
746
799
  }
747
800
 
748
- /* TEMP: use media queries for browsers that don't support container queries */
749
- @supports not (container-type: inline-size) {
750
- @media (min-width: 47rem) {
751
- /*.card { flex-direction: row; }*/ /* interferes with single-card section */
752
- .card > img, .cards > article > img {
753
- max-height: var(--width);
754
- max-width: var(--width);
755
- }
756
- .cards :last-child:nth-child(3n - 2) {
757
- grid-column-end: span 3;
758
- flex-direction: row;
759
- }
760
- }}
761
801
 
762
802
  /* -----------------------------------------------------------------------------
763
803
  // #tags - an inline list of metatags; can be text, links, icons, or other
@@ -771,7 +811,8 @@ selectmenu::part(listbox) {
771
811
  padding: 0;
772
812
  }
773
813
 
774
- .tags > li {
814
+ /* TODO: .tag should be in classes.css and kept in sync with this rule? */
815
+ .tags > li, .tag {
775
816
  display: inline-block;
776
817
  color: var(--secondary);
777
818
  font-size: var(--small);
@@ -793,12 +834,6 @@ selectmenu::part(listbox) {
793
834
  margin-bottom: var(--m);
794
835
  }
795
836
 
796
- /* TEMP: add margin-top to buttons for browsers that don't support :has() */
797
- @supports not (:has(a)) {
798
- .tags + .buttons {
799
- margin-top: var(--m);
800
- }}
801
-
802
837
 
803
838
  /* -----------------------------------------------------------------------------
804
839
  // #grid - multi-column grid adjustments
@@ -814,12 +849,6 @@ selectmenu::part(listbox) {
814
849
  container-type: none; /* containment clashes with grid on safari */
815
850
  }
816
851
 
817
- /* for layouts with left & right asides, put main in the middle grid columns */
818
- /* grrr, firefox is not forgiving with :has() rules, so this must be separated*/
819
- .dual-aside {
820
- grid-column: 2 / -2;
821
- }
822
-
823
852
  /*full is a grid area for a row that spans all columns - [0000] specificity */
824
853
  :where(.grid) > :where(header,hgroup,h1,h2,h3,h4,h5,h6,nav:not(.column),footer){
825
854
  grid-column: full;
@@ -911,7 +940,7 @@ selectmenu::part(listbox) {
911
940
  // #progressbar - a circular progress bar component - from almond.css
912
941
  // -------------------------------------------------------------------------- */
913
942
 
914
- [role="progressbar"] {
943
+ [role="progressbar"] {
915
944
  --value: 50;
916
945
  --thick: 50%;
917
946
  --medium: 58%;