From 3e21e26bbc3831b377d1fc5f4005a2a8a1ba7db3 Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Tue, 3 Oct 2023 17:22:04 -0700
Subject: [PATCH 01/30] No more escaping animation / keyframe names. Old Safari
version compatibility.
---
script.js | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/script.js b/script.js
index 51bf104..89b0ceb 100644
--- a/script.js
+++ b/script.js
@@ -1,16 +1,15 @@
// 🌘 CSS Scope Inline (https://github.com/gnat/css-scope-inline)
window.cssScopeCount ??= 1 // Let extra copies share the scope count.
-new MutationObserver(mutations => {
- document?.body?.querySelectorAll('style').forEach(node => { // Faster than walking MutationObserver results when recieving subtree (DOM swap, htmx, ajax, jquery).
- if (node.cssScopeInlineDone) return // Skip if node was processed.
- if (!node.parentNode) return // Skip if no parent.
- var scope = 'self__'+(window.cssScopeCount++) // Ready. Make unique scope, example: .self__1234
+window.cssScope ??= new MutationObserver(mutations => { // Allow 1 observer.
+ document?.body?.querySelectorAll('style:not([ready])').forEach(node => { // Faster than walking MutationObserver results when recieving subtree (DOM swap, htmx, ajax, jquery).
+ var scope = 'me__'+(window.cssScopeCount++) // Ready. Make unique scope, example: .me__1234
node.parentNode.classList.add(scope)
- node.textContent = node.textContent.replace(/(^|\.|(?<=\s|[^a-zA-Z0-9\-\_]))(me|this|self)(?![a-zA-Z])/g, '.'+scope) // Can use: me this self
- node.cssScopeInlineDone = 1
- // Optional. Responsive design. Mobile First (above breakpoint): 🟢 None sm md lg xl xx 🏁 Desktop First (below breakpoint): 🏁 xs- sm- md- lg- xl- None 🟢
- node.textContent = node.textContent.replace(/(?:@media)\s(xs-|sm-|md-|lg-|xl-|sm|md|lg|xl|xx)/g, // *- matches must be first!
+ node.textContent = node.textContent
+ .replace(/(?:^|\.|(\s|[^a-zA-Z0-9\-\_]))(me|this|self)(?![a-zA-Z])/g, '$1.'+scope) // Can use: me this self
+ .replace(/((@keyframes|animation:|animation-name:)[^{};]*)\.me__/g, '$1me__') // Optional. Removes need to escape names using \
+ .replace(/(?:@media)\s(xs-|sm-|md-|lg-|xl-|sm|md|lg|xl|xx)/g, // Optional. Responsive design. Mobile First (above breakpoint): 🟢 None sm md lg xl xx 🏁 Desktop First (below breakpoint): 🏁 xs- sm- md- lg- xl- None 🟢 *- matches must be first!
(match, part1) => { return '@media '+({'sm':'(min-width: 640px)','md':'(min-width: 768px)', 'lg':'(min-width: 1024px)', 'xl':'(min-width: 1280px)', 'xx':'(min-width: 1536px)', 'xs-':'(max-width: 639px)', 'sm-':'(max-width: 767px)', 'md-':'(max-width: 1023px)', 'lg-':'(max-width: 1279px)', 'xl-':'(max-width: 1535px)'}[part1]) }
)
+ node.setAttribute('ready', '')
})
}).observe(document.documentElement, {childList: true, subtree: true})
From cb4363cb538fdf007bfdc615cdfbcf5994f934bb Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Tue, 3 Oct 2023 17:28:29 -0700
Subject: [PATCH 02/30] Update example.html
---
example.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/example.html b/example.html
index 396af7b..174c7fa 100644
--- a/example.html
+++ b/example.html
@@ -47,8 +47,8 @@
}
}
/* Animations */
- me { animation: \me 2s ease-in-out infinite }
- @keyframes \me { /* ♻️ Looped animation @keyframes can be scoped using \ */
+ me { animation: me 2s ease-in-out infinite }
+ @keyframes me { /* ♻️ Looped animation @keyframes can be scoped! (Use me-* or me_* for more names) */
0% { transform: translateY(0px); }
50% { transform: translateY(20px); }
100% { transform: translateY(0px); }
From b3ab44b923706e40432dd435b8117c89948bbc6e Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Tue, 3 Oct 2023 17:29:38 -0700
Subject: [PATCH 03/30] Update example.html
---
example.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/example.html b/example.html
index 174c7fa..4b8052b 100644
--- a/example.html
+++ b/example.html
@@ -51,7 +51,7 @@
@keyframes me { /* ♻️ Looped animation @keyframes can be scoped! (Use me-* or me_* for more names) */
0% { transform: translateY(0px); }
50% { transform: translateY(20px); }
- 100% { transform: translateY(0px); }
+ 100% { transform: translateY(0px); }
}
/* Plain CSS works untouched! */
h1, h2, h3 { font-size: 3rem; margin: 20px 0; }
From 06825abc1b6c88b31bf016b1a88137c4e3590dc3 Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Tue, 3 Oct 2023 17:31:57 -0700
Subject: [PATCH 04/30] Update example.html
---
example.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/example.html b/example.html
index 4b8052b..9867c77 100644
--- a/example.html
+++ b/example.html
@@ -48,7 +48,7 @@
}
/* Animations */
me { animation: me 2s ease-in-out infinite }
- @keyframes me { /* ♻️ Looped animation @keyframes can be scoped! (Use me-* or me_* for more names) */
+ @keyframes me { /* ♻️ Looped animation @keyframes can be scoped! .. prefix with me- or me_ for more names! */
0% { transform: translateY(0px); }
50% { transform: translateY(20px); }
100% { transform: translateY(0px); }
From c629b52fdeef84de8e668b13f460a71a2d051b61 Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Tue, 3 Oct 2023 17:33:04 -0700
Subject: [PATCH 05/30] Update example.html
---
example.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/example.html b/example.html
index 9867c77..0dbac85 100644
--- a/example.html
+++ b/example.html
@@ -3,7 +3,7 @@
🌘 CSS Scope Inline Test Page
-
+
red
green
From 3ed9972f5b2b268b0f3fcdd5b122fb089ab365f6 Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Wed, 27 Nov 2024 15:45:27 -0800
Subject: [PATCH 28/30] Update README.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 4a75837..c87898c 100644
--- a/README.md
+++ b/README.md
@@ -63,8 +63,8 @@ Use whatever you'd like, but there's a few advantages with this approach over Ta
* Flat, 1 selector per line can be very short like Tailwind. See the examples.
* Use just plain CSS variables in your design system.
* Use the short `@media` queries for responsive design.
- * Mobile First (flow: **above** breakpoint): **🟢 None** `sm` `md` `lg` `xl` `xx` 🏁
- * Desktop First (flow: **below** breakpoint): 🏁 `xs-` `sm-` `md-` `lg-` `xl-` **🟢 None**
+ * Mobile First (flow: **above** breakpoint): **🟢 None (xs)** `sm` `md` `lg` `xl` `xx` 🏁
+ * Desktop First (flow: **below** breakpoint): 🏁 `xs-` `sm-` `md-` `lg-` `xl-` **🟢 None (xx)**
* 🟢 = No breakpoint. Default. See the [Live Example](https://gnat.github.io/css-scope-inline/example.html)!
* Based on [Tailwind](https://tailwindcss.com/docs/responsive-design) breakpoints. We use `xx` not `2xl` to not break CSS highlighters.
* Unlike Tailwind, you can [nest your @media styles](https://developer.chrome.com/articles/css-nesting/#nesting-media)!
From b75583fe2bc4af41c4f187a5bb7ef5a790ce90cd Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Thu, 28 Nov 2024 13:28:02 -0800
Subject: [PATCH 29/30] Improved Responsive Design docs.
---
example.html | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/example.html b/example.html
index 2c59d33..02fb7e7 100644
--- a/example.html
+++ b/example.html
@@ -74,7 +74,7 @@ 🛸 Scoped style using me
me div ul li { display: inline-block; width: 110px; text-align: center; background: #444; border-radius: 5px; padding: 10px 2px; margin: 10px 10px }
Responsive Design 🔛 Resize the window!
- 🟢 = No breakpoint. Default.
+ 🟢 = None specified.
-
Mobile First (above breakpoint)
+
📱 Mobile First! Add styles as size increases.
@@ -99,7 +99,7 @@
Responsive Design 🔛 Resize the window!
@media xs- { &[n6] { background: var(--color); } }
}
-
Desktop First (below breakpoint)
+
💻 Desktop First! Add styles as size decreases.
From 94c64bef727a6f81317f0473d379a133e9d35ef4 Mon Sep 17 00:00:00 2001
From: Nathaniel Sabanski
Date: Sat, 30 Nov 2024 05:49:03 -0800
Subject: [PATCH 30/30] Added more notes to Tailwind comparison.
---
README.md | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index c87898c..38435f5 100644
--- a/README.md
+++ b/README.md
@@ -47,9 +47,10 @@ Or, 🌐 CDN: `