gerillass 2.3.0 → 3.0.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.
Files changed (55) hide show
  1. package/README.md +46 -7
  2. package/SKILL.md +37 -12
  3. package/gerillass.json +527 -145
  4. package/package.json +1 -1
  5. package/scss/internal/_color-problem.scss +99 -0
  6. package/scss/internal/_color-stops-problem.scss +94 -0
  7. package/scss/internal/_condition-width.scss +22 -0
  8. package/scss/internal/_custom-property-in.scss +25 -0
  9. package/scss/internal/_gradient.scss +425 -0
  10. package/scss/internal/_image-value.scss +68 -0
  11. package/scss/internal/_is-condition-value.scss +94 -0
  12. package/scss/internal/_is-css-function.scss +21 -0
  13. package/scss/internal/_is-size.scss +22 -0
  14. package/scss/internal/_keyword-value.scss +76 -0
  15. package/scss/internal/_length-problem.scss +127 -0
  16. package/scss/internal/_sibling-index.scss +51 -0
  17. package/scss/internal/_words.scss +35 -0
  18. package/scss/library/_adaptive.scss +17 -0
  19. package/scss/library/_after.scss +2 -12
  20. package/scss/library/_background-dots.scss +36 -43
  21. package/scss/library/_background-image.scss +40 -52
  22. package/scss/library/_background-stripes.scss +40 -54
  23. package/scss/library/_before.scss +2 -12
  24. package/scss/library/_border-radius.scss +83 -0
  25. package/scss/library/_brand-logo.scss +10 -24
  26. package/scss/library/_breakpoint.scss +19 -26
  27. package/scss/library/_circle.scss +7 -0
  28. package/scss/library/_columnizer.scss +62 -2
  29. package/scss/library/_container-query.scss +13 -29
  30. package/scss/library/_container.scss +2 -19
  31. package/scss/library/_counter.scss +3 -14
  32. package/scss/library/_ellipsis.scss +78 -1
  33. package/scss/library/_except.scss +15 -0
  34. package/scss/library/_focus-ring.scss +29 -0
  35. package/scss/library/_font-face.scss +117 -1
  36. package/scss/library/_gradient.scss +31 -0
  37. package/scss/library/_index.scss +1 -2
  38. package/scss/library/_line-clamp.scss +2 -13
  39. package/scss/library/_only.scss +16 -0
  40. package/scss/library/_position.scss +34 -3
  41. package/scss/library/_remove.scss +1 -1
  42. package/scss/library/_resizable.scss +29 -2
  43. package/scss/library/_screen-agent.scss +8 -22
  44. package/scss/library/_sizer.scss +9 -0
  45. package/scss/library/_sprite.scss +65 -0
  46. package/scss/library/_text-gradient.scss +36 -18
  47. package/scss/library/_text-image.scss +2 -23
  48. package/scss/library/_text-stroke.scss +30 -0
  49. package/scss/library/_triangle.scss +25 -56
  50. package/scss/utilities/_gradient-value.scss +24 -0
  51. package/scss/utilities/_index.scss +1 -0
  52. package/scss/utilities/_validate-breakpoint.scss +32 -6
  53. package/scss/utilities/_validate-scissors.scss +7 -0
  54. package/scss/library/_linear-gradient.scss +0 -26
  55. package/scss/library/_radial-gradient.scss +0 -30
