|
11 | 11 | @use '../../mixins/headings'; |
12 | 12 | @use '../../mixins/media-query'; |
13 | 13 | @use '../../mixins/ms'; |
| 14 | +@use '../../mixins/spacing'; |
14 | 15 | @use '../../mixins/theme'; |
15 | 16 |
|
16 | 17 | /// We can't use `grid-gap` exclusively due to some containers only being |
@@ -39,6 +40,20 @@ $_cover-gap: ms.step(1, 1rem); |
39 | 40 |
|
40 | 41 | $_focus-overflow: (size.$edge-large * -1); |
41 | 42 |
|
| 43 | +/// The cloudy modifier adds clouds to the bottom right corner and also applies |
| 44 | +/// some fluid padding to accommodate. The clouds feel best when they are sized |
| 45 | +/// just a _tad_ larger than this fluid padding. |
| 46 | +/// |
| 47 | +/// @type Number |
| 48 | +/// @access private |
| 49 | + |
| 50 | +$_cloud-height: fluid.fluid-clamp( |
| 51 | + size.$padding-container-vertical-min * 1.33, |
| 52 | + size.$padding-container-vertical-max * 1.33, |
| 53 | + breakpoint.$s, |
| 54 | + breakpoint.$m |
| 55 | +); |
| 56 | + |
42 | 57 | /** |
43 | 58 | * The main card container |
44 | 59 | * |
@@ -127,6 +142,57 @@ $_focus-overflow: (size.$edge-large * -1); |
127 | 142 | } |
128 | 143 | } |
129 | 144 |
|
| 145 | +/** |
| 146 | + * Cloudy modifier |
| 147 | + * |
| 148 | + * Chrome and Safari often introduce little subpixel artifacts between the edge |
| 149 | + * of a bottom-right image or positioned element that is sized responsively. To |
| 150 | + * minimize this, we assume that this modifier will be shown on a default/light |
| 151 | + * background, and we use a pseudo element for the cloud of the same color so |
| 152 | + * we can offset it slightly (which overlays any artifacting). |
| 153 | + * |
| 154 | + * 1. On the element itself we can include the "background" clouds. These are |
| 155 | + * lower contrast so the artifacting is less noticeable, and they do not |
| 156 | + * match light backgrounds so we can't offset them. |
| 157 | + * 2. We include more generous spacing to account for the clouds. It is still |
| 158 | + * theoretically possible for content to overlap the clouds, so this modifier |
| 159 | + * should be used carefully. |
| 160 | + */ |
| 161 | + |
| 162 | +.c-card--cloudy { |
| 163 | + @include spacing.fluid-padding-block; /* 2 */ |
| 164 | + @include spacing.fluid-padding-inline; /* 2 */ |
| 165 | + background-image: svg-load('clouds/background.svg'); /* 1 */ |
| 166 | + background-position: bottom right; |
| 167 | + background-repeat: no-repeat; |
| 168 | + background-size: auto $_cloud-height; |
| 169 | +} |
| 170 | + |
| 171 | +/** |
| 172 | + * Pseudo element used to position the cloud matching the container background, |
| 173 | + * offset to obscure rounding artifacts. |
| 174 | + * |
| 175 | + * 1. Fluid sizing based on asset's natural dimensions, since we don't have an |
| 176 | + * `auto` width in this context. |
| 177 | + * 2. Offsetting to obscure artifacts. |
| 178 | + * 3. Prevent pointer events so that cloud can never block interactions (clicks, |
| 179 | + * text selection, etc.) |
| 180 | + */ |
| 181 | + |
| 182 | +.c-card--cloudy::before { |
| 183 | + aspect-ratio: 580 / 220; /* 1 */ |
| 184 | + background-image: svg-load('clouds/foreground.svg'); |
| 185 | + background-position: bottom right; |
| 186 | + background-repeat: no-repeat; |
| 187 | + background-size: contain; |
| 188 | + block-size: $_cloud-height; /* 1 */ |
| 189 | + content: ''; |
| 190 | + inset-block-end: -1px; /* 2 */ |
| 191 | + inset-inline-end: -1px; /* 2 */ |
| 192 | + pointer-events: none; /* 3 */ |
| 193 | + position: absolute; |
| 194 | +} |
| 195 | + |
130 | 196 | /** |
131 | 197 | * Header area |
132 | 198 | * |
|
0 commit comments