@uncinq/css-components 1.17.0 → 1.19.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.
- package/README.md +2 -2
- package/css/components/button.css +1 -1
- package/css/components/push.css +272 -0
- package/css/index.css +1 -0
- package/docs/buttons/btn.md +2 -0
- package/docs/cascade-layers.md +1 -1
- package/docs/content/_index.md +1 -1
- package/docs/content/overview.md +3 -2
- package/docs/content/push.md +106 -0
- package/docs/content/surtitle.md +1 -1
- package/docs/overview.md +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<img width="1280" height="640" alt="share-css-components" src="https://github.com/user-attachments/assets/3d74df8a-e7bf-4ba5-8529-99cfef0bc176" />
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
30 components and 1 utility, written as plain CSS, reading their values from [@uncinq/component-tokens](https://github.com/uncinq/component-tokens) and adding none of their own.
|
|
8
8
|
|
|
9
9
|
## Where this sits
|
|
10
10
|
|
|
@@ -55,7 +55,7 @@ The failure is silent. No error is raised, the page simply stays at its mobile v
|
|
|
55
55
|
| --- | --- |
|
|
56
56
|
| Buttons | `.btn` with colour, size and style variants, plus `btn-close`, `btn-menu`, `btn-search`, `btn-filter`, `btn-share`, `btn-toc`, `btn-toggle-video` |
|
|
57
57
|
| Overlays | `modal`, `drawer`, `dropdown`, and the shared panel skeleton |
|
|
58
|
-
| Content | `alert`, `badge`, `banner`, `card`, `items`, `list`, `media`, `surtitle` |
|
|
58
|
+
| Content | `alert`, `badge`, `banner`, `card`, `items`, `list`, `media`, `push`, `surtitle` |
|
|
59
59
|
| Navigation | `nav`, `nav-title`, `nav-accessibility`, `breadcrumb`, `pagination` |
|
|
60
60
|
| Embeds | `embed`, `video`, `map` |
|
|
61
61
|
| Forms | `form`, `form-check` and the layout helpers |
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
background-color: var(--btn-color-background-hover);
|
|
43
43
|
border-color: var(--btn-color-border-hover);
|
|
44
44
|
box-shadow: var(--btn-shadow-hover);
|
|
45
|
-
color: var(--btn-color-text-hover);
|
|
45
|
+
color: var(--btn-color-text-hover, var(--btn-color-text));
|
|
46
46
|
text-decoration-color: var(--btn-color-text-decoration-hover);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/* components/push.css */
|
|
2
|
+
/*
|
|
3
|
+
* .push — a video or an image with a surtitle, title, text and CTA laid over it.
|
|
4
|
+
* Reads --push-* from @uncinq/component-tokens.
|
|
5
|
+
*
|
|
6
|
+
* Structure, the same for every modifier:
|
|
7
|
+
* <div class="push">
|
|
8
|
+
* <div class="content">
|
|
9
|
+
* <p class="surtitle">...</p>
|
|
10
|
+
* <h2 class="title">...</h2>
|
|
11
|
+
* <div class="text">...</div>
|
|
12
|
+
* <a class="btn">...</a>
|
|
13
|
+
* </div>
|
|
14
|
+
* <div class="media">
|
|
15
|
+
* picture | .video > video
|
|
16
|
+
* </div>
|
|
17
|
+
* </div>
|
|
18
|
+
*
|
|
19
|
+
* The push carries the ratio and places .content inside it; .content is only
|
|
20
|
+
* the text box, which .push-card turns into a card. The ratio is drawn by
|
|
21
|
+
* .push::after, so that pseudo-element is taken.
|
|
22
|
+
*
|
|
23
|
+
* Modifiers:
|
|
24
|
+
* .push-center | .push-end horizontal position of the content
|
|
25
|
+
* .push-align-start | -center | -end text alignment
|
|
26
|
+
* .push-vertical-start | .push-vertical-end vertical position of the content
|
|
27
|
+
* .push-card background behind the text
|
|
28
|
+
* .push-darken gradient under the text
|
|
29
|
+
*/
|
|
30
|
+
@layer components {
|
|
31
|
+
.push {
|
|
32
|
+
--media-color-background: var(--push-color-background);
|
|
33
|
+
--ratio-video: auto;
|
|
34
|
+
|
|
35
|
+
border-radius: var(--push-border-radius);
|
|
36
|
+
display: grid;
|
|
37
|
+
/* A fixed track: sized by its content, it would widen to the ratio box's
|
|
38
|
+
transferred size whenever the push is stretched by a min-height. */
|
|
39
|
+
grid-template-columns: minmax(0, 1fr);
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
padding-block: var(--push-content-padding-block);
|
|
42
|
+
padding-inline: var(--push-content-padding-inline);
|
|
43
|
+
position: relative;
|
|
44
|
+
|
|
45
|
+
@media (--sm) {
|
|
46
|
+
--push-content-max-inline-size: var(--push-content-max-inline-size-tablet);
|
|
47
|
+
}
|
|
48
|
+
@media (--lg) {
|
|
49
|
+
--push-content-max-inline-size: var(--push-content-max-inline-size-laptop);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* The ratio: an empty box sharing the single grid cell with .content, and
|
|
53
|
+
stretched over the padding by negative margins so that the ratio is the
|
|
54
|
+
push's own. The push takes the taller of the two, so a text that needs
|
|
55
|
+
more room grows it rather than being cut, even under a min-height. */
|
|
56
|
+
&::after {
|
|
57
|
+
aspect-ratio: var(--push-ratio-mobile);
|
|
58
|
+
content: '';
|
|
59
|
+
grid-area: 1 / 1;
|
|
60
|
+
justify-self: stretch;
|
|
61
|
+
margin-block: calc(var(--push-content-padding-block) * -1);
|
|
62
|
+
margin-inline: calc(var(--push-content-padding-inline) * -1);
|
|
63
|
+
|
|
64
|
+
@media (--sm) {
|
|
65
|
+
aspect-ratio: var(--push-ratio);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
&:not(.push-card) {
|
|
70
|
+
--btn-color-background: var(--color-light);
|
|
71
|
+
--btn-color-background-hover: var(--color-light-hover);
|
|
72
|
+
--btn-color-border: var(--color-light);
|
|
73
|
+
--btn-color-border-hover: var(--color-light-hover);
|
|
74
|
+
--btn-color-text: var(--color-text-on-light);
|
|
75
|
+
--color-heading: var(--push-color);
|
|
76
|
+
--color-link: var(--push-color);
|
|
77
|
+
--color-link-hover: var(--push-color);
|
|
78
|
+
--surtitle-color-text: var(--push-surtitle-color, oklch(from var(--push-color) l c h / var(--opacity-muted)));
|
|
79
|
+
|
|
80
|
+
color: var(--push-color);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* A grid item stacks above the media and the darken overlay through its
|
|
84
|
+
z-index alone. Left unpositioned, it is no containing block, so the
|
|
85
|
+
.btn::after overlay below covers the whole push, not just the text. */
|
|
86
|
+
> .content {
|
|
87
|
+
align-self: var(--push-content-justify, center);
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
gap: var(--push-content-gap);
|
|
91
|
+
grid-area: 1 / 1;
|
|
92
|
+
justify-self: var(--push-content-items, flex-start);
|
|
93
|
+
max-inline-size: var(--push-content-max-inline-size);
|
|
94
|
+
width: 100%;
|
|
95
|
+
z-index: 1;
|
|
96
|
+
|
|
97
|
+
@media (--sm) {
|
|
98
|
+
text-align: var(--push-content-align);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
> * {
|
|
102
|
+
margin-block: 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* The button keeps its own width rather than stretching across the
|
|
106
|
+
box, and follows the text alignment, which applies from --sm up. */
|
|
107
|
+
> .btn {
|
|
108
|
+
align-self: start;
|
|
109
|
+
|
|
110
|
+
@media (--sm) {
|
|
111
|
+
align-self: var(--push-content-align, start);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* A background: clicks go through it, to the push's own link. */
|
|
117
|
+
.media {
|
|
118
|
+
height: 100%;
|
|
119
|
+
inset: 0;
|
|
120
|
+
pointer-events: none;
|
|
121
|
+
position: absolute;
|
|
122
|
+
width: 100%;
|
|
123
|
+
|
|
124
|
+
/* …except the pause control a .video lays over an autoplaying video,
|
|
125
|
+
which has to stay usable (WCAG 2.2.2). */
|
|
126
|
+
.btn-toggle-video {
|
|
127
|
+
pointer-events: auto;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Safari draws a play button over a video it refuses to autoplay, in
|
|
131
|
+
Low Power Mode for one. The button sits in the browser's shadow DOM,
|
|
132
|
+
which only gives way to !important. */
|
|
133
|
+
video::-webkit-media-controls-start-playback-button {
|
|
134
|
+
-webkit-appearance: none;
|
|
135
|
+
display: none !important;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.surtitle {
|
|
140
|
+
margin-block-end: calc(var(--push-content-gap) * -1);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.btn::after {
|
|
144
|
+
content: '';
|
|
145
|
+
inset: 0;
|
|
146
|
+
position: absolute;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Card: the text box takes the look of a .card. Each value reads an optional
|
|
151
|
+
--push-card-* first, unset by default, so push cards can be restyled
|
|
152
|
+
without touching the cards themselves. */
|
|
153
|
+
.push-card > .content {
|
|
154
|
+
background-color: var(--push-card-color-background, var(--card-color-background));
|
|
155
|
+
border-color: var(--push-card-color-border, var(--card-color-border));
|
|
156
|
+
border-radius: var(--push-card-border-radius, var(--card-border-radius));
|
|
157
|
+
border-style: var(--push-card-border-style, var(--card-border-style));
|
|
158
|
+
border-width: var(--push-card-border-width, var(--card-border-width));
|
|
159
|
+
box-shadow: var(--push-card-shadow, var(--card-shadow));
|
|
160
|
+
color: var(--push-card-color-text, var(--card-color-text));
|
|
161
|
+
padding-block: var(--push-card-padding-block, var(--card-padding-block));
|
|
162
|
+
padding-inline: var(--push-card-padding-inline, var(--card-padding-inline));
|
|
163
|
+
|
|
164
|
+
> .title {
|
|
165
|
+
color: var(--push-card-title-color, var(--card-title-color));
|
|
166
|
+
font-family: var(--push-card-title-font-family, var(--card-title-font-family));
|
|
167
|
+
font-size: var(--push-card-title-font-size, var(--card-title-font-size));
|
|
168
|
+
font-weight: var(--push-card-title-font-weight, var(--card-title-font-weight));
|
|
169
|
+
line-height: var(--push-card-title-line-height, var(--card-title-line-height));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
173
|
+
transition: var(--push-card-transition, var(--card-transition));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@media (hover: hover) and (pointer: fine) {
|
|
178
|
+
.push-card:hover > .content {
|
|
179
|
+
--push-card-shadow: var(--push-card-shadow-hover, var(--card-shadow-hover));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Darken */
|
|
184
|
+
.push-darken {
|
|
185
|
+
/* Logical gradient directions (flipped under RTL) */
|
|
186
|
+
--push-gradient-to-end: to right; /* toward inline-end */
|
|
187
|
+
--push-gradient-to-start: to left; /* toward inline-start */
|
|
188
|
+
|
|
189
|
+
/* The shadow comes from the edge the content sits against. Only this
|
|
190
|
+
variable changes from one variant to the next; the ::before below is
|
|
191
|
+
the single place that paints it. */
|
|
192
|
+
--push-darken: linear-gradient(var(--push-gradient-to-end), var(--push-gradient-color-from) 0%, var(--push-gradient-color-to) var(--push-gradient-stop));
|
|
193
|
+
|
|
194
|
+
&:dir(rtl) {
|
|
195
|
+
--push-gradient-to-end: to left;
|
|
196
|
+
--push-gradient-to-start: to right;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@media (--sm) {
|
|
200
|
+
&.push-end {
|
|
201
|
+
--push-darken: linear-gradient(var(--push-gradient-to-start), var(--push-gradient-color-from) 0%, var(--push-gradient-color-to) var(--push-gradient-stop));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* A vertical offset tilts the gradient the same way, as in .hero.
|
|
206
|
+
Declared after the horizontal ones, so it wins when both are set. */
|
|
207
|
+
&.push-vertical-start {
|
|
208
|
+
--push-darken: linear-gradient(to bottom, var(--push-gradient-color-from) 0%, var(--push-gradient-color-to) var(--push-gradient-stop));
|
|
209
|
+
}
|
|
210
|
+
&.push-vertical-end {
|
|
211
|
+
--push-darken: linear-gradient(to top, var(--push-gradient-color-from) 0%, var(--push-gradient-color-to) var(--push-gradient-stop));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* …except when the text carries its own background, or is centered: the
|
|
215
|
+
media is dimmed as a whole instead. */
|
|
216
|
+
&.push-card,
|
|
217
|
+
&.push-center {
|
|
218
|
+
--push-darken: transparent;
|
|
219
|
+
|
|
220
|
+
.media {
|
|
221
|
+
filter: brightness(var(--push-media-brightness));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Painted on the push itself, edge to edge: .content is only the text box.
|
|
226
|
+
Same layering as .hero: the overlay sits above the media, the content
|
|
227
|
+
above the overlay. */
|
|
228
|
+
&::before {
|
|
229
|
+
background: var(--push-darken);
|
|
230
|
+
content: '';
|
|
231
|
+
inset: 0;
|
|
232
|
+
pointer-events: none;
|
|
233
|
+
position: absolute;
|
|
234
|
+
z-index: 1;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* Offset: horizontal position of the content */
|
|
239
|
+
.push-center {
|
|
240
|
+
@media (--sm) {
|
|
241
|
+
--push-content-items: center;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.push-end {
|
|
246
|
+
@media (--sm) {
|
|
247
|
+
--push-content-items: flex-end;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* Text alignment */
|
|
252
|
+
.push-align-start {
|
|
253
|
+
--push-content-align: start;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.push-align-center {
|
|
257
|
+
--push-content-align: center;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.push-align-end {
|
|
261
|
+
--push-content-align: end;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Vertical position of the content (centered by default) */
|
|
265
|
+
.push-vertical-start {
|
|
266
|
+
--push-content-justify: flex-start;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.push-vertical-end {
|
|
270
|
+
--push-content-justify: flex-end;
|
|
271
|
+
}
|
|
272
|
+
}
|
package/css/index.css
CHANGED
package/docs/buttons/btn.md
CHANGED
|
@@ -44,6 +44,8 @@ Each sets four properties together: background, border, their hover values, and
|
|
|
44
44
|
|
|
45
45
|
The text colour always comes from the matching `--color-text-on-*` semantic token, so contrast survives a change to the underlying colour. That pairing is the reason to rebrand by redefining `--color-brand` rather than `--btn-color-background`.
|
|
46
46
|
|
|
47
|
+
The text keeps its colour on hover: `.btn` reads `var(--btn-color-text-hover, var(--btn-color-text))`, and `--btn-color-text-hover` is no token, so it is unset unless a variant or a context sets it. A context that recolours its buttons, as a push over a dark media does, only needs `--btn-color-text`.
|
|
48
|
+
|
|
47
49
|
`.btn-primary` and `.btn-brand` resolve to exactly the same values, as do `.btn-secondary` and `.btn-neutral`. The intent names exist so a page can say *primary action* without deciding which colour that is.
|
|
48
50
|
|
|
49
51
|
## Sizes
|
package/docs/cascade-layers.md
CHANGED
|
@@ -10,7 +10,7 @@ This package writes to two layers.
|
|
|
10
10
|
|
|
11
11
|
| Layer | Contents |
|
|
12
12
|
| --- | --- |
|
|
13
|
-
| `@layer components` | All
|
|
13
|
+
| `@layer components` | All 30 components |
|
|
14
14
|
| `@layer utilities` | `.scrollsnap`, the only utility |
|
|
15
15
|
|
|
16
16
|
The full order, including layers owned by the sibling packages and by the project itself, is the **consuming project's** responsibility. Declare it once, at the very top of your entry stylesheet, before any `@import`:
|
package/docs/content/_index.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
isIndex: false
|
|
3
3
|
title: Content
|
|
4
|
-
description: Alerts, badges, banners, cards, the items grid, labelled lists, media objects and surtitles.
|
|
4
|
+
description: Alerts, badges, banners, cards, the items grid, labelled lists, media objects, pushes and surtitles.
|
|
5
5
|
weight: 5
|
|
6
6
|
icon: card-text
|
|
7
7
|
---
|
package/docs/content/overview.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
isIndex: false
|
|
3
3
|
title: Overview
|
|
4
|
-
description: The
|
|
4
|
+
description: The nine content components, the three that are meant to nest, and the two colour patterns they follow.
|
|
5
5
|
weight: 1
|
|
6
6
|
icon: book
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Nine components for laying out page content.
|
|
10
10
|
|
|
11
11
|
| Page | Class | Purpose |
|
|
12
12
|
| --- | --- | --- |
|
|
@@ -17,6 +17,7 @@ Eight components for laying out page content.
|
|
|
17
17
|
| [Items](../items/) | `.items` | The responsive grid that holds cards |
|
|
18
18
|
| [List](../list/) | `.list` | A compact labelled list |
|
|
19
19
|
| [Media](../media/) | `.media` | The structural base for images and video |
|
|
20
|
+
| [Push](../push/) | `.push` | A video or image with text and a call to action laid over it |
|
|
20
21
|
| [Surtitle](../surtitle/) | `.surtitle` | An eyebrow label above a heading |
|
|
21
22
|
|
|
22
23
|
## Three of them are meant to nest
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
isIndex: false
|
|
3
|
+
title: Push
|
|
4
|
+
description: A video or image with text laid over it, how the push places its text box, the position and darken modifiers, and the card variant.
|
|
5
|
+
weight: 9
|
|
6
|
+
icon: image
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
A video or an image with a surtitle, a title, some text and a call to action laid over it.
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<div class="push push-darken">
|
|
13
|
+
<div class="content">
|
|
14
|
+
<p class="surtitle">Collection</p>
|
|
15
|
+
<h2 class="title">Push title</h2>
|
|
16
|
+
<div class="text"><p>Short text.</p></div>
|
|
17
|
+
<a class="btn" href="/collection">Discover</a>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="media">
|
|
20
|
+
<picture>...</picture>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Child | Role |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `.content` | The text box, placed inside the push |
|
|
28
|
+
| `.media` | The image or video, stretched behind the content, see [Media](../media/) |
|
|
29
|
+
| `.surtitle` | An optional eyebrow, pulled back by one gap, see [Surtitle](../surtitle/) |
|
|
30
|
+
| `.btn` | The call to action, whose `::after` makes the whole push clickable |
|
|
31
|
+
|
|
32
|
+
The markup is the same for every modifier: switching a push to a card, or moving its text, is a class change, never a change of structure.
|
|
33
|
+
|
|
34
|
+
## The push carries the ratio
|
|
35
|
+
|
|
36
|
+
The push is a one-cell grid with the content padding. Two boxes share that cell: `.content`, placed by the position modifiers below, and an empty `::after` that carries the ratio, `--push-ratio-mobile` below `--sm` and `--push-ratio` from `--sm` up. Negative margins stretch that box over the padding, so the ratio is the push's own. `.media` is absolutely positioned and fills the push.
|
|
37
|
+
|
|
38
|
+
The push takes the taller of the two boxes: a text that needs more room than the ratio leaves grows the push instead of being cut, even when a layout gives the push a `min-height` to fill its row. The single track is fixed to `minmax(0, 1fr)`, so the ratio box never widens it. To change the shape of one push, override the two ratio tokens on it rather than setting a height.
|
|
39
|
+
|
|
40
|
+
`.push::after` is therefore taken; `::before` is the darken overlay.
|
|
41
|
+
|
|
42
|
+
`--push-ratio-double` is not read here. It is a second ratio for layouts that set two pushes side by side and want a taller shape than a full-width one.
|
|
43
|
+
|
|
44
|
+
## The media is a background
|
|
45
|
+
|
|
46
|
+
`.media` takes `pointer-events: none`: a click on the image or the video goes through to the push and its link, and a tap never starts or pauses a video. The pause control that a [`.video`](../../embeds/video/) lays over an autoplaying video is the exception, set back to `pointer-events: auto`, since WCAG requires a way to stop it. A video that needs its native `controls` does not belong in a push.
|
|
47
|
+
|
|
48
|
+
Safari draws a play button over a video it refuses to autoplay, in Low Power Mode for instance. The push hides it through `::-webkit-media-controls-start-playback-button`, with the one `!important` of the component: the button lives in the browser's shadow DOM, and nothing weaker overrides it there. The video then shows its first frame, or its poster.
|
|
49
|
+
|
|
50
|
+
## What the push hands down
|
|
51
|
+
|
|
52
|
+
Unless it has `.push-card`, a push sets the text, heading, link and surtitle colours from `--push-color`, and turns `.btn` into a light button that reads on a dark media. `--push-surtitle-color` overrides the surtitle colour alone; it is unset by default, and the surtitle falls back to `--push-color` at `--opacity-muted`.
|
|
53
|
+
|
|
54
|
+
It also reassigns two other namespaces:
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
--media-color-background: var(--push-color-background);
|
|
58
|
+
--ratio-video: auto;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The background colour shows while the media loads, or behind an image with transparent areas. `--ratio-video: auto` lets a `.video` inside the push fill it instead of imposing its own ratio.
|
|
62
|
+
|
|
63
|
+
## Position and alignment
|
|
64
|
+
|
|
65
|
+
The content is centred vertically and sits at the start horizontally by default. Three groups of modifiers move it.
|
|
66
|
+
|
|
67
|
+
| Modifier | Effect |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `.push-center`, `.push-end` | Horizontal position of the content, from `--sm` up |
|
|
70
|
+
| `.push-align-start`, `-center`, `-end` | Text alignment, from `--sm` up |
|
|
71
|
+
| `.push-vertical-start`, `.push-vertical-end` | Vertical position of the content |
|
|
72
|
+
|
|
73
|
+
Each one only sets a private variable (`--push-content-items`, `--push-content-align`, `--push-content-justify`), so they combine freely. The content is capped at `--push-content-max-inline-size`, which narrows at `--sm` and `--lg` so that a line of text never spans a full-width push. Those steps follow the viewport, not the push: a layout that sets pushes side by side should reset the token to `100%` on them.
|
|
74
|
+
|
|
75
|
+
The `.btn` keeps its own width rather than stretching across the content, and follows the text alignment from `--sm` up, like the rest of the text.
|
|
76
|
+
|
|
77
|
+
A push stretched taller than its ratio, by a grid row or a carousel track, keeps its content where the modifiers put it within the whole height.
|
|
78
|
+
|
|
79
|
+
## Darken
|
|
80
|
+
|
|
81
|
+
`.push-darken` paints a gradient between the media and the content, from the edge the content sits against: the start edge by default, the end edge with `.push-end`, the top or bottom with a vertical modifier. Directions flip under `:dir(rtl)`.
|
|
82
|
+
|
|
83
|
+
The gradient is painted by a `::before` on the push itself, edge to edge, since `.content` is only the text box.
|
|
84
|
+
|
|
85
|
+
With `.push-center` or `.push-card` there is no edge to darken from, so the whole media is dimmed instead, with `filter: brightness(var(--push-media-brightness))`. That token references `--hero-media-brightness` by default, so a push and a hero dim their media alike.
|
|
86
|
+
|
|
87
|
+
## Card
|
|
88
|
+
|
|
89
|
+
`.push-card` puts the text on a background of its own, for media too busy to read text over. Nothing changes in the markup: `.content` itself takes the look of a [card](../card/).
|
|
90
|
+
|
|
91
|
+
It reads the card tokens for its background, border, radius, shadow, text colour, padding, title typography and transition. Each one goes through an optional `--push-card-*` of the same name first, unset by default:
|
|
92
|
+
|
|
93
|
+
```css
|
|
94
|
+
border-radius: var(--push-card-border-radius, var(--card-border-radius));
|
|
95
|
+
padding-block: var(--push-card-padding-block, var(--card-padding-block));
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Override `--push-card-*` to restyle every push card without touching the cards themselves, or `--card-*` to change both. Its shadow swaps to `--push-card-shadow-hover`, falling back to `--card-shadow-hover`, when the push is hovered. A push card does not inherit `--push-color`, so its text keeps the card colours.
|
|
99
|
+
|
|
100
|
+
## The whole-push link
|
|
101
|
+
|
|
102
|
+
`.btn::after` lays an overlay across the push, so a click anywhere on it follows the call to action.
|
|
103
|
+
|
|
104
|
+
`.content` stacks above the media and the darken overlay through its `z-index` as a grid item, without being positioned, so it is no containing block: the overlay resolves against the push and covers it entirely. Anything that does make `.content` a containing block, such as a `transform` or `translate` from an entrance animation, narrows the clickable area to the text box.
|
|
105
|
+
|
|
106
|
+
As with the [whole-card link](../card/#the-whole-card-link), a push with more than one interactive element needs a different structure, since the overlay covers the others.
|
package/docs/content/surtitle.md
CHANGED
package/docs/overview.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
isIndex: false
|
|
3
3
|
title: Overview
|
|
4
|
-
description: The
|
|
4
|
+
description: The 30 components and 1 utility, how to install them, the import order inside the package, and what it deliberately leaves out.
|
|
5
5
|
weight: 1
|
|
6
6
|
icon: book
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
`@uncinq/css-components` is the top of the stack:
|
|
9
|
+
`@uncinq/css-components` is the top of the stack: 30 components and 1 utility, written as plain CSS, reading their values from [@uncinq/component-tokens](../../component-tokens/) and adding no values of their own.
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
@uncinq/design-tokens primitive + semantic values
|
|
@@ -25,7 +25,7 @@ One page per component, grouped into six sections.
|
|
|
25
25
|
| --- | --- |
|
|
26
26
|
| [Buttons](../buttons/) | [`.btn`](../buttons/btn/), [`.btn-close`](../buttons/btn-close/), [`.btn-menu`](../buttons/btn-menu/), [`.btn-search`](../buttons/btn-search/), [`.btn-filter`](../buttons/btn-filter/), [`.btn-share`](../buttons/btn-share/), [`.btn-toc`](../buttons/btn-toc/), [`.btn-toggle-video`](../buttons/btn-toggle-video/) |
|
|
27
27
|
| [Overlays](../overlays/) | [panel](../overlays/panel/), [`.modal`](../overlays/modal/), [`.drawer`](../overlays/drawer/), [`.dropdown`](../overlays/dropdown/) |
|
|
28
|
-
| [Content](../content/) | [`.alert`](../content/alert/), [`.badge`](../content/badge/), [`.banner`](../content/banner/), [`.card`](../content/card/), [`.items`](../content/items/), [`.list`](../content/list/), [`.media`](../content/media/), [`.surtitle`](../content/surtitle/) |
|
|
28
|
+
| [Content](../content/) | [`.alert`](../content/alert/), [`.badge`](../content/badge/), [`.banner`](../content/banner/), [`.card`](../content/card/), [`.items`](../content/items/), [`.list`](../content/list/), [`.media`](../content/media/), [`.push`](../content/push/), [`.surtitle`](../content/surtitle/) |
|
|
29
29
|
| [Navigation](../navigation/) | [`.nav`](../navigation/nav/), [`.nav-title`](../navigation/nav-title/), [`.nav-accessibility`](../navigation/nav-accessibility/), [`.breadcrumb-wrapper`](../navigation/breadcrumb/), [`.pagination`](../navigation/pagination/) |
|
|
30
30
|
| [Embeds](../embeds/) | [`.embed`](../embeds/embed/), [`.video`](../embeds/video/), [`.map`](../embeds/map/) |
|
|
31
31
|
| [Forms](../forms/) | [`.form`](../forms/form/), [`.form-check`](../forms/form-check/) |
|