0
# Sass API
1
2
The Sass API provides comprehensive mixin and function systems for styling ripple effects with CSS-only fallbacks. It supports both basic and advanced configuration patterns for different design requirements.
3
4
## Capabilities
5
6
### Core Mixins
7
8
These mixins are required for any ripple implementation.
9
10
```scss { .api }
11
/**
12
* Base ripple surface styles - MANDATORY
13
* Adds fundamental styles required for ripple effects
14
*/
15
@mixin surface();
16
17
/**
18
* Bounded ripple radius styles
19
* For ripples clipped by element boundaries (most common)
20
* @param $radius - Border radius for the ripple bounds (default: 100%)
21
*/
22
@mixin radius-bounded($radius: 100%);
23
24
/**
25
* Unbounded ripple radius styles
26
* For ripples extending beyond element boundaries (checkboxes, radio buttons)
27
* @param $radius - Border radius for the ripple effect (default: 100%)
28
*/
29
@mixin radius-unbounded($radius: 100%);
30
```
31
32
**Usage Example:**
33
34
```scss
35
@use "@material/ripple";
36
37
.my-button {
38
@include ripple.surface;
39
@include ripple.radius-bounded;
40
@include ripple.states;
41
}
42
43
.my-checkbox-ripple {
44
@include ripple.surface;
45
@include ripple.radius-unbounded;
46
@include ripple.states;
47
}
48
```
49
50
### Basic State Mixins
51
52
Simple approach using automatic opacity calculations based on color lightness.
53
54
```scss { .api }
55
/**
56
* Basic state styles with automatic opacity - MANDATORY when using basic approach
57
* Adds hover, focus, and press state styles using calculated opacities
58
* @param $color - Base color for the ripple effect
59
* @param $has-nested-focusable-element - Whether element contains focusable children (default: false)
60
*/
61
@mixin states($color, $has-nested-focusable-element: false);
62
63
/**
64
* Activated state styles for toggleable elements
65
* @param $color - Base color for activated states
66
* @param $has-nested-focusable-element - Whether element contains focusable children (default: false)
67
*/
68
@mixin states-activated($color, $has-nested-focusable-element: false);
69
70
/**
71
* Selected state styles for selectable elements
72
* @param $color - Base color for selected states
73
* @param $has-nested-focusable-element - Whether element contains focusable children (default: false)
74
*/
75
@mixin states-selected($color, $has-nested-focusable-element: false);
76
```
77
78
**Usage Examples:**
79
80
```scss
81
@use "@material/ripple";
82
@use "@material/theme";
83
84
// Basic button with primary theme color
85
.my-button {
86
@include ripple.surface;
87
@include ripple.radius-bounded;
88
@include ripple.states(theme.prop-value(primary));
89
}
90
91
// Toggleable element with activated states
92
.my-toggle {
93
@include ripple.surface;
94
@include ripple.radius-bounded;
95
@include ripple.states(theme.prop-value(on-surface));
96
97
&--activated {
98
@include ripple.states-activated(theme.prop-value(primary));
99
}
100
}
101
102
// Form field with nested input
103
.my-form-field {
104
@include ripple.surface;
105
@include ripple.radius-bounded;
106
@include ripple.states(theme.prop-value(on-surface), $has-nested-focusable-element: true);
107
}
108
```
109
110
### Advanced State Mixins
111
112
Granular control over individual state opacities.
113
114
```scss { .api }
115
/**
116
* Base color setup for advanced states - MANDATORY when using advanced approach
117
* @param $color - Base color for all state calculations
118
*/
119
@mixin states-base-color($color);
120
121
/**
122
* Custom opacity values for specific interaction states
123
* @param $opacity-map - Map of state names to opacity values (hover, focus, press)
124
* @param $has-nested-focusable-element - Whether element contains focusable children (default: false)
125
*/
126
@mixin states-opacities($opacity-map, $has-nested-focusable-element: false);
127
```
128
129
**Usage Example:**
130
131
```scss
132
@use "@material/ripple";
133
134
.my-custom-surface {
135
@include ripple.surface;
136
@include ripple.radius-bounded;
137
@include ripple.states-base-color(#1976d2);
138
@include ripple.states-opacities((
139
hover: 0.04,
140
focus: 0.12,
141
press: 0.10
142
));
143
}
144
145
// Different opacities for activated state
146
.my-custom-surface--activated {
147
@include ripple.states-base-color(#ffffff);
148
@include ripple.states-opacities((
149
hover: 0.08,
150
focus: 0.24,
151
press: 0.20
152
));
153
}
154
```
155
156
### Deprecated Mixins
157
158
These mixins are deprecated but still supported for backward compatibility.
159
160
```scss { .api }
161
/**
162
* DEPRECATED: Use states-opacities instead
163
* Set hover state opacity
164
* @param $opacity - Hover opacity value
165
*/
166
@mixin states-hover-opacity($opacity);
167
168
/**
169
* DEPRECATED: Use states-opacities instead
170
* Set focus state opacity
171
* @param $opacity - Focus opacity value
172
* @param $has-nested-focusable-element - Whether element contains focusable children (default: false)
173
*/
174
@mixin states-focus-opacity($opacity, $has-nested-focusable-element: false);
175
176
/**
177
* DEPRECATED: Use states-opacities instead
178
* Set press state opacity
179
* @param $opacity - Press opacity value
180
*/
181
@mixin states-press-opacity($opacity);
182
```
183
184
### Sass Functions
185
186
Utility functions for opacity calculations and color manipulation.
187
188
```scss { .api }
189
/**
190
* Calculate appropriate opacity for a color in a given state
191
* @param $color - Base color value
192
* @param $state - State name (hover, focus, press, selected, activated)
193
* @returns Calculated opacity value for the color and state combination
194
*/
195
@function states-opacity($color, $state);
196
```
197
198
**Usage Example:**
199
200
```scss
201
@use "@material/ripple";
202
203
$primary-color: #1976d2;
204
205
.my-element {
206
@include ripple.surface;
207
@include ripple.radius-bounded;
208
@include ripple.states-base-color($primary-color);
209
@include ripple.states-opacities((
210
hover: ripple.states-opacity($primary-color, hover),
211
focus: ripple.states-opacity($primary-color, focus),
212
press: ripple.states-opacity($primary-color, press)
213
));
214
}
215
```
216
217
## CSS Classes
218
219
When JavaScript is not available, these CSS classes provide basic ripple styling.
220
221
### Surface Classes
222
223
```scss { .api }
224
/**
225
* Basic ripple surface class
226
* Apply to elements that should have ripple effects
227
*/
228
.mdc-ripple-surface {}
229
230
/**
231
* Primary theme color ripple
232
* Uses the theme's primary color for ripple effects
233
*/
234
.mdc-ripple-surface--primary {}
235
236
/**
237
* Secondary theme color ripple
238
* Uses the theme's secondary (accent) color for ripple effects
239
*/
240
.mdc-ripple-surface--accent {}
241
```
242
243
### State Classes (Applied by JavaScript)
244
245
```scss { .api }
246
/**
247
* Applied when ripple is upgraded with JavaScript
248
* Enables CSS variable-based ripple animations
249
*/
250
.mdc-ripple-upgraded {}
251
252
/**
253
* Applied to unbounded ripples
254
* Allows ripple to extend beyond element boundaries
255
*/
256
.mdc-ripple-upgraded--unbounded {}
257
258
/**
259
* Applied during focus state
260
* Shows background highlighting for focused elements
261
*/
262
.mdc-ripple-upgraded--background-focused {}
263
264
/**
265
* Applied during ripple activation animation
266
* Triggers the expanding ripple effect
267
*/
268
.mdc-ripple-upgraded--foreground-activation {}
269
270
/**
271
* Applied during ripple deactivation animation
272
* Triggers the fade-out ripple effect
273
*/
274
.mdc-ripple-upgraded--foreground-deactivation {}
275
```
276
277
## Implementation Patterns
278
279
### Basic Button Implementation
280
281
```scss
282
@use "@material/ripple";
283
@use "@material/theme";
284
285
.custom-button {
286
// Base button styles
287
padding: 8px 16px;
288
border: none;
289
border-radius: 4px;
290
cursor: pointer;
291
292
// Ripple integration
293
@include ripple.surface;
294
@include ripple.radius-bounded;
295
@include ripple.states(theme.prop-value(primary));
296
297
// Ensure proper stacking context
298
position: relative;
299
overflow: hidden;
300
}
301
```
302
303
### Icon Button (Unbounded)
304
305
```scss
306
@use "@material/ripple";
307
@use "@material/theme";
308
309
.icon-button {
310
width: 40px;
311
height: 40px;
312
border-radius: 50%;
313
border: none;
314
background: transparent;
315
cursor: pointer;
316
317
// Unbounded ripple for circular button
318
@include ripple.surface;
319
@include ripple.radius-unbounded;
320
@include ripple.states(theme.prop-value(on-surface));
321
322
// Ensure ripple visibility
323
position: relative;
324
overflow: visible;
325
}
326
```
327
328
### Form Field with Nested Input
329
330
```scss
331
@use "@material/ripple";
332
@use "@material/theme";
333
334
.form-field {
335
padding: 16px;
336
border: 1px solid;
337
border-radius: 4px;
338
cursor: pointer;
339
340
// Ripple with nested focusable element
341
@include ripple.surface;
342
@include ripple.radius-bounded;
343
@include ripple.states(
344
theme.prop-value(on-surface),
345
$has-nested-focusable-element: true
346
);
347
348
position: relative;
349
overflow: hidden;
350
351
input {
352
// Input styling
353
border: none;
354
background: transparent;
355
outline: none;
356
}
357
}
358
```
359
360
### Advanced Custom Ripple
361
362
```scss
363
@use "@material/ripple";
364
365
.premium-surface {
366
@include ripple.surface;
367
@include ripple.radius-bounded(8px);
368
369
// Custom color and opacity configuration
370
@include ripple.states-base-color(#9c27b0);
371
@include ripple.states-opacities((
372
hover: 0.06,
373
focus: 0.18,
374
press: 0.14
375
));
376
377
// Premium activated state
378
&--premium {
379
@include ripple.states-base-color(#ffd700);
380
@include ripple.states-opacities((
381
hover: 0.08,
382
focus: 0.20,
383
press: 0.16
384
));
385
}
386
}
387
```
388
389
### CSS-Only Fallback Pattern
390
391
```scss
392
@use "@material/ripple";
393
@use "@material/theme";
394
395
.fallback-button {
396
@include ripple.surface;
397
@include ripple.radius-bounded;
398
@include ripple.states(theme.prop-value(primary));
399
400
// CSS-only states using pseudo-classes
401
// These work when JavaScript is disabled
402
&:hover {
403
// Hover styles applied via CSS
404
}
405
406
&:focus {
407
// Focus styles applied via CSS
408
}
409
410
&:active {
411
// Active/press styles applied via CSS
412
}
413
}
414
```
415
416
## CSS Variables
417
418
The Sass system generates and manages these CSS custom properties:
419
420
### Size and Position Variables
421
422
```css
423
--mdc-ripple-fg-size: /* Foreground ripple size */
424
--mdc-ripple-left: /* Left position for unbounded ripples */
425
--mdc-ripple-top: /* Top position for unbounded ripples */
426
```
427
428
### Animation Variables
429
430
```css
431
--mdc-ripple-fg-scale: /* Scale factor for ripple animation */
432
--mdc-ripple-fg-translate-start: /* Animation start position */
433
--mdc-ripple-fg-translate-end: /* Animation end position */
434
```
435
436
These variables are automatically managed by the JavaScript foundation and should not be set manually in most cases.