@anydigital/blades 0.27.0-beta.9 → 0.28.0-alpha

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.
@@ -0,0 +1,31 @@
1
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
2
+ .has-float-label {
3
+ /* Default/fallback state */
4
+ > span,
5
+ label {
6
+ padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
7
+ padding-block-start: 0.25rem;
8
+ opacity: 75%;
9
+ transition: all 0.25s;
10
+ }
11
+ input,
12
+ textarea,
13
+ select {
14
+ margin-block-start: 0; /* reset Pico */
15
+ padding-inline-start: 1rem; /* match Pico */
16
+ padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
17
+
18
+ &::placeholder {
19
+ opacity: 100%;
20
+ transition: all 0.25s;
21
+ }
22
+ }
23
+
24
+ /* Enlarged state */
25
+ &:has(*:placeholder-shown:not(:focus)) {
26
+ > span,
27
+ label {
28
+ padding-block: 0.75rem; /* match Pico */
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,55 @@
1
+ /* Extends https://github.com/picocss/pico/blob/main/scss/content/_link.scss
2
+ <!--section:code-->
3
+ ```css */
4
+ a {
5
+ /* Use inline flex only if link contains an icon */
6
+ &:has(> i) {
7
+ display: inline-flex;
8
+ gap: 0.375ch; /* =3/8 */
9
+ overflow-y: clip; /* to work in pair with text-underline-offset in Safari */
10
+ }
11
+ > i {
12
+ font-style: normal;
13
+ float: left; /* ✅ Chrome ❌ Safari */
14
+ text-underline-offset: -2em; /* ❌ Chrome ✅ Safari - to clip it with overflow-y */
15
+
16
+ /* Favicons */
17
+ > img {
18
+ height: 1.25em;
19
+ margin-block: calc(-0.25em / 2);
20
+ display: inline-block; /* for Tailwind CSS Typography */
21
+ }
22
+
23
+ /* Font Awesome */
24
+ &[class^="fa-"],
25
+ &[class*=" fa-"] {
26
+ line-height: inherit;
27
+ --fa-width: auto;
28
+ }
29
+ &.fa-lg {
30
+ line-height: normal;
31
+ }
32
+ }
33
+ }
34
+ /*```
35
+ > **PRO-TIP** for 11ty: https://blades.ninja/build-awesome-11ty/processors/#auto-link-favicons
36
+
37
+ <!--section:docs,summary-->
38
+
39
+ Use Blades' `<i>`-helper to wrap emojis, favicons, or simply drop Font Awesome icons inside links. It automatically handles sizing and alignment while preventing underline on icons.
40
+
41
+ <!--section:docs-->
42
+
43
+ Compare:
44
+
45
+ | Without Blades <hr class="lg"> | With Blades' `<i>`-helper <hr class="lg"> | Clean HTML without `<span>ning` <hr class="x2"> |
46
+ | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
47
+ | [🥷 Link with emoji](#) | [<i>🥷</i> Link with emoji](#) | `<a><i>🥷</i> Text</a>` |
48
+ | [![](https://www.google.com/s2/favicons?domain=any.digital&sz=64) Multi-line link <br> with favicon](#) | [<i>![](https://www.google.com/s2/favicons?domain=any.digital&sz=64)</i> Multi-line link <br> with favicon](#) | `<a><i><img src="..."></i> Text</a>` |
49
+ | [<b class="fa-brands fa-github fa-lg"></b> Link with Font Awesome icon](#) | [<i class="fa-brands fa-github fa-lg"></i> Link with Font Awesome icon](#) | `<a><i class="fa-..."></i> Text</a>` |
50
+
51
+ ---
52
+
53
+ [How we made it ↗ &nbsp;<small>(on Codepen)</small>](https://codepen.io/editor/anydigital/pen/019d2b94-5616-75dc-a23e-e111869d5237){role=button .outline}
54
+
55
+ <!--section--> */
@@ -29,21 +29,24 @@ Soft-increase selector specificity trick:
29
29
 
30
30
  `table:not(.does-not-exist)` (inspired by postcss) is used here to increase specificity against selectors like `&:is(table, .table)`
31
31
 
32
- <!--section:docs-->
32
+ <!--section:docs,summary-->
33
+
34
+ `<table class="responsive">` allows a table to full-bleed and scroll on mobile.
33
35
 
34
- `<table class="responsive">` allows a table to full-bleed and scroll on mobile:
35
- <hr><div>
36
+ <!--section:docs-->
36
37
 
37
- | Term | Description <hr class="x2"> | Link |
38
- | --- | --- | --- |
38
+ | Term | Description <hr class="x2"> | Link |
39
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
39
40
  | Responsive design | Approach to web design that aims to make web pages render well on a variety of devices and window or screen sizes from minimum to maximum display size to ensure usability and satisfaction. | https://en.wikipedia.org/wiki/Responsive_web_design |
40
41
 
41
42
  {.responsive}
42
- </div><hr>
43
+
44
+ ---
43
45
 
44
46
  Tables inside https://blades.ninja/css/breakout/ are responsive by default.
45
47
 
46
48
  Living examples:
49
+
47
50
  - https://any.digital/insights/ai-ide/
48
51
  - https://any.digital/insights/css-frameworks/
49
52
  - https://any.digital/insights/ssg/
package/blades.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "blades"
5
- spec.version = "0.27.0-beta.9"
5
+ spec.version = "0.28.0-alpha"
6
6
  spec.authors = ["Anton Staroverov"]
7
7
 
8
8
  spec.summary = "Framework-agnostic CSS utilities and single-file Liquid 'blades' for modern web development."
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@anydigital/blades",
3
- "version": "0.27.0-beta.9",
3
+ "version": "0.28.0-alpha",
4
4
  "description": "Framework-agnostic CSS utilities and single-file Liquid 'blades' for modern web development.",
5
5
  "style": "./assets/blades.css",
6
6
  "exports": {
7
7
  ".": "./src/blades.css",
8
+ "./core": "./src/blades.core.css",
8
9
  "./theme": "./src/blades.theme.css",
10
+ "./float-label": "./src/float-label.css",
9
11
  "./unreduce-motion": "./src/_unreduce-motion.css"
10
12
  },
11
13
  "scripts": {
package/src/_layout.css CHANGED
@@ -1,28 +1,18 @@
1
1
  /* Extends https://github.com/picocss/pico/blob/main/scss/layout/
2
- <!--section:docs-->
2
+ <!--section:docs-intro-->
3
3
 
4
4
  Global styles:
5
- - Prevent horizontal overflow and scrolling, modern way.
6
5
  ```css */
7
6
  html {
7
+ /* Prevent horizontal overflow and scrolling, modern way. */
8
8
  overflow-x: clip;
9
9
  }
10
- /*```
11
-
12
- ### Landmarks
13
- - Ensure `body` takes at least the full height of the viewport (using dynamic viewport height for better mobile support).
14
- - Make the `body` a flex container with column layout, and `main` to automatically fill available space. This is useful for creating sticky footers and full-height layouts.
15
- ```css */
16
10
  body {
11
+ /* Ensure `body` takes at least the full height of the viewport (using dynamic viewport height for better mobile support). */
17
12
  min-height: 100dvh;
18
-
19
- display: flex;
20
- flex-direction: column;
21
- > main {
22
- flex-grow: 1;
23
- }
24
13
  }
25
14
  /*```
15
+ <!--section:docs-->
26
16
 
27
17
  ### Auto-columns
28
18
  ```css */
package/src/_table.css CHANGED
@@ -33,6 +33,9 @@ table {
33
33
  margin: 0;
34
34
  visibility: hidden;
35
35
 
36
+ &.lg {
37
+ width: 18ch;
38
+ }
36
39
  &.x2 {
37
40
  width: 24ch;
38
41
  }
@@ -40,8 +43,6 @@ table {
40
43
  }
41
44
  }
42
45
  /*```
43
- ---
44
-
45
46
  ### Borderless table
46
47
 
47
48
  `<table class="borderless">` removes all default borders:
@@ -1,5 +1,5 @@
1
1
  /* Extends https://github.com/picocss/pico/blob/main/scss/content/_typography.scss
2
- <!--section:docs-->
2
+ <!--section:docs-intro-->
3
3
 
4
4
  Global styles:
5
5
  ```css */
@@ -10,6 +10,8 @@ html {
10
10
  }
11
11
 
12
12
  body {
13
+ /* Evaluates the last ~4 lines of text blocks to prevent a single word from sitting on the final line. */
14
+ text-wrap: pretty;
13
15
  /* Enable global hyphenation */
14
16
  hyphens: auto;
15
17
  /* ... except for links and tables which are better (safer) without hyphenation */
@@ -19,6 +21,7 @@ body {
19
21
  }
20
22
  }
21
23
  /*```
24
+ <!--section:docs-->
22
25
 
23
26
  ### Heading anchors
24
27
 
@@ -37,13 +40,14 @@ h6 {
37
40
  position: relative;
38
41
 
39
42
  [data-is-anchor] {
40
- visibility: hidden;
41
43
  position: absolute;
42
- top: 0;
43
44
  right: 100%;
45
+ top: 50%;
46
+ transform: translateY(-50%);
44
47
  padding-right: 0.2ch;
45
48
  color: silver;
46
49
  text-decoration: none;
50
+ visibility: hidden;
47
51
  }
48
52
  /* Avoid double-tap on touch devices */
49
53
  @media (hover: hover) {
@@ -89,14 +93,18 @@ ol {
89
93
  /* ⚠️ `data-marker` works only in Chrome and Firefox */
90
94
  content: attr(data-marker) " ";
91
95
  }
96
+ }
97
+ /*```
92
98
 
93
- /* Helper class to remove list styling at all */
94
- &.unlist {
95
- padding-inline-start: 0;
99
+ ### Unlist
96
100
 
97
- > li {
98
- list-style: none;
99
- }
101
+ Helper class to remove list styling at all:
102
+ ```css */
103
+ .unlist {
104
+ padding-inline-start: 0;
105
+
106
+ > li {
107
+ list-style: none;
100
108
  }
101
109
  }
102
110
  /*```
@@ -0,0 +1,18 @@
1
+ /*** Follows https://github.com/picocss/pico/blob/main/scss/_index.scss ***/
2
+
3
+ /* Layout */
4
+ @import "./_layout";
5
+ @import "./breakout";
6
+
7
+ /* Content */
8
+ @import "./_typography";
9
+ @import "./link-icon";
10
+ @import "./_table";
11
+ @import "./responsive-table";
12
+ @import "./_code";
13
+
14
+ /* Forms */
15
+ @import "./float-label.core";
16
+
17
+ /* Utilities */
18
+ @import "./_utilities";
package/src/blades.css CHANGED
@@ -1,15 +1,2 @@
1
- /*** Follows https://github.com/picocss/pico/blob/main/scss/_index.scss ***/
2
-
3
- /* Layout */
4
- @import "./_layout";
5
- @import "./breakout";
6
-
7
- /* Content */
8
- @import "./_typography";
9
- @import "./_link";
10
- @import "./_table";
11
- @import "./responsive-table";
12
- @import "./_code";
13
-
14
- /* Utilities */
15
- @import "./_utilities";
1
+ @import "./blades.core";
2
+ @import "./blades.theme";
@@ -1,5 +1,16 @@
1
1
  /* <!--section:code-->
2
2
  ```css */
3
+ @import "./float-label.theme";
4
+
5
+ body {
6
+ /* Make the `body` a flex container with column layout, and `main` to automatically fill available space. This is useful for creating sticky footers and full-height layouts. */
7
+ display: flex;
8
+ flex-direction: column;
9
+ > main {
10
+ flex-grow: 1;
11
+ }
12
+ }
13
+
3
14
  a {
4
15
  &:not([href^="#"]) {
5
16
  text-decoration-thickness: 1px;
@@ -14,11 +25,10 @@ h1 {
14
25
  margin-bottom: 1rem; /* for tw-typography */
15
26
  }
16
27
 
17
- /* Fix https://github.com/picocss/pico/blob/main/css/pico.css for the very first headings
28
+ /* Potential fix https://github.com/picocss/pico/blob/main/css/pico.css for the very first headings
18
29
  :where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) {
19
30
  margin-top: var(--pico-typography-spacing-top);
20
31
  }
21
- */
22
32
  h1,
23
33
  h2,
24
34
  h3,
@@ -26,9 +36,11 @@ h4,
26
36
  h5,
27
37
  h6 {
28
38
  & ~ & {
29
- margin-top: 2rem;
39
+ margin-bottom: 2rem;
30
40
  }
31
41
  }
42
+ NOTE: be careful with wrapped headings, i.e. inside nav: https://blades.ninja/build-awesome-11ty/#usage
43
+ */
32
44
 
33
45
  hr {
34
46
  margin-block: 2em; /* for pico.css & tw-typography */
@@ -63,7 +75,7 @@ table {
63
75
  [data-jump-to="top"] {
64
76
  > i {
65
77
  display: inline-block;
66
- padding: 0.25rem;
78
+ padding: 0.25rem 0.375rem;
67
79
  margin: 0.5rem;
68
80
  font-size: 0.75rem;
69
81
  color: black;
package/src/breakout.css CHANGED
@@ -79,10 +79,14 @@
79
79
  }
80
80
  }
81
81
  }
82
- /*```<!--section:docs-->
82
+ /*```
83
+ <!--section:docs,summary-->
84
+
83
85
  Framework-agnostic utilities for breaking out images and figures beyond their container width.
84
86
 
85
- Use the `.breakout` class to allow elements to extend beyond their parent container:
87
+ Use the `.breakout` class to allow elements to extend beyond their parent container.
88
+
89
+ <!--section:docs-->
86
90
 
87
91
  ```html
88
92
  <div class="breakout">
@@ -91,4 +95,5 @@ Use the `.breakout` class to allow elements to extend beyond their parent contai
91
95
  ```
92
96
 
93
97
  The breakout container has `10%` inline padding and a max-width of `calc(10% + 65ch + 10%)`. The breakout utilities support images, pictures, figures, canvas, audio, video, tables, pre, iframe, and other media elements. Tables inside `.breakout` are specifically enhanced for horizontal scrolling and full-bleed mobile display. This is automatically included when you import the stylesheet.
98
+
94
99
  <!--section--> */
@@ -0,0 +1,44 @@
1
+ /* Moved here from https://github.com/anydigital/float-label-css for easier maintenance
2
+ <!--section:docs-->
3
+
4
+ First, we target either:
5
+ 1. `<label>` which `:has` inner form inputs (classless approach)
6
+ 2. or explicit `.has-float-label` class (alternative approach)
7
+ ```css */
8
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
9
+ .has-float-label {
10
+ display: block;
11
+ position: relative;
12
+ /*
13
+ ```
14
+ Then, we define the default/fallback state (when the float label should be minimized):
15
+ ```css */
16
+ > span,
17
+ label {
18
+ position: absolute;
19
+ left: 0;
20
+ top: 0;
21
+ cursor: text;
22
+ font-size: 75%;
23
+ }
24
+ /*
25
+ ```
26
+ Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
27
+ ```css */
28
+ *:placeholder-shown:not(:focus)::placeholder {
29
+ opacity: 0;
30
+ }
31
+ &:has(*:placeholder-shown:not(:focus)) {
32
+ > span,
33
+ label {
34
+ font-size: inherit;
35
+ opacity: 50%;
36
+ }
37
+ }
38
+ }
39
+ /*
40
+ ```
41
+ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state information to *propagate* to the parent level. This enables modern CSS to target inner float label (`<span>` or `<label>`) regardless of its position relative to the input field.
42
+
43
+ Historically, this was not possible: the float label had to be placed after the input field to be targeted using the `input:focus + label` selector.
44
+ <!--section--> */
@@ -0,0 +1,3 @@
1
+ /* Float Label CSS v2.0.0-alpha */
2
+ @import "./float-label.core";
3
+ @import "./float-label.theme";
@@ -0,0 +1,31 @@
1
+ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
2
+ .has-float-label {
3
+ /* Default/fallback state */
4
+ > span,
5
+ label {
6
+ padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
7
+ padding-block-start: 0.25rem;
8
+ opacity: 75%;
9
+ transition: all 0.25s;
10
+ }
11
+ input,
12
+ textarea,
13
+ select {
14
+ margin-block-start: 0; /* reset Pico */
15
+ padding-inline-start: 1rem; /* match Pico */
16
+ padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
17
+
18
+ &::placeholder {
19
+ opacity: 100%;
20
+ transition: all 0.25s;
21
+ }
22
+ }
23
+
24
+ /* Enlarged state */
25
+ &:has(*:placeholder-shown:not(:focus)) {
26
+ > span,
27
+ label {
28
+ padding-block: 0.75rem; /* match Pico */
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,55 @@
1
+ /* Extends https://github.com/picocss/pico/blob/main/scss/content/_link.scss
2
+ <!--section:code-->
3
+ ```css */
4
+ a {
5
+ /* Use inline flex only if link contains an icon */
6
+ &:has(> i) {
7
+ display: inline-flex;
8
+ gap: 0.375ch; /* =3/8 */
9
+ overflow-y: clip; /* to work in pair with text-underline-offset in Safari */
10
+ }
11
+ > i {
12
+ font-style: normal;
13
+ float: left; /* ✅ Chrome ❌ Safari */
14
+ text-underline-offset: -2em; /* ❌ Chrome ✅ Safari - to clip it with overflow-y */
15
+
16
+ /* Favicons */
17
+ > img {
18
+ height: 1.25em;
19
+ margin-block: calc(-0.25em / 2);
20
+ display: inline-block; /* for Tailwind CSS Typography */
21
+ }
22
+
23
+ /* Font Awesome */
24
+ &[class^="fa-"],
25
+ &[class*=" fa-"] {
26
+ line-height: inherit;
27
+ --fa-width: auto;
28
+ }
29
+ &.fa-lg {
30
+ line-height: normal;
31
+ }
32
+ }
33
+ }
34
+ /*```
35
+ > **PRO-TIP** for 11ty: https://blades.ninja/build-awesome-11ty/processors/#auto-link-favicons
36
+
37
+ <!--section:docs,summary-->
38
+
39
+ Use Blades' `<i>`-helper to wrap emojis, favicons, or simply drop Font Awesome icons inside links. It automatically handles sizing and alignment while preventing underline on icons.
40
+
41
+ <!--section:docs-->
42
+
43
+ Compare:
44
+
45
+ | Without Blades <hr class="lg"> | With Blades' `<i>`-helper <hr class="lg"> | Clean HTML without `<span>ning` <hr class="x2"> |
46
+ | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
47
+ | [🥷 Link with emoji](#) | [<i>🥷</i> Link with emoji](#) | `<a><i>🥷</i> Text</a>` |
48
+ | [![](https://www.google.com/s2/favicons?domain=any.digital&sz=64) Multi-line link <br> with favicon](#) | [<i>![](https://www.google.com/s2/favicons?domain=any.digital&sz=64)</i> Multi-line link <br> with favicon](#) | `<a><i><img src="..."></i> Text</a>` |
49
+ | [<b class="fa-brands fa-github fa-lg"></b> Link with Font Awesome icon](#) | [<i class="fa-brands fa-github fa-lg"></i> Link with Font Awesome icon](#) | `<a><i class="fa-..."></i> Text</a>` |
50
+
51
+ ---
52
+
53
+ [How we made it ↗ &nbsp;<small>(on Codepen)</small>](https://codepen.io/editor/anydigital/pen/019d2b94-5616-75dc-a23e-e111869d5237){role=button .outline}
54
+
55
+ <!--section--> */
@@ -29,21 +29,24 @@ Soft-increase selector specificity trick:
29
29
 
30
30
  `table:not(.does-not-exist)` (inspired by postcss) is used here to increase specificity against selectors like `&:is(table, .table)`
31
31
 
32
- <!--section:docs-->
32
+ <!--section:docs,summary-->
33
+
34
+ `<table class="responsive">` allows a table to full-bleed and scroll on mobile.
33
35
 
34
- `<table class="responsive">` allows a table to full-bleed and scroll on mobile:
35
- <hr><div>
36
+ <!--section:docs-->
36
37
 
37
- | Term | Description <hr class="x2"> | Link |
38
- | --- | --- | --- |
38
+ | Term | Description <hr class="x2"> | Link |
39
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
39
40
  | Responsive design | Approach to web design that aims to make web pages render well on a variety of devices and window or screen sizes from minimum to maximum display size to ensure usability and satisfaction. | https://en.wikipedia.org/wiki/Responsive_web_design |
40
41
 
41
42
  {.responsive}
42
- </div><hr>
43
+
44
+ ---
43
45
 
44
46
  Tables inside https://blades.ninja/css/breakout/ are responsive by default.
45
47
 
46
48
  Living examples:
49
+
47
50
  - https://any.digital/insights/ai-ide/
48
51
  - https://any.digital/insights/css-frameworks/
49
52
  - https://any.digital/insights/ssg/
package/src/_link.css DELETED
@@ -1,46 +0,0 @@
1
- /* Extends https://github.com/picocss/pico/blob/main/scss/content/_link.scss
2
- <!--section:code-->
3
- ```css */
4
- a {
5
- /* Helper to handle [fav]icons in links */
6
- > i {
7
- display: inline-block;
8
- font-style: normal;
9
-
10
- > img {
11
- height: 1.25em;
12
- margin-block: calc(-0.25em / 2);
13
-
14
- /* for tw-typography (.prose) */
15
- display: inline-block;
16
- }
17
- }
18
- }
19
- /*```
20
- > **PRO-TIP** for 11ty: https://blades.ninja/build-awesome-11ty/processors/#auto-link-favicons
21
-
22
- <!--section:docs-->
23
-
24
- ### Link [fav]icons
25
-
26
- Wrap [fav]icons inside links using `<i>...&nbsp;</i>` helper to size automatically and avoid underline. Compare:
27
-
28
- <big class="grid">
29
- <article><a href="https://github.com/anydigital/blades">
30
- 🥷 Blades
31
- </a></article>
32
- <article><a href="https://github.com/anydigital/blades">
33
- <i>🥷&nbsp;</i>Blades
34
- </a></article>
35
- </big>
36
-
37
- <big class="grid">
38
- <article><a href="https://github.com/anydigital/blades">
39
- <img src="https://www.google.com/s2/favicons?domain=github.com&amp;sz=64" >/anydigital/blades
40
- </a></article>
41
- <article><a href="https://github.com/anydigital/blades">
42
- <i><img src="https://www.google.com/s2/favicons?domain=github.com&amp;sz=64">&nbsp;</i>/anydigital/blades
43
- </a></article>
44
- </big>
45
-
46
- <!--section--> */