package/README.md CHANGED
@@ -32,6 +32,7 @@ Hope you’ll enjoy using it!
32
32
  - [Using with Angular](#using-with-angular)
33
33
  - [Using with Gulp](#using-with-gulp)
34
34
  - [Using with Grunt](#using-with-grunt)
35
+ - [Using with Ruby: Rails, Jekyll, or plain Sass](#using-with-ruby-rails-jekyll-or-plain-sass)
35
36
  - [Cloning the Repository from Github](#cloning-the-repository-from-github)
36
37
  - [Versions these examples were tested with](#versions-these-examples-were-tested-with)
37
38
  - [Using Gerillass with an AI coding agent](#using-gerillass-with-an-ai-coding-agent)
@@ -184,6 +185,35 @@ Then:
184
185
 
185
186
  @use 'gerillass' as *;
186
187
 
188
+ ### Using with Ruby: Rails, Jekyll, or plain Sass
189
+
190
+ Gerillass is also a gem. It installs the same Sass files and nothing else: no runtime dependencies, because each kind of project already brings its own Dart Sass. It needs Dart Sass; the LibSass-based `sass-rails` and `sassc-rails` cannot compile it.
191
+
192
+ bundle add gerillass
193
+
194
+ **Rails.** With `dartsass-rails` on Propshaft, the Rails 8 default, or `dartsass-sprockets` on Sprockets, there is nothing to configure: the gem hands the library's folder to Sass, and none of its files end up in `public/assets`. Then, in `app/assets/stylesheets/application.scss`:
195
+
196
+ @use 'gerillass' as *;
197
+
198
+ **Jekyll.** Put the gem in the plugins group of your `Gemfile`:
199
+
200
+ group :jekyll_plugins do
201
+ gem "gerillass"
202
+ end
203
+
204
+ Then, in a stylesheet with front matter such as `assets/css/main.scss`:
205
+
206
+ ---
207
+ ---
208
+ @use 'gerillass' as *;
209
+
210
+ **Plain Ruby.** Pass the library's folder to `sass-embedded` yourself:
211
+
212
+ require "sass-embedded"
213
+ require "gerillass"
214
+
215
+ Sass.compile("style.scss", load_paths: [Gerillass.load_path])
216
+
187
217
  ### Cloning the repository from Github
188
218
 
189
219
  You can clone the repository into your local computer from Github.
@@ -210,10 +240,15 @@ Including to the project:
210
240
  | Gulp / gulp-sass | 5.0.1 / 6.0.1 |
211
241
  | Grunt / grunt-sass | 1.6.3 / 4.1.0 |
212
242
  | Parcel / @parcel/transformer-sass | 2.16.4 / 2.16.4, with Dart Sass 1.104.1 and Gerillass 2.1.0 |
243
+ | Ruby / Rails | 4.0.1 / 8.1.3.1 |
244
+ | Propshaft / dartsass-rails | 1.3.2 / 0.5.1 |
245
+ | sprockets-rails / dartsass-sprockets | 3.5.2 / 3.2.1 |
246
+ | Jekyll / jekyll-sass-converter | 4.4.1 / 3.1.0 |
247
+ | sass-embedded (Ruby) | 1.104.1 |
213
248
 
214
249
  ## Using Gerillass with an AI coding agent
215
250
 
216
- A library this size has no training data behind it, so an agent asked to use Gerillass will guess at the argument forms and get them wrong. Two files ship with the package to stop that. Both live inside the installed package, so an agent working in your project can read them straight out of `node_modules/gerillass/`.
251
+ A library this size has no training data behind it, so an agent asked to use Gerillass will guess at the argument forms and get them wrong. Two files ship with the package to stop that. Both live inside the installed package, so an agent working in your project can read them straight out of `node_modules/gerillass/`, or, in a Ruby project, out of the gem's folder, which `bundle info gerillass --path` prints.
217
252
 
218
253
  **`gerillass.json`** describes every mixin and function: its signature, what each argument accepts, examples that compile, and inputs that are refused.
219
254
 
@@ -224,6 +259,10 @@ A library this size has no training data behind it, so an agent asked to use Ger
224
259
  mkdir -p .claude/skills/gerillass
225
260
  cp node_modules/gerillass/SKILL.md .claude/skills/gerillass/
226
261
 
262
+ In a Ruby project, copy it from the gem instead:
263
+
264
+ cp "$(bundle info gerillass --path)/SKILL.md" .claude/skills/gerillass/
265
+
227
266
  Otherwise, point your agent at the file and it will read it as plain Markdown.
228
267
 
229
268
  ### Why you can trust what they say
@@ -264,21 +303,21 @@ So, feel free to use any tool to support that. My suggestion is Autoprefixer. If
264
303
 
265
304
  ## Experimenting
266
305
 
267
- Experimentation with Gerillass is easy: If you're processing Sass files on your computer already, [download the Gerillass Sass library](https://github.com/selfishprimate/gerillass/archive/main.zip), include it in your project, and start using it. If not, use [Gerillass Play](https://github.com/selfishprimate/gerillass-play)! Gerillass Play is a Gulp based playground, built for you to get started with [Sass](https://sass-lang.com/) and [Gerillass](https://gerillass.com/) quickly.
306
+ The quickest way to try Gerillass is the [playground](https://gerillass.com/playground). It runs in your browser, so there is nothing to install: write Sass on one side and read the CSS it compiles to on the other. Pick a mixin to start from an example, and pick any published Gerillass version to compile against, which makes it easy to see how a call behaves before and after an upgrade.
268
307
 
269
- **Important Note**: Don't forget that you must have [Node.js](https://nodejs.org/en/) and [Gulp CLI](https://gulpjs.com/docs/en/getting-started/quick-start) installed on your machine to work with Gerillass Play.
308
+ When you are ready to use it in a project, follow the [installation](#installation) steps for your build tool.
270
309
 
271
310
  ## Testing
272
311
 
273
- Gerillass comes with a unit-testing module named [True](https://github.com/oddbird/true), which makes Sass unit tests possible (endless thanks to the [OddBird Team](https://github.com/oddbird)).
274
-
275
- You can find two test examples under the `test` folder, take your time, examine the codes, and then write your unit tests. After that, run the following command to see if the tests pass.
312
+ The test suite runs with [Jest](https://jestjs.io/) and [True](https://github.com/oddbird/true), which makes Sass unit tests possible (endless thanks to the [OddBird Team](https://github.com/oddbird)).
276
313
 
277
314
  npm test
278
315
 
316
+ It checks more than hand-written assertions: every mixin is called at least once, every documented example is compiled and compared with a snapshot, and every input a mixin should refuse must stop the build with the library's own error message. [CONTRIBUTING.md](CONTRIBUTING.md#testing) explains which of these a change needs.
317
+
279
318
  ## Contribution
280
319
 
281
- Please read the [contribution details](CONTRIBUTING.md) and feel free to contribute to the library.
320
+ Please read the [contribution details](CONTRIBUTING.md) and feel free to contribute to the library. If you are working on a mixin, the site's dev server has a lab that renders your working copy of the library as you edit it; [CONTRIBUTING.md](CONTRIBUTING.md#seeing-what-it-renders) shows how to use it.
282
321
 
283
322
  ## License
284
323
 
package/SKILL.md CHANGED
@@ -5,7 +5,7 @@ description: Use the Gerillass Sass mixin library — loading it, the mixin cata
5
5
 
6
6
  # Gerillass
7
7
 
8
- A Sass mixin library: 56 mixins and 23 functions that emit CSS from
8
+ A Sass mixin library: 55 mixins and 24 functions that emit CSS from
9
9
  semantic declarations. It is Sass source only — there is no runtime and no
10
10
  utility classes, so styles live in your stylesheet and your markup stays clean.
11
11
 
@@ -33,7 +33,17 @@ Anything else, by pointing a load path at `node_modules/gerillass/scss`:
33
33
  @use "gerillass" as *;
34
34
  ```
35
35
 
36
- Dart Sass only. LibSass and node-sass are not supported.
36
+ In a Ruby project, from the `gerillass` gem. Rails with `dartsass-rails` or
37
+ `dartsass-sprockets`, and Jekyll with the gem in its `:jekyll_plugins` group,
38
+ need no configuration. Plain Ruby passes the folder to `sass-embedded` with
39
+ `load_paths: [Gerillass.load_path]`. Then:
40
+
41
+ ```scss
42
+ @use "gerillass" as *; // the gerillass gem: Rails and Jekyll need no setup; plain Ruby passes Gerillass.load_path
43
+ ```
44
+
45
+ Dart Sass only. LibSass and node-sass are not supported, which rules out
46
+ `sass-rails` and `sassc-rails` in Ruby.
37
47
 
38
48
  ## Two names for every mixin
39
49
 
@@ -65,6 +75,7 @@ a dropped declaration rather than an error.
65
75
 
66
76
  | Mixin | Rejects, for example |
67
77
  |---|---|
78
+ | `adaptive` | `.wrap { @include adaptive(auto); }` |
68
79
  | `after` | `.a { @include after(42) { color: red; } }` |
69
80
  | `all-buttons` | `@include all-buttons(nonsense) { color: red; }` |
70
81
  | `all-text-inputs` | `@include all-text-inputs(nonsense) { color: red; }` |
@@ -76,35 +87,41 @@ a dropped declaration rather than an error.
76
87
  | `before` | `.a { @include before(42) { color: red; } }` |
77
88
  | `border-box` | `@include border-box(only);` |
78
89
  | `border-radius` | `.a { @include border-radius(1px, 2px, 3px); }` |
90
+ | `brand-logo` | `.logo { @include brand-logo(120px, 40px, "/img/a.svg" "/img/b.svg"); }` |
79
91
  | `breakpoint` | `.a { @include breakpoint("between", "medium", "large") { color: red; } }` |
80
92
  | `breakpointer` | `.a { @include breakpointer(42); }` |
81
93
  | `center` | `.modal { @include center(diagonal); }` |
94
+ | `circle` | `.dot { @include circle(huge); }` |
82
95
  | `columnizer` | `.grid { @include columnizer(3, 20px, true, 9); }` |
83
96
  | `container-query` | `.title { @include container-query("min", 400px, 800px) { color: red; } }` |
84
97
  | `container` | `.card { @include container("card", sideways); }` |
98
+ | `ellipsis` | `.a { @include ellipsis(100%, huge); }` |
85
99
  | `escape-to-parent` | `.a { @include escape-to-parent(42) { color: red; } }` |
86
100
  | `except` | `.a { @include except(#ff0000) { margin: 0; } }` |
87
101
  | `focus-ring` | `@include focus-ring;` |
88
102
  | `font-face` | `.a { @include font-face("Inter", "/fonts/inter"); }` |
103
+ | `gradient` | `.a { @include gradient((red, blue), sideways); }` |
89
104
  | `hide` | `.a { @include hide(nonsense); }` |
90
105
  | `line-clamp` | `.a { @include line-clamp(0); }` |
91
- | `linear-gradient` | `.a { @include linear-gradient(sideways, (red, blue)); }` |
92
106
  | `loadify` | `@include loadify(nonsense);` |
93
107
  | `motion-safe` | `.card { @include motion-safe; }` |
94
108
  | `only` | `.a { @include only(#ff0000) { margin: 0; } }` |
95
109
  | `position` | `.badge { @include position(absolute, 0, $logical: yes); }` |
96
- | `radial-gradient` | `.a { @include radial-gradient(42, "center", (red, blue)); }` |
97
110
  | `remove` | `.a { @include remove(a, b, c); }` |
98
111
  | `reset-css` | `.a { @include reset-css; }` |
112
+ | `resizable` | `.a { @include resizable(huge); }` |
99
113
  | `scissors` | `.a { @include scissors(5px 10px); }` |
100
114
  | `screen-agent` | `.a { @include screen-agent(var(--density)) { color: red; } }` |
115
+ | `sizer` | `.a { @include sizer(huge); }` |
101
116
  | `smartphone` | `.a { @include smartphone(Nokia3310) { display: none; } }` |
102
117
  | `sprite` | `.icon { @include sprite("/img/sprite.txt"); }` |
103
118
  | `stretched-link` | `.card a { @include stretched-link(middle); }` |
104
119
  | `tablet` | `.a { @include tablet(Surface) { display: none; } }` |
105
- | `text-gradient` | `.a { @include text-gradient(sideways, (red, blue)); }` |
120
+ | `text-gradient` | `.a { @include text-gradient("top", (red, blue)); }` |
121
+ | `text-image` | `.a { @include text-image(16 9); }` |
106
122
  | `text-selection` | `.a { @include text-selection(bogus) { background: yellow; } }` |
107
123
  | `text-shadow` | `.a { @include text-shadow(42); }` |
124
+ | `text-stroke` | `.a { @include text-stroke(huge); }` |
108
125
  | `tokens` | `:root { @include tokens(#fff); }` |
109
126
  | `triangle` | `.caret { @include triangle(sideways); }` |
110
127
 
@@ -124,12 +141,12 @@ a dropped declaration rather than an error.
124
141
 
125
142
  **`breakpoint`**
126
143
 
127
- - With one argument the query matches exactly that width, `(width: 768px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider. 3.0.0 will refuse the one-argument form.
144
+ - With one argument the query matches exactly that width, `(width: 768px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider.
128
145
  - Declarations written after the include, in the same rule, are emitted after the `@media` block and win over it. Write them before the include.
129
146
 
130
147
  **`container-query`**
131
148
 
132
- - A size on its own matches exactly that width, `(width: 400px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider. 3.0.0 will refuse the one-argument form.
149
+ - A size on its own matches exactly that width, `(width: 400px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider.
133
150
 
134
151
  **`container`**
135
152
 
@@ -139,6 +156,10 @@ a dropped declaration rather than an error.
139
156
 
140
157
  - Numbering restarts on every item, each showing the first number, when the items are size containers (`container-type: inline-size`): containment scopes counters to each item.
141
158
 
159
+ **`except`**
160
+
161
+ - An+B with an offset cannot be passed as a number: Sass does the arithmetic, so `except(2n+1)` becomes `3n` and excludes every third element, not the odd ones. Use `odd` or `even`, or a coefficient alone such as `3n`.
162
+
142
163
  **`loadify`**
143
164
 
144
165
  - `init` and every call must be in the same module, or the module with the call must `@use` the one that calls `init`. Otherwise Sass fails with "The target selector was not found".
@@ -147,9 +168,13 @@ a dropped declaration rather than an error.
147
168
 
148
169
  - Keep the resting state outside the block. An element hidden in its base rule and revealed by an animation inside the block stays hidden for a user who asked for less motion; put the start state in the keyframes instead.
149
170
 
171
+ **`only`**
172
+
173
+ - An+B with an offset cannot be passed as a number: Sass does the arithmetic, so `only(2n+1)` becomes `3n` and selects every third element, not the odd ones. Use `odd` or `even`, or a coefficient alone such as `3n`.
174
+
150
175
  **`remove`**
151
176
 
152
- - With one argument the element is hidden at exactly that width, `(width: 768px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider. 3.0.0 will refuse the one-argument form.
177
+ - With one argument the element is hidden at exactly that width, `(width: 768px)`, which is a single pixel, and the mixin prints a warning. Write `only` for that width, or `min`, `max` or a range for anything wider.
153
178
  - A `display` written after the include, in the same rule, is emitted after the `@media` block and wins over it. Write it before the include.
154
179
 
155
180
  ## Mixins
@@ -183,16 +208,15 @@ a dropped declaration rather than an error.
183
208
  | `except($params...)` | Selects every sibling except the ones named. |
184
209
  | `focus-ring($width: 2px, $offset: 2px, $color: currentColor)` | Draws a keyboard focus ring with outline on :focus-visible, which survives forced-colors mode where a box-shadow ring disappears. |
185
210
  | `font-face($font-family, $file-path, $font-style: normal, $font-weight: 400, $file-formats: eot woff2 woff ttf svg, $font-display: null)` | Emits an @font-face rule for one family across several file formats. Must be called at the root. |
211
+ | `gradient($colors, $type: linear, $direction: null, $shape: null, $position: null, $from: null, $in: null, $repeating: false)` | A linear, radial or conic gradient as background-image, plain or repeating, with an optional colour interpolation space. Replaced linear-gradient and radial-gradient in 3.0.0. |
186
212
  | `hide($toggle: "hide")` | Visually hides an element while keeping it available to screen readers, or reverses that. |
187
213
  | `line-clamp($lines: 3)` | Truncates text after a number of lines, where ellipsis truncates one. It emits five declarations rather than one because -webkit-line-clamp does nothing on its own: without display: -webkit-box or without -webkit-box-orient: vertical the text is not clamped at all and nothing warns you, and without overflow: hidden the clamped text spills out below the box. The unprefixed line-clamp is emitted too, for when it becomes Baseline. |
188
- | `linear-gradient($direction, $colors)` | Linear gradient background from a direction name or an angle. |
189
214
  | `loadify($params...)` | Fades elements in on page load. Call once at the root to set up, then on each element. Under prefers-reduced-motion: reduce the end state is applied directly and no animation runs. Switching the animation off alone would not do, because the element starts invisible and the animation is what reveals it, so the content would stay hidden for good. |
190
215
  | `motion-safe` | Wraps its content in @media (prefers-reduced-motion: no-preference), so motion is opt-in: a user who asked their system for less motion gets none of it. |
191
216
  | `only($params...)` | Selects only the siblings named. |
192
217
  | `placeholder-shown` | Styles an input while its placeholder is visible. |
193
218
  | `placeholder` | Styles the placeholder text of an input across vendor prefixes. |
194
219
  | `position($position: absolute, $offsets: 0, $logical: false)` | Sets position and offsets in one call, using shorthand order. |
195
- | `radial-gradient($shape, $position, $colors)` | Radial gradient background from a shape and a position. |
196
220
  | `remove($params...)` | Hides an element outright, or within a media query: from a breakpoint up with min, up to it with max, or between two breakpoints. One breakpoint on its own hides the element at exactly that width, a single pixel, and prints a warning: pass only for that. |
197
221
  | `reset-css` | Meyer reset. Must be called at the root of the stylesheet. |
198
222
  | `reset-figure` | Removes default figure margins and makes the image inside responsive. |
@@ -205,7 +229,7 @@ a dropped declaration rather than an error.
205
229
  | `sprite($params...)` | Sets up an element as a sprite tile: an image, a background position, or both. |
206
230
  | `stretched-link($value: "before")` | Expands a link to cover its positioned parent, so the whole card is clickable. |
207
231
  | `tablet($device, $orientation: null)` | Media query targeting a known tablet by device dimensions. |
208
- | `text-gradient($direction, $colors)` | Applies a linear gradient to the text itself via background-clip. |
232
+ | `text-gradient($colors, $type: linear, $direction: null, $shape: null, $position: null, $from: null, $in: null, $repeating: false)` | Fills the text with a gradient through background-clip: text. It takes the gradient mixin's arguments, colours first: a linear, radial or conic gradient, plain or repeating, with an optional colour space. |
209
233
  | `text-image($image: null)` | Fills the text with an image via background-clip. |
210
234
  | `text-selection($value: null)` | Styles the ::selection pseudo-element. |
211
235
  | `text-shadow($params...)` | Layered text shadows built from a direction, a colour and an offset. |
@@ -228,6 +252,7 @@ and camelCase is what tells them apart from the kebab-case mixins above.
228
252
  | `fluid($min, $max, $min-viewport: 320px, $max-viewport: 1280px)` | A clamp() value that grows with the viewport between two widths, then stops. The preferred value keeps a rem term rather than being pure vw, because a vw-only value ignores browser text zoom and fails WCAG 1.4.4. It is a function rather than a mixin because the value is the hard part and belongs to any property, not only font-size. |
229
253
  | `fontSizer($size, $time)` | Multiplies a size by a factor. Handy for a modular scale. |
230
254
  | `fontSource($font-family, $file-path, $file-formats)` | Builds one src entry for an @font-face rule. |
255
+ | `gradientValue($colors, $type: linear, $direction: null, $shape: null, $position: null, $from: null, $in: null, $repeating: false)` | The gradient mixin's gradient as a value, for layering it with an image in one background-image, or using it as a mask-image or border-image. It takes the same arguments and refuses the same input, but cannot write the fallback the mixin writes before a gradient with $in. |
231
256
  | `isColor($value)` | Returns the value if every item in it is a colour, and errors otherwise. |
232
257
  | `isGutter($value)` | True for anything that can sit where a CSS length is expected: a number, a calculation, or a CSS function such as var(). |
233
258
  | `isNumber($value)` | Returns the value if it is a number. |
@@ -239,7 +264,7 @@ and camelCase is what tells them apart from the kebab-case mixins above.
239
264
  | `shade($color, $percentage)` | Mixes a colour towards black by a percentage. |
240
265
  | `shorthandProperty($value)` | Expands one to four values into the four-value CSS shorthand order. |
241
266
  | `tint($color, $percentage)` | Mixes a colour towards white by a percentage. |
242
- | `validateBreakpoint($value)` | Resolves a breakpoint name to its width, passing other values through. |
267
+ | `validateBreakpoint($value)` | Resolves a breakpoint name to its width, passing a length, a percentage or a CSS function through, and refusing a word that is not a key. |
243
268
  | `validateLength($value)` | Returns the value if it is a length or one of auto, inherit, initial, 0. Returns null quietly for null, so a caller can skip a value. |
244
269
  | `validateRatio($ratio)` | Turns an aspect ratio into a value for the CSS aspect-ratio property. |
245
270
  | `validateScissors($value)` | Normalises corner values for the scissors mixin, adding px where missing. |