@anyblades/blades 2.3.3 → 2.4.1
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/README.md +4 -2
- package/_includes/blades/links.njk +9 -0
- package/blades.gemspec +1 -1
- package/css/blades.css +63 -29
- package/css/blades.ninja.css +78 -0
- package/css/blades.standalone.core.css +39 -21
- package/css/blades.standalone.css +71 -31
- package/css/blades.standalone.theme.css +28 -10
- package/css/breakout.css +1 -1
- package/css/float-label.core.css +10 -10
- package/css/float-label.css +20 -20
- package/css/float-label.theme.css +10 -10
- package/package.json +4 -3
- package/src/blades.ninja.css +78 -0
- package/src/blades.standalone.core.css +3 -0
- package/src/blades.standalone.theme.css +21 -0
- package/src/breakout.css +1 -1
- package/src/components/_timeline.css +25 -0
- package/src/content/_code.css +1 -8
- package/src/float-label.core.css +2 -2
- package/src/float-label.theme.css +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# 🥷 *Bl*ades  
|
|
1
|
+
# 🥷 *Bl*ades ![][B_NPM]
|
|
2
|
+
|
|
3
|
+
[B_NPM]: https://img.shields.io/npm/v/@anyblades/blades?label=&color=white
|
|
2
4
|
|
|
3
5
|
<!--section:summary-->
|
|
4
6
|
|
|
@@ -59,7 +61,7 @@ Live example using <i class="fa-brands fa-tailwind-css"></i> Tailwind: https://g
|
|
|
59
61
|
- https://github.com/getgrav/grav-theme-quark2 for Grav CMS v2
|
|
60
62
|
- https://jekyll.blades.ninja/ starter <!--{.faded}-->
|
|
61
63
|
|
|
62
|
-
### Standalone
|
|
64
|
+
### Standalone versions
|
|
63
65
|
|
|
64
66
|
- https://blades.ninja/css/standalone/
|
|
65
67
|
|
package/blades.gemspec
CHANGED
package/css/blades.css
CHANGED
|
@@ -3100,7 +3100,7 @@ How it works:
|
|
|
3100
3100
|
transform: translateX(-50%);
|
|
3101
3101
|
}
|
|
3102
3102
|
/* Respect img/picture min-width */
|
|
3103
|
-
.breakout > *:is(img, picture), .breakout-all > *:is(img, picture) {
|
|
3103
|
+
.breakout > *:is(img, picture):not(.does-not-exist), .breakout-all > *:is(img, picture):not(.does-not-exist) /* soft win specificity over .breakout-item above */ {
|
|
3104
3104
|
min-width: auto;
|
|
3105
3105
|
}
|
|
3106
3106
|
/* Max out the width of the element */
|
|
@@ -3498,11 +3498,7 @@ The `<pre><code>` blocks are Prism-compatible and support captions via `data-cap
|
|
|
3498
3498
|
```
|
|
3499
3499
|
How it works:
|
|
3500
3500
|
```css */
|
|
3501
|
-
|
|
3502
|
-
padding: 1rem 1.5rem;
|
|
3503
|
-
padding-inline-end: 2rem;
|
|
3504
|
-
}
|
|
3505
|
-
@media (max-width: 767px) {
|
|
3501
|
+
@media (width < 768px) {
|
|
3506
3502
|
pre {
|
|
3507
3503
|
border-radius: 0
|
|
3508
3504
|
}
|
|
@@ -3515,9 +3511,6 @@ code[data-caption]::before {
|
|
|
3515
3511
|
font-style: italic;
|
|
3516
3512
|
opacity: 50%;
|
|
3517
3513
|
}
|
|
3518
|
-
code:where(pre > *) {
|
|
3519
|
-
padding: 0;
|
|
3520
|
-
}
|
|
3521
3514
|
/*```
|
|
3522
3515
|
\3c !--section--> */
|
|
3523
3516
|
/* Forms */
|
|
@@ -3526,9 +3519,9 @@ code:where(pre > *) {
|
|
|
3526
3519
|
|
|
3527
3520
|
First, we target either:
|
|
3528
3521
|
1. `<label>` which `:has` inner form inputs (classless approach)
|
|
3529
|
-
2. or explicit `.has-float-label` class (
|
|
3522
|
+
2. or explicit `.has-float-label` class (explicit approach)
|
|
3530
3523
|
```css */
|
|
3531
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
3524
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
3532
3525
|
.has-float-label {
|
|
3533
3526
|
display: block;
|
|
3534
3527
|
position: relative;
|
|
@@ -3537,8 +3530,8 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
3537
3530
|
```
|
|
3538
3531
|
Then, we define the default/fallback state (when the float label should be minimized):
|
|
3539
3532
|
```css */
|
|
3540
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
3541
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
3533
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
3534
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
3542
3535
|
.has-float-label > span,
|
|
3543
3536
|
.has-float-label label {
|
|
3544
3537
|
position: absolute;
|
|
@@ -3551,21 +3544,21 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
3551
3544
|
```
|
|
3552
3545
|
Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
|
|
3553
3546
|
```css */
|
|
3554
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
3547
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
3555
3548
|
opacity: 0;
|
|
3556
3549
|
}
|
|
3557
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
3550
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
3558
3551
|
opacity: 0;
|
|
3559
3552
|
}
|
|
3560
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
3553
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
3561
3554
|
opacity: 0;
|
|
3562
3555
|
}
|
|
3563
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
3556
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
3564
3557
|
font-size: inherit;
|
|
3565
3558
|
opacity: 50%;
|
|
3566
3559
|
}
|
|
3567
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
3568
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
3560
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
3561
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
3569
3562
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
3570
3563
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
3571
3564
|
font-size: inherit;
|
|
@@ -3577,6 +3570,29 @@ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state inform
|
|
|
3577
3570
|
|
|
3578
3571
|
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.
|
|
3579
3572
|
\3c !--section--> */
|
|
3573
|
+
/* Components */
|
|
3574
|
+
/*\3c !--section:docs-->
|
|
3575
|
+
|
|
3576
|
+
Use `dl.timeline` or wrap a `<dl>` with `.has-timeline` to style it as a
|
|
3577
|
+
vertical timeline — each `<dd>` gets a left border strip acting as the track:
|
|
3578
|
+
|
|
3579
|
+
<article class="has-timeline">
|
|
3580
|
+
|
|
3581
|
+
May 11, 2026
|
|
3582
|
+
: First Blades CSS stable release (v2.2.0).
|
|
3583
|
+
|
|
3584
|
+
Mar 15, 2025
|
|
3585
|
+
: Last Pico CSS update (v2.1.1).
|
|
3586
|
+
|
|
3587
|
+
</article>
|
|
3588
|
+
|
|
3589
|
+
\3c !--section:code-->```css */
|
|
3590
|
+
dl.timeline dd, .has-timeline > dl dd {
|
|
3591
|
+
margin-block: 0;
|
|
3592
|
+
padding: 0.25rem 0 0.75rem 1rem;
|
|
3593
|
+
border-inline-start: 0.25rem solid gray;
|
|
3594
|
+
}
|
|
3595
|
+
/*```*/
|
|
3580
3596
|
/* Utilities */
|
|
3581
3597
|
/* Extends https://github.com/picocss/pico/tree/main/scss/utilities
|
|
3582
3598
|
\3c !--section:docs-->
|
|
@@ -3636,8 +3652,8 @@ How it works:
|
|
|
3636
3652
|
\3c !--section:code-->
|
|
3637
3653
|
```css */
|
|
3638
3654
|
/* Default/fallback state */
|
|
3639
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
3640
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
3655
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
3656
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
3641
3657
|
.has-float-label > span,
|
|
3642
3658
|
.has-float-label label {
|
|
3643
3659
|
padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
|
|
@@ -3645,9 +3661,9 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
3645
3661
|
opacity: 75%;
|
|
3646
3662
|
transition: all 0.25s;
|
|
3647
3663
|
}
|
|
3648
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
3649
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
3650
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
3664
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
3665
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
3666
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
3651
3667
|
.has-float-label input,
|
|
3652
3668
|
.has-float-label textarea,
|
|
3653
3669
|
.has-float-label select {
|
|
@@ -3655,21 +3671,21 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
3655
3671
|
padding-inline-start: 1rem; /* match Pico */
|
|
3656
3672
|
padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
|
|
3657
3673
|
}
|
|
3658
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
3674
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
3659
3675
|
opacity: 100%;
|
|
3660
3676
|
-moz-transition: all 0.25s;
|
|
3661
3677
|
transition: all 0.25s;
|
|
3662
3678
|
}
|
|
3663
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
3679
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
3664
3680
|
opacity: 100%;
|
|
3665
3681
|
transition: all 0.25s;
|
|
3666
3682
|
}
|
|
3667
3683
|
/* Enlarged state */
|
|
3668
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
3684
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
3669
3685
|
padding-block: 0.75rem; /* match Pico */
|
|
3670
3686
|
}
|
|
3671
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
3672
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
3687
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
3688
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
3673
3689
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
3674
3690
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
3675
3691
|
padding-block: 0.75rem; /* match Pico */
|
|
@@ -3712,6 +3728,14 @@ a:not([href^="#"]) {
|
|
|
3712
3728
|
a:not([href^="#"]):hover {
|
|
3713
3729
|
text-decoration-thickness: 2px;
|
|
3714
3730
|
}
|
|
3731
|
+
h1,
|
|
3732
|
+
h2,
|
|
3733
|
+
h3,
|
|
3734
|
+
h4,
|
|
3735
|
+
h5,
|
|
3736
|
+
h6 {
|
|
3737
|
+
text-wrap: balance;
|
|
3738
|
+
}
|
|
3715
3739
|
h1 {
|
|
3716
3740
|
margin-bottom: 1rem; /* for tw-typography */
|
|
3717
3741
|
font-size: 2.5em; /* for pico.css & tw-typography */
|
|
@@ -3722,10 +3746,20 @@ hr {
|
|
|
3722
3746
|
ul ul {
|
|
3723
3747
|
font-size: 87.5%;
|
|
3724
3748
|
}
|
|
3749
|
+
dl dt {
|
|
3750
|
+
margin-block: 0.25rem;
|
|
3751
|
+
font-weight: 500;
|
|
3752
|
+
}
|
|
3753
|
+
dl dd {
|
|
3754
|
+
margin-block-end: 1rem;
|
|
3755
|
+
}
|
|
3725
3756
|
pre small {
|
|
3726
3757
|
font-weight: lighter;
|
|
3727
3758
|
opacity: 75%;
|
|
3728
3759
|
}
|
|
3760
|
+
pre:has(code) {
|
|
3761
|
+
background: #181c25 !important;
|
|
3762
|
+
}
|
|
3729
3763
|
table th {
|
|
3730
3764
|
font-weight: bold;
|
|
3731
3765
|
vertical-align: bottom;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*\3c !--section:docs-->
|
|
2
|
+
|
|
3
|
+
### `sup`er and `sub`headings
|
|
4
|
+
|
|
5
|
+
<article><br>
|
|
6
|
+
|
|
7
|
+
# <sup style>Parent page</sup> Page title <sub style>Subtitle</sub>
|
|
8
|
+
|
|
9
|
+
</article>
|
|
10
|
+
|
|
11
|
+
How it works:
|
|
12
|
+
```css */
|
|
13
|
+
sup[style] {
|
|
14
|
+
display: block;
|
|
15
|
+
font-size: 0.75rem;
|
|
16
|
+
letter-spacing: 0.0625em;
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
}
|
|
19
|
+
sub[style] {
|
|
20
|
+
display: block;
|
|
21
|
+
bottom: 0;
|
|
22
|
+
font-weight: 300;
|
|
23
|
+
line-height: 1.1;
|
|
24
|
+
opacity: 75%;
|
|
25
|
+
}
|
|
26
|
+
sub[style]:where(h1 > *) {
|
|
27
|
+
font-size: 50%;
|
|
28
|
+
}
|
|
29
|
+
/*```
|
|
30
|
+
|
|
31
|
+
### Teasers
|
|
32
|
+
|
|
33
|
+
<article style="padding-inline: 2rem">
|
|
34
|
+
<a href="https://blades.ninja/" role="button" class="outline">
|
|
35
|
+
<h4>Blades CSS</h4>
|
|
36
|
+
Fully compatible and actively maintained successor to Pico CSS.
|
|
37
|
+
</a>
|
|
38
|
+
</article>
|
|
39
|
+
|
|
40
|
+
How it works:
|
|
41
|
+
```css */
|
|
42
|
+
a[role="button"]:has(h1, h2, h3, h4, h5, h6) {
|
|
43
|
+
margin: 0 0 0.5rem -1rem;
|
|
44
|
+
border-width: 1px 0 0 1px;
|
|
45
|
+
text-align: start;
|
|
46
|
+
}
|
|
47
|
+
/*```
|
|
48
|
+
|
|
49
|
+
### `.opt`ional content
|
|
50
|
+
|
|
51
|
+
How it works:
|
|
52
|
+
```css */
|
|
53
|
+
@media (width < 1024px) {
|
|
54
|
+
.opt {
|
|
55
|
+
display: none
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/*```
|
|
59
|
+
|
|
60
|
+
### Nicer GitHub favicons
|
|
61
|
+
|
|
62
|
+
<article>
|
|
63
|
+
|
|
64
|
+
https://github.com/anyblades/blades
|
|
65
|
+
|
|
66
|
+
</article>
|
|
67
|
+
|
|
68
|
+
How it works:
|
|
69
|
+
```css */
|
|
70
|
+
img[src*="?domain=github.com&"] {
|
|
71
|
+
border-radius: 50%;
|
|
72
|
+
}
|
|
73
|
+
@media (prefers-color-scheme: dark) {
|
|
74
|
+
img[src*="?domain=github.com&"] {
|
|
75
|
+
filter: invert(1)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/*```*/
|
|
@@ -104,7 +104,7 @@ How it works:
|
|
|
104
104
|
|
|
105
105
|
/* Respect img/picture min-width */
|
|
106
106
|
|
|
107
|
-
.breakout > *:is(img, picture), .breakout-all > *:is(img, picture) {
|
|
107
|
+
.breakout > *:is(img, picture):not(.does-not-exist), .breakout-all > *:is(img, picture):not(.does-not-exist) /* soft win specificity over .breakout-item above */ {
|
|
108
108
|
min-width: auto;
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -551,12 +551,7 @@ The `<pre><code>` blocks are Prism-compatible and support captions via `data-cap
|
|
|
551
551
|
How it works:
|
|
552
552
|
```css */
|
|
553
553
|
|
|
554
|
-
|
|
555
|
-
padding: 1rem 1.5rem;
|
|
556
|
-
padding-inline-end: 2rem;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
@media (max-width: 767px) {
|
|
554
|
+
@media (width < 768px) {
|
|
560
555
|
|
|
561
556
|
pre {
|
|
562
557
|
border-radius: 0
|
|
@@ -573,10 +568,6 @@ code[data-caption]::before {
|
|
|
573
568
|
opacity: 50%;
|
|
574
569
|
}
|
|
575
570
|
|
|
576
|
-
code:where(pre > *) {
|
|
577
|
-
padding: 0;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
571
|
/*```
|
|
581
572
|
\3c !--section--> */
|
|
582
573
|
|
|
@@ -587,10 +578,10 @@ code:where(pre > *) {
|
|
|
587
578
|
|
|
588
579
|
First, we target either:
|
|
589
580
|
1. `<label>` which `:has` inner form inputs (classless approach)
|
|
590
|
-
2. or explicit `.has-float-label` class (
|
|
581
|
+
2. or explicit `.has-float-label` class (explicit approach)
|
|
591
582
|
```css */
|
|
592
583
|
|
|
593
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
584
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
594
585
|
.has-float-label {
|
|
595
586
|
display: block;
|
|
596
587
|
position: relative;
|
|
@@ -601,8 +592,8 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
601
592
|
Then, we define the default/fallback state (when the float label should be minimized):
|
|
602
593
|
```css */
|
|
603
594
|
|
|
604
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
605
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
595
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
596
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
606
597
|
.has-float-label > span,
|
|
607
598
|
.has-float-label label {
|
|
608
599
|
position: absolute;
|
|
@@ -617,25 +608,25 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
617
608
|
Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
|
|
618
609
|
```css */
|
|
619
610
|
|
|
620
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
611
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
621
612
|
opacity: 0;
|
|
622
613
|
}
|
|
623
614
|
|
|
624
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
615
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
625
616
|
opacity: 0;
|
|
626
617
|
}
|
|
627
618
|
|
|
628
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
619
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
629
620
|
opacity: 0;
|
|
630
621
|
}
|
|
631
622
|
|
|
632
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
623
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
633
624
|
font-size: inherit;
|
|
634
625
|
opacity: 50%;
|
|
635
626
|
}
|
|
636
627
|
|
|
637
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
638
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
628
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
629
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
639
630
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
640
631
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
641
632
|
font-size: inherit;
|
|
@@ -649,6 +640,33 @@ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state inform
|
|
|
649
640
|
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.
|
|
650
641
|
\3c !--section--> */
|
|
651
642
|
|
|
643
|
+
/* Components */
|
|
644
|
+
|
|
645
|
+
/*\3c !--section:docs-->
|
|
646
|
+
|
|
647
|
+
Use `dl.timeline` or wrap a `<dl>` with `.has-timeline` to style it as a
|
|
648
|
+
vertical timeline — each `<dd>` gets a left border strip acting as the track:
|
|
649
|
+
|
|
650
|
+
<article class="has-timeline">
|
|
651
|
+
|
|
652
|
+
May 11, 2026
|
|
653
|
+
: First Blades CSS stable release (v2.2.0).
|
|
654
|
+
|
|
655
|
+
Mar 15, 2025
|
|
656
|
+
: Last Pico CSS update (v2.1.1).
|
|
657
|
+
|
|
658
|
+
</article>
|
|
659
|
+
|
|
660
|
+
\3c !--section:code-->```css */
|
|
661
|
+
|
|
662
|
+
dl.timeline dd, .has-timeline > dl dd {
|
|
663
|
+
margin-block: 0;
|
|
664
|
+
padding: 0.25rem 0 0.75rem 1rem;
|
|
665
|
+
border-inline-start: 0.25rem solid gray;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/*```*/
|
|
669
|
+
|
|
652
670
|
/* Utilities */
|
|
653
671
|
|
|
654
672
|
/* Extends https://github.com/picocss/pico/tree/main/scss/utilities
|
|
@@ -104,7 +104,7 @@ How it works:
|
|
|
104
104
|
|
|
105
105
|
/* Respect img/picture min-width */
|
|
106
106
|
|
|
107
|
-
.breakout > *:is(img, picture), .breakout-all > *:is(img, picture) {
|
|
107
|
+
.breakout > *:is(img, picture):not(.does-not-exist), .breakout-all > *:is(img, picture):not(.does-not-exist) /* soft win specificity over .breakout-item above */ {
|
|
108
108
|
min-width: auto;
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -551,12 +551,7 @@ The `<pre><code>` blocks are Prism-compatible and support captions via `data-cap
|
|
|
551
551
|
How it works:
|
|
552
552
|
```css */
|
|
553
553
|
|
|
554
|
-
|
|
555
|
-
padding: 1rem 1.5rem;
|
|
556
|
-
padding-inline-end: 2rem;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
@media (max-width: 767px) {
|
|
554
|
+
@media (width < 768px) {
|
|
560
555
|
|
|
561
556
|
pre {
|
|
562
557
|
border-radius: 0
|
|
@@ -573,10 +568,6 @@ code[data-caption]::before {
|
|
|
573
568
|
opacity: 50%;
|
|
574
569
|
}
|
|
575
570
|
|
|
576
|
-
code:where(pre > *) {
|
|
577
|
-
padding: 0;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
571
|
/*```
|
|
581
572
|
\3c !--section--> */
|
|
582
573
|
|
|
@@ -587,10 +578,10 @@ code:where(pre > *) {
|
|
|
587
578
|
|
|
588
579
|
First, we target either:
|
|
589
580
|
1. `<label>` which `:has` inner form inputs (classless approach)
|
|
590
|
-
2. or explicit `.has-float-label` class (
|
|
581
|
+
2. or explicit `.has-float-label` class (explicit approach)
|
|
591
582
|
```css */
|
|
592
583
|
|
|
593
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
584
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
594
585
|
.has-float-label {
|
|
595
586
|
display: block;
|
|
596
587
|
position: relative;
|
|
@@ -601,8 +592,8 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
601
592
|
Then, we define the default/fallback state (when the float label should be minimized):
|
|
602
593
|
```css */
|
|
603
594
|
|
|
604
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
605
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
595
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
596
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
606
597
|
.has-float-label > span,
|
|
607
598
|
.has-float-label label {
|
|
608
599
|
position: absolute;
|
|
@@ -617,25 +608,25 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
617
608
|
Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
|
|
618
609
|
```css */
|
|
619
610
|
|
|
620
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
611
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
621
612
|
opacity: 0;
|
|
622
613
|
}
|
|
623
614
|
|
|
624
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
615
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
625
616
|
opacity: 0;
|
|
626
617
|
}
|
|
627
618
|
|
|
628
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
619
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
629
620
|
opacity: 0;
|
|
630
621
|
}
|
|
631
622
|
|
|
632
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
623
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
633
624
|
font-size: inherit;
|
|
634
625
|
opacity: 50%;
|
|
635
626
|
}
|
|
636
627
|
|
|
637
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
638
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
628
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
629
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
639
630
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
640
631
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
641
632
|
font-size: inherit;
|
|
@@ -649,6 +640,33 @@ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state inform
|
|
|
649
640
|
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.
|
|
650
641
|
\3c !--section--> */
|
|
651
642
|
|
|
643
|
+
/* Components */
|
|
644
|
+
|
|
645
|
+
/*\3c !--section:docs-->
|
|
646
|
+
|
|
647
|
+
Use `dl.timeline` or wrap a `<dl>` with `.has-timeline` to style it as a
|
|
648
|
+
vertical timeline — each `<dd>` gets a left border strip acting as the track:
|
|
649
|
+
|
|
650
|
+
<article class="has-timeline">
|
|
651
|
+
|
|
652
|
+
May 11, 2026
|
|
653
|
+
: First Blades CSS stable release (v2.2.0).
|
|
654
|
+
|
|
655
|
+
Mar 15, 2025
|
|
656
|
+
: Last Pico CSS update (v2.1.1).
|
|
657
|
+
|
|
658
|
+
</article>
|
|
659
|
+
|
|
660
|
+
\3c !--section:code-->```css */
|
|
661
|
+
|
|
662
|
+
dl.timeline dd, .has-timeline > dl dd {
|
|
663
|
+
margin-block: 0;
|
|
664
|
+
padding: 0.25rem 0 0.75rem 1rem;
|
|
665
|
+
border-inline-start: 0.25rem solid gray;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/*```*/
|
|
669
|
+
|
|
652
670
|
/* Utilities */
|
|
653
671
|
|
|
654
672
|
/* Extends https://github.com/picocss/pico/tree/main/scss/utilities
|
|
@@ -725,8 +743,8 @@ How it works:
|
|
|
725
743
|
|
|
726
744
|
/* Default/fallback state */
|
|
727
745
|
|
|
728
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
729
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
746
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
747
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
730
748
|
.has-float-label > span,
|
|
731
749
|
.has-float-label label {
|
|
732
750
|
padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
|
|
@@ -735,9 +753,9 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
735
753
|
transition: all 0.25s;
|
|
736
754
|
}
|
|
737
755
|
|
|
738
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
739
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
740
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
756
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
757
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
758
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
741
759
|
.has-float-label input,
|
|
742
760
|
.has-float-label textarea,
|
|
743
761
|
.has-float-label select {
|
|
@@ -746,25 +764,25 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
746
764
|
padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
|
|
747
765
|
}
|
|
748
766
|
|
|
749
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
767
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
750
768
|
opacity: 100%;
|
|
751
769
|
-moz-transition: all 0.25s;
|
|
752
770
|
transition: all 0.25s;
|
|
753
771
|
}
|
|
754
772
|
|
|
755
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
773
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
756
774
|
opacity: 100%;
|
|
757
775
|
transition: all 0.25s;
|
|
758
776
|
}
|
|
759
777
|
|
|
760
778
|
/* Enlarged state */
|
|
761
779
|
|
|
762
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
780
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
763
781
|
padding-block: 0.75rem; /* match Pico */
|
|
764
782
|
}
|
|
765
783
|
|
|
766
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
767
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
784
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
785
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
768
786
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
769
787
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
770
788
|
padding-block: 0.75rem; /* match Pico */
|
|
@@ -815,6 +833,15 @@ a:not([href^="#"]):hover {
|
|
|
815
833
|
text-decoration-thickness: 2px;
|
|
816
834
|
}
|
|
817
835
|
|
|
836
|
+
h1,
|
|
837
|
+
h2,
|
|
838
|
+
h3,
|
|
839
|
+
h4,
|
|
840
|
+
h5,
|
|
841
|
+
h6 {
|
|
842
|
+
text-wrap: balance;
|
|
843
|
+
}
|
|
844
|
+
|
|
818
845
|
h1 {
|
|
819
846
|
margin-bottom: 1rem; /* for tw-typography */
|
|
820
847
|
font-size: 2.5em; /* for pico.css & tw-typography */
|
|
@@ -828,11 +855,24 @@ ul ul {
|
|
|
828
855
|
font-size: 87.5%;
|
|
829
856
|
}
|
|
830
857
|
|
|
858
|
+
dl dt {
|
|
859
|
+
margin-block: 0.25rem;
|
|
860
|
+
font-weight: 500;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
dl dd {
|
|
864
|
+
margin-block-end: 1rem;
|
|
865
|
+
}
|
|
866
|
+
|
|
831
867
|
pre small {
|
|
832
868
|
font-weight: lighter;
|
|
833
869
|
opacity: 75%;
|
|
834
870
|
}
|
|
835
871
|
|
|
872
|
+
pre:has(code) {
|
|
873
|
+
background: #181c25 !important;
|
|
874
|
+
}
|
|
875
|
+
|
|
836
876
|
table th {
|
|
837
877
|
font-weight: bold;
|
|
838
878
|
vertical-align: bottom;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
\3c !--section:code-->
|
|
3
3
|
```css */
|
|
4
4
|
/* Default/fallback state */
|
|
5
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
6
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
5
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
6
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
7
7
|
.has-float-label > span,
|
|
8
8
|
.has-float-label label {
|
|
9
9
|
padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
|
|
@@ -11,9 +11,9 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
11
11
|
opacity: 75%;
|
|
12
12
|
transition: all 0.25s;
|
|
13
13
|
}
|
|
14
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
15
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
16
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
14
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
15
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
16
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
17
17
|
.has-float-label input,
|
|
18
18
|
.has-float-label textarea,
|
|
19
19
|
.has-float-label select {
|
|
@@ -21,21 +21,21 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
21
21
|
padding-inline-start: 1rem; /* match Pico */
|
|
22
22
|
padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
|
|
23
23
|
}
|
|
24
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
24
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
25
25
|
opacity: 100%;
|
|
26
26
|
-moz-transition: all 0.25s;
|
|
27
27
|
transition: all 0.25s;
|
|
28
28
|
}
|
|
29
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
29
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
30
30
|
opacity: 100%;
|
|
31
31
|
transition: all 0.25s;
|
|
32
32
|
}
|
|
33
33
|
/* Enlarged state */
|
|
34
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
34
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
35
35
|
padding-block: 0.75rem; /* match Pico */
|
|
36
36
|
}
|
|
37
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
38
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
37
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
38
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
39
39
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
40
40
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
41
41
|
padding-block: 0.75rem; /* match Pico */
|
|
@@ -78,6 +78,14 @@ a:not([href^="#"]) {
|
|
|
78
78
|
a:not([href^="#"]):hover {
|
|
79
79
|
text-decoration-thickness: 2px;
|
|
80
80
|
}
|
|
81
|
+
h1,
|
|
82
|
+
h2,
|
|
83
|
+
h3,
|
|
84
|
+
h4,
|
|
85
|
+
h5,
|
|
86
|
+
h6 {
|
|
87
|
+
text-wrap: balance;
|
|
88
|
+
}
|
|
81
89
|
h1 {
|
|
82
90
|
margin-bottom: 1rem; /* for tw-typography */
|
|
83
91
|
font-size: 2.5em; /* for pico.css & tw-typography */
|
|
@@ -88,10 +96,20 @@ hr {
|
|
|
88
96
|
ul ul {
|
|
89
97
|
font-size: 87.5%;
|
|
90
98
|
}
|
|
99
|
+
dl dt {
|
|
100
|
+
margin-block: 0.25rem;
|
|
101
|
+
font-weight: 500;
|
|
102
|
+
}
|
|
103
|
+
dl dd {
|
|
104
|
+
margin-block-end: 1rem;
|
|
105
|
+
}
|
|
91
106
|
pre small {
|
|
92
107
|
font-weight: lighter;
|
|
93
108
|
opacity: 75%;
|
|
94
109
|
}
|
|
110
|
+
pre:has(code) {
|
|
111
|
+
background: #181c25 !important;
|
|
112
|
+
}
|
|
95
113
|
table th {
|
|
96
114
|
font-weight: bold;
|
|
97
115
|
vertical-align: bottom;
|
package/css/breakout.css
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
transform: translateX(-50%);
|
|
42
42
|
}
|
|
43
43
|
/* Respect img/picture min-width */
|
|
44
|
-
.breakout > *:is(img, picture), .breakout-all > *:is(img, picture) {
|
|
44
|
+
.breakout > *:is(img, picture):not(.does-not-exist), .breakout-all > *:is(img, picture):not(.does-not-exist) /* soft win specificity over .breakout-item above */ {
|
|
45
45
|
min-width: auto;
|
|
46
46
|
}
|
|
47
47
|
/* Max out the width of the element */
|
package/css/float-label.core.css
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
First, we target either:
|
|
5
5
|
1. `<label>` which `:has` inner form inputs (classless approach)
|
|
6
|
-
2. or explicit `.has-float-label` class (
|
|
6
|
+
2. or explicit `.has-float-label` class (explicit approach)
|
|
7
7
|
```css */
|
|
8
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
8
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
9
9
|
.has-float-label {
|
|
10
10
|
display: block;
|
|
11
11
|
position: relative;
|
|
@@ -14,8 +14,8 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
14
14
|
```
|
|
15
15
|
Then, we define the default/fallback state (when the float label should be minimized):
|
|
16
16
|
```css */
|
|
17
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
18
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
17
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
18
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
19
19
|
.has-float-label > span,
|
|
20
20
|
.has-float-label label {
|
|
21
21
|
position: absolute;
|
|
@@ -28,21 +28,21 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
28
28
|
```
|
|
29
29
|
Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
|
|
30
30
|
```css */
|
|
31
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
31
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
32
32
|
opacity: 0;
|
|
33
33
|
}
|
|
34
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
34
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
35
35
|
opacity: 0;
|
|
36
36
|
}
|
|
37
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
37
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
38
38
|
opacity: 0;
|
|
39
39
|
}
|
|
40
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
40
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
41
41
|
font-size: inherit;
|
|
42
42
|
opacity: 50%;
|
|
43
43
|
}
|
|
44
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
45
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
44
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
45
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
46
46
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
47
47
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
48
48
|
font-size: inherit;
|
package/css/float-label.css
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
First, we target either:
|
|
6
6
|
1. `<label>` which `:has` inner form inputs (classless approach)
|
|
7
|
-
2. or explicit `.has-float-label` class (
|
|
7
|
+
2. or explicit `.has-float-label` class (explicit approach)
|
|
8
8
|
```css */
|
|
9
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
9
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
10
10
|
.has-float-label {
|
|
11
11
|
display: block;
|
|
12
12
|
position: relative;
|
|
@@ -15,8 +15,8 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
15
15
|
```
|
|
16
16
|
Then, we define the default/fallback state (when the float label should be minimized):
|
|
17
17
|
```css */
|
|
18
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
19
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
18
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
19
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
20
20
|
.has-float-label > span,
|
|
21
21
|
.has-float-label label {
|
|
22
22
|
position: absolute;
|
|
@@ -29,21 +29,21 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
29
29
|
```
|
|
30
30
|
Finally, we detect if placeholder is shown, but not in focus. That means we can safely hide it, and enlarge the float label instead:
|
|
31
31
|
```css */
|
|
32
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
32
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::-moz-placeholder, .has-float-label *:placeholder-shown:not(:focus)::-moz-placeholder {
|
|
33
33
|
opacity: 0;
|
|
34
34
|
}
|
|
35
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
35
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:-moz-placeholder:not(:focus)::placeholder, .has-float-label *:-moz-placeholder:not(:focus)::placeholder {
|
|
36
36
|
opacity: 0;
|
|
37
37
|
}
|
|
38
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
38
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) *:placeholder-shown:not(:focus)::placeholder, .has-float-label *:placeholder-shown:not(:focus)::placeholder {
|
|
39
39
|
opacity: 0;
|
|
40
40
|
}
|
|
41
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
41
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
42
42
|
font-size: inherit;
|
|
43
43
|
opacity: 50%;
|
|
44
44
|
}
|
|
45
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
46
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
45
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
46
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
47
47
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
48
48
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
49
49
|
font-size: inherit;
|
|
@@ -56,8 +56,8 @@ The `:has(*:placeholder-shown:not(:focus))` trick allows this input state inform
|
|
|
56
56
|
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.
|
|
57
57
|
\3c !--section--> */
|
|
58
58
|
/* Default/fallback state */
|
|
59
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
60
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
59
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
60
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
61
61
|
.has-float-label > span,
|
|
62
62
|
.has-float-label label {
|
|
63
63
|
padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
|
|
@@ -65,9 +65,9 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
65
65
|
opacity: 75%;
|
|
66
66
|
transition: all 0.25s;
|
|
67
67
|
}
|
|
68
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
69
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
70
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
68
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
69
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
70
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
71
71
|
.has-float-label input,
|
|
72
72
|
.has-float-label textarea,
|
|
73
73
|
.has-float-label select {
|
|
@@ -75,21 +75,21 @@ label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea
|
|
|
75
75
|
padding-inline-start: 1rem; /* match Pico */
|
|
76
76
|
padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
|
|
77
77
|
}
|
|
78
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
78
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
79
79
|
opacity: 100%;
|
|
80
80
|
-moz-transition: all 0.25s;
|
|
81
81
|
transition: all 0.25s;
|
|
82
82
|
}
|
|
83
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
83
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
84
84
|
opacity: 100%;
|
|
85
85
|
transition: all 0.25s;
|
|
86
86
|
}
|
|
87
87
|
/* Enlarged state */
|
|
88
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
88
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
89
89
|
padding-block: 0.75rem; /* match Pico */
|
|
90
90
|
}
|
|
91
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
92
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
91
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
92
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
93
93
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
94
94
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
95
95
|
padding-block: 0.75rem; /* match Pico */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Default/fallback state */
|
|
2
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
3
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
2
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) > span,
|
|
3
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) label,
|
|
4
4
|
.has-float-label > span,
|
|
5
5
|
.has-float-label label {
|
|
6
6
|
padding-inline-start: calc(1rem + 1px); /* match Pico's padding + border */
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
opacity: 75%;
|
|
9
9
|
transition: all 0.25s;
|
|
10
10
|
}
|
|
11
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
12
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
13
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
11
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input,
|
|
12
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea,
|
|
13
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select,
|
|
14
14
|
.has-float-label input,
|
|
15
15
|
.has-float-label textarea,
|
|
16
16
|
.has-float-label select {
|
|
@@ -18,21 +18,21 @@
|
|
|
18
18
|
padding-inline-start: 1rem; /* match Pico */
|
|
19
19
|
padding-block: 1.125rem 0.375rem; /* match Pico's total: 2 x 0.75rem = 1.5rem */
|
|
20
20
|
}
|
|
21
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
21
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::-moz-placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::-moz-placeholder, .has-float-label input::-moz-placeholder, .has-float-label textarea::-moz-placeholder, .has-float-label select::-moz-placeholder {
|
|
22
22
|
opacity: 100%;
|
|
23
23
|
-moz-transition: all 0.25s;
|
|
24
24
|
transition: all 0.25s;
|
|
25
25
|
}
|
|
26
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
26
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) input::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) textarea::placeholder, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) select::placeholder, .has-float-label input::placeholder, .has-float-label textarea::placeholder, .has-float-label select::placeholder {
|
|
27
27
|
opacity: 100%;
|
|
28
28
|
transition: all 0.25s;
|
|
29
29
|
}
|
|
30
30
|
/* Enlarged state */
|
|
31
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
31
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) > span, label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:-moz-placeholder:not(:focus)) label, .has-float-label:has(*:-moz-placeholder:not(:focus)) > span, .has-float-label:has(*:-moz-placeholder:not(:focus)) label {
|
|
32
32
|
padding-block: 0.75rem; /* match Pico */
|
|
33
33
|
}
|
|
34
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
35
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
34
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) > span,
|
|
35
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):has(*:placeholder-shown:not(:focus)) label,
|
|
36
36
|
.has-float-label:has(*:placeholder-shown:not(:focus)) > span,
|
|
37
37
|
.has-float-label:has(*:placeholder-shown:not(:focus)) label {
|
|
38
38
|
padding-block: 0.75rem; /* match Pico */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anyblades/blades",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": "./src/blades.css",
|
|
6
6
|
"./standalone": "./src/blades.standalone.css",
|
|
@@ -44,5 +44,6 @@
|
|
|
44
44
|
"repository": {
|
|
45
45
|
"type": "git",
|
|
46
46
|
"url": "git+https://github.com/anyblades/blades.git"
|
|
47
|
-
}
|
|
48
|
-
|
|
47
|
+
},
|
|
48
|
+
"===": "==="
|
|
49
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*<!--section:docs-->
|
|
2
|
+
|
|
3
|
+
### `sup`er and `sub`headings
|
|
4
|
+
|
|
5
|
+
<article><br>
|
|
6
|
+
|
|
7
|
+
# <sup style>Parent page</sup> Page title <sub style>Subtitle</sub>
|
|
8
|
+
|
|
9
|
+
</article>
|
|
10
|
+
|
|
11
|
+
How it works:
|
|
12
|
+
```css */
|
|
13
|
+
sup[style] {
|
|
14
|
+
display: block;
|
|
15
|
+
font-size: 0.75rem;
|
|
16
|
+
letter-spacing: 0.0625em;
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
}
|
|
19
|
+
sub[style] {
|
|
20
|
+
display: block;
|
|
21
|
+
line-height: 1.1;
|
|
22
|
+
bottom: 0;
|
|
23
|
+
font-weight: 300;
|
|
24
|
+
opacity: 75%;
|
|
25
|
+
|
|
26
|
+
&:where(h1 > *) {
|
|
27
|
+
font-size: 50%;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/*```
|
|
31
|
+
|
|
32
|
+
### Teasers
|
|
33
|
+
|
|
34
|
+
<article style="padding-inline: 2rem">
|
|
35
|
+
<a href="https://blades.ninja/" role="button" class="outline">
|
|
36
|
+
<h4>Blades CSS</h4>
|
|
37
|
+
Fully compatible and actively maintained successor to Pico CSS.
|
|
38
|
+
</a>
|
|
39
|
+
</article>
|
|
40
|
+
|
|
41
|
+
How it works:
|
|
42
|
+
```css */
|
|
43
|
+
a[role="button"]:has(h1, h2, h3, h4, h5, h6) {
|
|
44
|
+
text-align: start;
|
|
45
|
+
border-width: 1px 0 0 1px;
|
|
46
|
+
margin: 0 0 0.5rem -1rem;
|
|
47
|
+
}
|
|
48
|
+
/*```
|
|
49
|
+
|
|
50
|
+
### `.opt`ional content
|
|
51
|
+
|
|
52
|
+
How it works:
|
|
53
|
+
```css */
|
|
54
|
+
.opt {
|
|
55
|
+
@media (width < 1024px) {
|
|
56
|
+
display: none;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/*```
|
|
60
|
+
|
|
61
|
+
### Nicer GitHub favicons
|
|
62
|
+
|
|
63
|
+
<article>
|
|
64
|
+
|
|
65
|
+
https://github.com/anyblades/blades
|
|
66
|
+
|
|
67
|
+
</article>
|
|
68
|
+
|
|
69
|
+
How it works:
|
|
70
|
+
```css */
|
|
71
|
+
img[src*="?domain=github.com&"] {
|
|
72
|
+
border-radius: 50%;
|
|
73
|
+
|
|
74
|
+
@media (prefers-color-scheme: dark) {
|
|
75
|
+
filter: invert(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/*```*/
|
|
@@ -45,6 +45,14 @@ a {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
h1,
|
|
49
|
+
h2,
|
|
50
|
+
h3,
|
|
51
|
+
h4,
|
|
52
|
+
h5,
|
|
53
|
+
h6 {
|
|
54
|
+
text-wrap: balance;
|
|
55
|
+
}
|
|
48
56
|
h1 {
|
|
49
57
|
font-size: 2.5em; /* for pico.css & tw-typography */
|
|
50
58
|
margin-bottom: 1rem; /* for tw-typography */
|
|
@@ -60,11 +68,24 @@ ul {
|
|
|
60
68
|
}
|
|
61
69
|
}
|
|
62
70
|
|
|
71
|
+
dl {
|
|
72
|
+
dt {
|
|
73
|
+
margin-block: 0.25rem;
|
|
74
|
+
font-weight: 500;
|
|
75
|
+
}
|
|
76
|
+
dd {
|
|
77
|
+
margin-block-end: 1rem;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
63
81
|
pre {
|
|
64
82
|
small {
|
|
65
83
|
opacity: 75%;
|
|
66
84
|
font-weight: lighter;
|
|
67
85
|
}
|
|
86
|
+
&:has(code) {
|
|
87
|
+
background: #181c25 !important;
|
|
88
|
+
}
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
table {
|
package/src/breakout.css
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/*<!--section:docs-->
|
|
2
|
+
|
|
3
|
+
Use `dl.timeline` or wrap a `<dl>` with `.has-timeline` to style it as a
|
|
4
|
+
vertical timeline — each `<dd>` gets a left border strip acting as the track:
|
|
5
|
+
|
|
6
|
+
<article class="has-timeline">
|
|
7
|
+
|
|
8
|
+
May 11, 2026
|
|
9
|
+
: First Blades CSS stable release (v2.2.0).
|
|
10
|
+
|
|
11
|
+
Mar 15, 2025
|
|
12
|
+
: Last Pico CSS update (v2.1.1).
|
|
13
|
+
|
|
14
|
+
</article>
|
|
15
|
+
|
|
16
|
+
<!--section:code-->```css */
|
|
17
|
+
dl.timeline,
|
|
18
|
+
.has-timeline > dl {
|
|
19
|
+
dd {
|
|
20
|
+
padding: 0.25rem 0 0.75rem 1rem;
|
|
21
|
+
margin-block: 0;
|
|
22
|
+
border-inline-start: 0.25rem solid gray;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/*```*/
|
package/src/content/_code.css
CHANGED
|
@@ -14,10 +14,7 @@ The `<pre><code>` blocks are Prism-compatible and support captions via `data-cap
|
|
|
14
14
|
How it works:
|
|
15
15
|
```css */
|
|
16
16
|
pre {
|
|
17
|
-
|
|
18
|
-
padding-inline-end: 2rem;
|
|
19
|
-
|
|
20
|
-
@media (max-width: 767px) {
|
|
17
|
+
@media (width < 768px) {
|
|
21
18
|
border-radius: 0;
|
|
22
19
|
}
|
|
23
20
|
}
|
|
@@ -33,10 +30,6 @@ code {
|
|
|
33
30
|
font-style: italic;
|
|
34
31
|
}
|
|
35
32
|
}
|
|
36
|
-
|
|
37
|
-
&:where(pre > *) {
|
|
38
|
-
padding: 0;
|
|
39
|
-
}
|
|
40
33
|
}
|
|
41
34
|
/*```
|
|
42
35
|
<!--section--> */
|
package/src/float-label.core.css
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
First, we target either:
|
|
5
5
|
1. `<label>` which `:has` inner form inputs (classless approach)
|
|
6
|
-
2. or explicit `.has-float-label` class (
|
|
6
|
+
2. or explicit `.has-float-label` class (explicit approach)
|
|
7
7
|
```css */
|
|
8
|
-
label:has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
8
|
+
label:has(> span):has(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select),
|
|
9
9
|
.has-float-label {
|
|
10
10
|
display: block;
|
|
11
11
|
position: relative;
|