gerillass 2.0.1 → 2.1.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/SKILL.md +9 -2
- package/gerillass.json +146 -2
- package/package.json +1 -1
- package/scss/library/_container-query.scss +63 -0
- package/scss/library/_container.scss +26 -0
- package/scss/library/_index.scss +3 -0
- package/scss/library/_line-clamp.scss +36 -0
- package/scss/library/_loadify.scss +11 -0
- package/scss/utilities/_fluid.scss +76 -0
- package/scss/utilities/_index.scss +1 -0
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:
|
|
8
|
+
A Sass mixin library: 53 mixins and 23 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
|
|
|
@@ -79,10 +79,13 @@ a dropped declaration rather than an error.
|
|
|
79
79
|
| `breakpointer` | `.a { @include breakpointer(42); }` |
|
|
80
80
|
| `center` | `.modal { @include center(diagonal); }` |
|
|
81
81
|
| `columnizer` | `.grid { @include columnizer(3, 20px, true, 9); }` |
|
|
82
|
+
| `container-query` | `.title { @include container-query("min", 400px, 800px) { color: red; } }` |
|
|
83
|
+
| `container` | `.card { @include container("card", sideways); }` |
|
|
82
84
|
| `escape-to-parent` | `.a { @include escape-to-parent(42) { color: red; } }` |
|
|
83
85
|
| `except` | `.a { @include except(#ff0000) { margin: 0; } }` |
|
|
84
86
|
| `font-face` | `.a { @include font-face("Inter", "/fonts/inter"); }` |
|
|
85
87
|
| `hide` | `.a { @include hide(nonsense); }` |
|
|
88
|
+
| `line-clamp` | `.a { @include line-clamp(0); }` |
|
|
86
89
|
| `linear-gradient` | `.a { @include linear-gradient(sideways, (red, blue)); }` |
|
|
87
90
|
| `loadify` | `@include loadify(nonsense);` |
|
|
88
91
|
| `only` | `.a { @include only(#ff0000) { margin: 0; } }` |
|
|
@@ -122,14 +125,17 @@ a dropped declaration rather than an error.
|
|
|
122
125
|
| `circle($size)` | Square element with a fully rounded border, i.e. a circle. |
|
|
123
126
|
| `clearfix` | Clears floated children using an ::after pseudo-element. |
|
|
124
127
|
| `columnizer($params...)` | Flexbox grid of equal columns, with an optional gutter and fill behaviour. |
|
|
128
|
+
| `container-query($params...)` | A @container rule, taking the same argument shapes as breakpoint so the two read alike. Sizes may be a key from $map-for-breakpoints or a raw length, and a length is the common case because a container is usually narrower than the viewport. Nothing matches at all unless an ancestor was declared with the container mixin. |
|
|
129
|
+
| `container($name: null, $type: inline-size)` | Marks an element as a query container, so container-query can ask about its width instead of the viewport's. The rule that asks has to sit on a descendant: an element is never matched by a @container rule reading its own container, and nothing warns you when it is not. |
|
|
125
130
|
| `counter($params...)` | CSS counter for a list, with optional text before and after the number. |
|
|
126
131
|
| `ellipsis($width: 100%, $display: inline-block)` | Truncates a single line of text with an ellipsis. |
|
|
127
132
|
| `escape-to-parent($selector: null)` | Re-roots the current selector under another one using @at-root. |
|
|
128
133
|
| `except($params...)` | Selects every sibling except the ones named. |
|
|
129
134
|
| `font-face($font-family, $file-path, $font-style: normal, $font-weight: 400, $file-formats: eot woff2 woff ttf svg)` | Emits an @font-face rule for one family across several file formats. Must be called at the root. |
|
|
130
135
|
| `hide($toggle: "hide")` | Visually hides an element while keeping it available to screen readers, or reverses that. |
|
|
136
|
+
| `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. |
|
|
131
137
|
| `linear-gradient($direction, $colors)` | Linear gradient background from a direction name or an angle. |
|
|
132
|
-
| `loadify($params...)` | Fades elements in on page load. Call once at the root to set up, then on each element. |
|
|
138
|
+
| `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. |
|
|
133
139
|
| `only($params...)` | Selects only the siblings named. |
|
|
134
140
|
| `placeholder-shown` | Styles an input while its placeholder is visible. |
|
|
135
141
|
| `placeholder` | Styles the placeholder text of an input across vendor prefixes. |
|
|
@@ -166,6 +172,7 @@ and camelCase is what tells them apart from the kebab-case mixins above.
|
|
|
166
172
|
| `convertToEm($value)` | Converts a pixel length to em, against a 16px base. |
|
|
167
173
|
| `convertToNumber($value)` | Parses a string of digits into a number. |
|
|
168
174
|
| `fillNulls($value, $seperation: comma, $skip: false)` | Replaces null entries in a list with 0, or drops them. |
|
|
175
|
+
| `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. |
|
|
169
176
|
| `fontSizer($size, $time)` | Multiplies a size by a factor. Handy for a modular scale. |
|
|
170
177
|
| `fontSource($font-family, $file-path, $file-formats)` | Builds one src entry for an @font-face rule. |
|
|
171
178
|
| `isColor($value)` | Returns the value if every item in it is a colour, and errors otherwise. |
|
package/gerillass.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gerillass",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Gerillass is an open-source toolkit that contains a set of Sass mixins to help designers and developers to create better, faster and consistent user interfaces.",
|
|
5
5
|
"homepage": "https://gerillass.com",
|
|
6
6
|
"documentation": "https://docs.gerillass.com",
|
|
@@ -571,6 +571,72 @@
|
|
|
571
571
|
".grid { @include columnizer(3, nonsense); }"
|
|
572
572
|
]
|
|
573
573
|
},
|
|
574
|
+
{
|
|
575
|
+
"name": "container-query",
|
|
576
|
+
"kind": "mixin",
|
|
577
|
+
"arguments": [
|
|
578
|
+
{
|
|
579
|
+
"name": "$params",
|
|
580
|
+
"variadic": true,
|
|
581
|
+
"accepts": [
|
|
582
|
+
"a size",
|
|
583
|
+
"two sizes for a range",
|
|
584
|
+
"one of min, max, only or between followed by a size",
|
|
585
|
+
"$name as a keyword, to query one named container"
|
|
586
|
+
]
|
|
587
|
+
}
|
|
588
|
+
],
|
|
589
|
+
"file": "scss/library/_container-query.scss",
|
|
590
|
+
"signature": "container-query($params...)",
|
|
591
|
+
"summary": "A @container rule, taking the same argument shapes as breakpoint so the two read alike. Sizes may be a key from $map-for-breakpoints or a raw length, and a length is the common case because a container is usually narrower than the viewport. Nothing matches at all unless an ancestor was declared with the container mixin.",
|
|
592
|
+
"examples": [
|
|
593
|
+
".title { @include container-query(\"min\", 400px) { font-size: 2rem; } }",
|
|
594
|
+
".title { @include container-query(\"max\", 399px) { font-size: 1rem; } }",
|
|
595
|
+
".title { @include container-query(\"between\", 300px 500px) { color: red; } }",
|
|
596
|
+
".title { @include container-query(300px, 500px) { color: red; } }",
|
|
597
|
+
".title { @include container-query(\"min\", \"medium\") { color: red; } }",
|
|
598
|
+
".title { @include container-query(\"min\", 400px, $name: \"card\") { color: red; } }"
|
|
599
|
+
],
|
|
600
|
+
"rejects": [
|
|
601
|
+
".title { @include container-query(\"min\", 400px, 800px) { color: red; } }",
|
|
602
|
+
".title { @include container-query(\"min\", 400px, $name: 42) { color: red; } }"
|
|
603
|
+
]
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
"name": "container",
|
|
607
|
+
"kind": "mixin",
|
|
608
|
+
"arguments": [
|
|
609
|
+
{
|
|
610
|
+
"name": "$name",
|
|
611
|
+
"default": "null",
|
|
612
|
+
"accepts": [
|
|
613
|
+
"a container name as a string, such as \"card\"",
|
|
614
|
+
"null for an unnamed container"
|
|
615
|
+
]
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
"name": "$type",
|
|
619
|
+
"default": "inline-size",
|
|
620
|
+
"accepts": [
|
|
621
|
+
"inline-size",
|
|
622
|
+
"size",
|
|
623
|
+
"normal"
|
|
624
|
+
]
|
|
625
|
+
}
|
|
626
|
+
],
|
|
627
|
+
"file": "scss/library/_container.scss",
|
|
628
|
+
"signature": "container($name: null, $type: inline-size)",
|
|
629
|
+
"summary": "Marks an element as a query container, so container-query can ask about its width instead of the viewport's. The rule that asks has to sit on a descendant: an element is never matched by a @container rule reading its own container, and nothing warns you when it is not.",
|
|
630
|
+
"examples": [
|
|
631
|
+
".card { @include container(\"card\"); }",
|
|
632
|
+
".panel { @include container; }",
|
|
633
|
+
".panel { @include container(null, size); }"
|
|
634
|
+
],
|
|
635
|
+
"rejects": [
|
|
636
|
+
".card { @include container(\"card\", sideways); }",
|
|
637
|
+
".card { @include container(42); }"
|
|
638
|
+
]
|
|
639
|
+
},
|
|
574
640
|
{
|
|
575
641
|
"name": "counter",
|
|
576
642
|
"kind": "mixin",
|
|
@@ -749,6 +815,35 @@
|
|
|
749
815
|
".a { @include hide(nonsense); }"
|
|
750
816
|
]
|
|
751
817
|
},
|
|
818
|
+
{
|
|
819
|
+
"name": "line-clamp",
|
|
820
|
+
"kind": "mixin",
|
|
821
|
+
"arguments": [
|
|
822
|
+
{
|
|
823
|
+
"name": "$lines",
|
|
824
|
+
"default": "3",
|
|
825
|
+
"accepts": [
|
|
826
|
+
"a whole number of lines, at least 1",
|
|
827
|
+
"none, to undo a clamp"
|
|
828
|
+
]
|
|
829
|
+
}
|
|
830
|
+
],
|
|
831
|
+
"file": "scss/library/_line-clamp.scss",
|
|
832
|
+
"signature": "line-clamp($lines: 3)",
|
|
833
|
+
"summary": "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.",
|
|
834
|
+
"examples": [
|
|
835
|
+
".excerpt { @include line-clamp(3); }",
|
|
836
|
+
".title { @include line-clamp(2); }",
|
|
837
|
+
".full { @include line-clamp(none); }",
|
|
838
|
+
".default { @include line-clamp; }"
|
|
839
|
+
],
|
|
840
|
+
"rejects": [
|
|
841
|
+
".a { @include line-clamp(0); }",
|
|
842
|
+
".a { @include line-clamp(2.5); }",
|
|
843
|
+
".a { @include line-clamp(3px); }",
|
|
844
|
+
".a { @include line-clamp(\"three\"); }"
|
|
845
|
+
]
|
|
846
|
+
},
|
|
752
847
|
{
|
|
753
848
|
"name": "linear-gradient",
|
|
754
849
|
"kind": "mixin",
|
|
@@ -796,7 +891,7 @@
|
|
|
796
891
|
],
|
|
797
892
|
"file": "scss/library/_loadify.scss",
|
|
798
893
|
"signature": "loadify($params...)",
|
|
799
|
-
"summary": "Fades elements in on page load. Call once at the root to set up, then on each element.",
|
|
894
|
+
"summary": "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.",
|
|
800
895
|
"examples": [
|
|
801
896
|
"@include loadify(init);\n.a { @include loadify; }",
|
|
802
897
|
"@include loadify;\n.a { @include loadify(0.4s, 1s); }"
|
|
@@ -1509,6 +1604,55 @@
|
|
|
1509
1604
|
".a { --x: #{fillNulls(1px null, nonsense)}; }"
|
|
1510
1605
|
]
|
|
1511
1606
|
},
|
|
1607
|
+
{
|
|
1608
|
+
"name": "fluid",
|
|
1609
|
+
"kind": "function",
|
|
1610
|
+
"arguments": [
|
|
1611
|
+
{
|
|
1612
|
+
"name": "$min",
|
|
1613
|
+
"required": true,
|
|
1614
|
+
"accepts": [
|
|
1615
|
+
"a length in px or rem, the value at $min-viewport"
|
|
1616
|
+
]
|
|
1617
|
+
},
|
|
1618
|
+
{
|
|
1619
|
+
"name": "$max",
|
|
1620
|
+
"required": true,
|
|
1621
|
+
"accepts": [
|
|
1622
|
+
"a length in px or rem, the value at $max-viewport, no smaller than $min"
|
|
1623
|
+
]
|
|
1624
|
+
},
|
|
1625
|
+
{
|
|
1626
|
+
"name": "$min-viewport",
|
|
1627
|
+
"default": "320px",
|
|
1628
|
+
"accepts": [
|
|
1629
|
+
"a length in px or rem, the width below which the value stops shrinking"
|
|
1630
|
+
]
|
|
1631
|
+
},
|
|
1632
|
+
{
|
|
1633
|
+
"name": "$max-viewport",
|
|
1634
|
+
"default": "1280px",
|
|
1635
|
+
"accepts": [
|
|
1636
|
+
"a length in px or rem, larger than $min-viewport"
|
|
1637
|
+
]
|
|
1638
|
+
}
|
|
1639
|
+
],
|
|
1640
|
+
"file": "scss/utilities/_fluid.scss",
|
|
1641
|
+
"signature": "fluid($min, $max, $min-viewport: 320px, $max-viewport: 1280px)",
|
|
1642
|
+
"summary": "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.",
|
|
1643
|
+
"examples": [
|
|
1644
|
+
".title { font-size: fluid(24px, 48px); }",
|
|
1645
|
+
".title { font-size: fluid(1rem, 3rem, 320px, 1200px); }",
|
|
1646
|
+
".section { padding: fluid(16px, 64px) fluid(8px, 40px); }",
|
|
1647
|
+
".stack { gap: fluid(0.5rem, 2rem); }"
|
|
1648
|
+
],
|
|
1649
|
+
"rejects": [
|
|
1650
|
+
".title { font-size: fluid(16px, 24px, 1280px, 320px); }",
|
|
1651
|
+
".title { font-size: fluid(40px, 20px); }",
|
|
1652
|
+
".title { font-size: fluid(16, 24); }",
|
|
1653
|
+
".title { font-size: fluid(1em, 2em); }"
|
|
1654
|
+
]
|
|
1655
|
+
},
|
|
1512
1656
|
{
|
|
1513
1657
|
"name": "fontSizer",
|
|
1514
1658
|
"kind": "function",
|
package/package.json
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:map";
|
|
5
|
+
@use "sass:meta";
|
|
6
|
+
@use "sass:string";
|
|
7
|
+
@use "../maps/map-for-breakpoints" as *;
|
|
8
|
+
@use "../utilities/validate-breakpoint" as *;
|
|
9
|
+
|
|
10
|
+
// A @container rule, taking the same argument shapes as `breakpoint` so the two
|
|
11
|
+
// read alike. Sizes may be a key from $map-for-breakpoints or a raw length; a
|
|
12
|
+
// container is usually narrower than the viewport, so a length is the common
|
|
13
|
+
// case.
|
|
14
|
+
//
|
|
15
|
+
// Pass $name to query one named container rather than the nearest ancestor.
|
|
16
|
+
// The container itself is declared with the `container` mixin, on an ancestor
|
|
17
|
+
// of whatever this styles.
|
|
18
|
+
@mixin container-query($params...) {
|
|
19
|
+
$keywords: meta.keywords($params);
|
|
20
|
+
$name: map.get($keywords, name);
|
|
21
|
+
$count: list.length($params);
|
|
22
|
+
|
|
23
|
+
@if $name != null and meta.type-of($name) != "string" {
|
|
24
|
+
@error "`#{$name}` is not a valid $name for `container-query`. Pass a container name as a string, such as `\"card\"`.";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
$condition: null;
|
|
28
|
+
|
|
29
|
+
@if $count == 1 {
|
|
30
|
+
$condition: "(width: #{validateBreakpoint(list.nth($params, 1))})";
|
|
31
|
+
} @else if $count == 2 {
|
|
32
|
+
$mode: list.nth($params, 1);
|
|
33
|
+
@if not list.index("only" "min" "max" "between", $mode) {
|
|
34
|
+
// Two bare sizes mean a range, as they do in `breakpoint`.
|
|
35
|
+
$condition: "(min-width: #{validateBreakpoint($mode)}) and (max-width: #{validateBreakpoint(list.nth($params, 2))})";
|
|
36
|
+
} @else {
|
|
37
|
+
$value: list.nth($params, 2);
|
|
38
|
+
@if $mode == "only" {
|
|
39
|
+
$condition: "(width: #{validateBreakpoint($value)})";
|
|
40
|
+
} @else if $mode == "min" {
|
|
41
|
+
$condition: "(min-width: #{validateBreakpoint($value)})";
|
|
42
|
+
} @else if $mode == "max" {
|
|
43
|
+
$condition: "(max-width: #{validateBreakpoint($value)})";
|
|
44
|
+
} @else {
|
|
45
|
+
$start: list.nth($value, 1);
|
|
46
|
+
$end: list.nth($value, 2);
|
|
47
|
+
$condition: "(min-width: #{validateBreakpoint($start)}) and (max-width: #{validateBreakpoint($end)})";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} @else {
|
|
51
|
+
@error "`container-query` takes one or two arguments, and was given #{$count}. Pass a size, two sizes for a range, or one of `min`, `max`, `only` or `between` followed by a size.";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@if $name {
|
|
55
|
+
@container #{string.unquote($name)} #{$condition} {
|
|
56
|
+
@content;
|
|
57
|
+
}
|
|
58
|
+
} @else {
|
|
59
|
+
@container #{$condition} {
|
|
60
|
+
@content;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
|
|
7
|
+
// Marks an element as a query container, so `container-query` can ask about its
|
|
8
|
+
// width instead of the viewport's.
|
|
9
|
+
//
|
|
10
|
+
// The rule that asks has to sit on a descendant. An element is not matched by a
|
|
11
|
+
// @container rule that reads its own container, and nothing warns you: the rule
|
|
12
|
+
// is simply never applied. Measured in a browser, a 600px element with
|
|
13
|
+
// `container-type: inline-size` on itself did not match `@container (min-width:
|
|
14
|
+
// 400px)`, while the same query did match a child of it.
|
|
15
|
+
@mixin container($name: null, $type: inline-size) {
|
|
16
|
+
@if not list.index("inline-size" "size" "normal", $type) {
|
|
17
|
+
@error "`#{$type}` is not a valid $type for `container`. Pass one of: inline-size, size, normal.";
|
|
18
|
+
}
|
|
19
|
+
@if $name != null and meta.type-of($name) != "string" {
|
|
20
|
+
@error "`#{$name}` is not a valid $name for `container`. Pass a name as a string, such as `\"card\"`, or no name at all.";
|
|
21
|
+
}
|
|
22
|
+
container-type: $type;
|
|
23
|
+
@if $name {
|
|
24
|
+
container-name: string.unquote($name);
|
|
25
|
+
}
|
|
26
|
+
}
|
package/scss/library/_index.scss
CHANGED
|
@@ -19,12 +19,15 @@
|
|
|
19
19
|
@forward "circle";
|
|
20
20
|
@forward "clearfix";
|
|
21
21
|
@forward "columnizer";
|
|
22
|
+
@forward "container";
|
|
23
|
+
@forward "container-query";
|
|
22
24
|
@forward "counter";
|
|
23
25
|
@forward "ellipsis";
|
|
24
26
|
@forward "escape-to-parent";
|
|
25
27
|
@forward "except";
|
|
26
28
|
@forward "font-face";
|
|
27
29
|
@forward "hide";
|
|
30
|
+
@forward "line-clamp";
|
|
28
31
|
@forward "linear-gradient";
|
|
29
32
|
@forward "loadify";
|
|
30
33
|
@forward "only";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:math";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
|
|
6
|
+
// Truncates text after a number of lines. `ellipsis` does one line; this does
|
|
7
|
+
// several, and needs five declarations rather than one because -webkit-line-clamp
|
|
8
|
+
// only works alongside two other properties.
|
|
9
|
+
//
|
|
10
|
+
// All five were measured in a browser, on a paragraph that runs to five lines
|
|
11
|
+
// with a clamp of three:
|
|
12
|
+
//
|
|
13
|
+
// the three together 3 lines, with an ellipsis
|
|
14
|
+
// without -webkit-box-orient 5 lines, no clamping and no warning
|
|
15
|
+
// without display: -webkit-box 5 lines, likewise
|
|
16
|
+
// the standard line-clamp alone 5 lines; it is not Baseline yet
|
|
17
|
+
// without overflow: hidden the box is 3 lines, but the rest of the text
|
|
18
|
+
// spills out below it
|
|
19
|
+
//
|
|
20
|
+
// So the standard property is emitted for the future and the prefixed trio is
|
|
21
|
+
// what actually does the work today.
|
|
22
|
+
@mixin line-clamp($lines: 3) {
|
|
23
|
+
@if $lines != none {
|
|
24
|
+
@if meta.type-of($lines) != "number" or not math.is-unitless($lines) {
|
|
25
|
+
@error "`#{$lines}` is not a valid $lines for `line-clamp`. Pass a whole number of lines, or `none` to undo a clamp.";
|
|
26
|
+
}
|
|
27
|
+
@if $lines < 1 or $lines != math.round($lines) {
|
|
28
|
+
@error "`#{$lines}` is not a valid $lines for `line-clamp`. Pass a whole number of lines that is at least 1, or `none` to undo a clamp.";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
display: -webkit-box;
|
|
32
|
+
-webkit-box-orient: vertical;
|
|
33
|
+
-webkit-line-clamp: $lines;
|
|
34
|
+
line-clamp: $lines;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
}
|
|
@@ -20,6 +20,17 @@
|
|
|
20
20
|
backface-visibility: hidden;
|
|
21
21
|
animation-name: loadify;
|
|
22
22
|
animation-fill-mode: forwards;
|
|
23
|
+
|
|
24
|
+
// The element starts invisible and the animation is what reveals it,
|
|
25
|
+
// so switching the animation off is not enough on its own: it would
|
|
26
|
+
// leave the content hidden for good. Under reduced motion the end
|
|
27
|
+
// state is applied directly instead, and nothing moves.
|
|
28
|
+
@media (prefers-reduced-motion: reduce) {
|
|
29
|
+
opacity: 1;
|
|
30
|
+
visibility: visible;
|
|
31
|
+
backface-visibility: visible;
|
|
32
|
+
animation: none;
|
|
33
|
+
}
|
|
23
34
|
}
|
|
24
35
|
} @else if (list.length($params) == 1 and list.nth($params, 1) != "init") or (list.length($params) == 1 and meta.type-of(list.nth($params, 1)) != "string") {
|
|
25
36
|
@error "#{list.nth($params, 1)} is not a valid argument. Please pass `init` as an argument to initialize the effect or do not pass any argument at all.";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:math";
|
|
5
|
+
@use "sass:meta";
|
|
6
|
+
@use "sass:string";
|
|
7
|
+
@use "../utilities/clear-unit" as *;
|
|
8
|
+
@use "../utilities/remify" as *;
|
|
9
|
+
|
|
10
|
+
// A value that grows with the viewport between two widths, then stops.
|
|
11
|
+
//
|
|
12
|
+
// clamp() takes a floor, a preferred value and a ceiling. The preferred value
|
|
13
|
+
// is the straight line through (min-viewport, min) and (max-viewport, max):
|
|
14
|
+
//
|
|
15
|
+
// slope = (max - min) / (max-viewport - min-viewport)
|
|
16
|
+
// intercept = min - slope * min-viewport
|
|
17
|
+
// preferred = intercept + slope * 100vw
|
|
18
|
+
//
|
|
19
|
+
// The intercept is emitted in rem rather than px deliberately. A preferred
|
|
20
|
+
// value made only of vw ignores browser zoom, which fails WCAG 1.4.4, and
|
|
21
|
+
// keeping a rem term in the sum is what restores it. This is the part that is
|
|
22
|
+
// easy to get wrong by hand, and the reason this is a function rather than a
|
|
23
|
+
// mixin: the value is the hard part, and it belongs to any property, not just
|
|
24
|
+
// font-size.
|
|
25
|
+
//
|
|
26
|
+
// Sass cannot add rem to vw, so the sum is assembled as a string. CSS evaluates
|
|
27
|
+
// it; Sass only writes it.
|
|
28
|
+
|
|
29
|
+
$_fluid-root-size: 16px;
|
|
30
|
+
|
|
31
|
+
@function fluid($min, $max, $min-viewport: 320px, $max-viewport: 1280px) {
|
|
32
|
+
// Pairs rather than a map: two arguments can legitimately hold the same
|
|
33
|
+
// length, and a map would reject that as a duplicate key.
|
|
34
|
+
$given: (($min, "$min"), ($max, "$max"), ($min-viewport, "$min-viewport"), ($max-viewport, "$max-viewport"));
|
|
35
|
+
@each $pair in $given {
|
|
36
|
+
$value: list.nth($pair, 1);
|
|
37
|
+
$label: list.nth($pair, 2);
|
|
38
|
+
@if meta.type-of($value) != "number" or math.is-unitless($value) {
|
|
39
|
+
@error "`#{$value}` is not a valid #{$label} for `fluid`. Pass a length in px or rem.";
|
|
40
|
+
}
|
|
41
|
+
@if math.unit($value) != "px" and math.unit($value) != "rem" {
|
|
42
|
+
@error "`#{$value}` is not a valid #{$label} for `fluid`. Pass a length in px or rem, not #{math.unit($value)}.";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Everything is compared in px, because Sass cannot convert rem to px on its
|
|
47
|
+
// own: it has no way to know the root font size, so the assumption is stated
|
|
48
|
+
// here rather than hidden.
|
|
49
|
+
$min-px: $min;
|
|
50
|
+
$max-px: $max;
|
|
51
|
+
$from-px: $min-viewport;
|
|
52
|
+
$to-px: $max-viewport;
|
|
53
|
+
@if math.unit($min) == "rem" { $min-px: clearUnit($min) * $_fluid-root-size; }
|
|
54
|
+
@if math.unit($max) == "rem" { $max-px: clearUnit($max) * $_fluid-root-size; }
|
|
55
|
+
@if math.unit($min-viewport) == "rem" { $from-px: clearUnit($min-viewport) * $_fluid-root-size; }
|
|
56
|
+
@if math.unit($max-viewport) == "rem" { $to-px: clearUnit($max-viewport) * $_fluid-root-size; }
|
|
57
|
+
|
|
58
|
+
@if $from-px >= $to-px {
|
|
59
|
+
@error "`fluid` needs $min-viewport to be smaller than $max-viewport, and was given #{$min-viewport} and #{$max-viewport}.";
|
|
60
|
+
}
|
|
61
|
+
@if $min-px > $max-px {
|
|
62
|
+
@error "`fluid` needs $min to be no larger than $max, and was given #{$min} and #{$max}. clamp() would return the floor at every width, so the value would never grow.";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
$slope: math.div($max-px - $min-px, $to-px - $from-px);
|
|
66
|
+
$intercept: $min-px - $slope * $from-px;
|
|
67
|
+
|
|
68
|
+
// Four decimals is past the point any browser renders differently, and keeps
|
|
69
|
+
// the output readable.
|
|
70
|
+
$vw: math.div(math.round($slope * 100 * 10000), 10000);
|
|
71
|
+
$floor: math.div(math.round(clearUnit(remify($min-px)) * 10000), 10000);
|
|
72
|
+
$base: math.div(math.round(clearUnit(remify($intercept)) * 10000), 10000);
|
|
73
|
+
$ceiling: math.div(math.round(clearUnit(remify($max-px)) * 10000), 10000);
|
|
74
|
+
|
|
75
|
+
@return string.unquote("clamp(#{$floor}rem, #{$base}rem + #{$vw}vw, #{$ceiling}rem)");
|
|
76
|
+
}
|