diff --git a/packages/beasties/README.md b/packages/beasties/README.md
index d2abc28..be3d188 100644
--- a/packages/beasties/README.md
+++ b/packages/beasties/README.md
@@ -244,6 +244,24 @@ You can estimate the contents of your viewport roughly and add a
```
+You can mark more than one element with `data-beasties-container`. CSS is then inlined if it matches inside _any_ of the containers, which is useful when the above-the-fold content is spread across multiple disconnected regions.
+
+```html
+
+
+
+ /* evaluated */
+
+
+ /* ignored */
+
+
+
+
+```
+
_Note: This is an easy way to improve the performance of Beasties_
### Skipping individual stylesheets
diff --git a/packages/beasties/src/dom.ts b/packages/beasties/src/dom.ts
index ca14240..392fe02 100644
--- a/packages/beasties/src/dom.ts
+++ b/packages/beasties/src/dom.ts
@@ -65,16 +65,18 @@ export function createDocument(html: string) {
// Extend Element.prototype with DOM manipulation methods.
extendElement(Element.prototype)
- // Beasties container is the viewport to evaluate critical CSS
- let beastiesContainer: Node | HTMLDocument = document.querySelector('[data-beasties-container]') as Node
+ // Beasties containers are the viewport to evaluate critical CSS.
+ let beastiesContainers: (Node | HTMLDocument)[] = document.querySelectorAll('[data-beasties-container]') as Node[]
- if (!beastiesContainer) {
+ if (!beastiesContainers.length) {
document.documentElement?.setAttribute('data-beasties-container', '')
- beastiesContainer = document.documentElement || document
+ beastiesContainers = [document.documentElement || document]
}
- document.beastiesContainer = beastiesContainer
- buildCache(beastiesContainer)
+ document.beastiesContainers = beastiesContainers
+ for (const container of beastiesContainers) {
+ buildCache(container)
+ }
return document
}
@@ -257,7 +259,11 @@ export interface HTMLDocument extends ParsedDocument {
exists: (sel: string) => boolean
querySelector: (sel: string) => Node
querySelectorAll: (sel: string) => Node[]
+ /**
+ * @deprecated
+ */
beastiesContainer: HTMLDocument | Node
+ beastiesContainers: (HTMLDocument | Node)[]
}
function extendDocument(document: ParsedDocument): asserts document is HTMLDocument {
@@ -336,6 +342,12 @@ function extendDocument(document: ParsedDocument): asserts document is HTMLDocum
return selectAll(sel, this)
},
},
+
+ beastiesContainer: {
+ get() {
+ return this.beastiesContainers?.[0]
+ },
+ },
})
}
diff --git a/packages/beasties/src/index.ts b/packages/beasties/src/index.ts
index 68689ba..e85bcb8 100644
--- a/packages/beasties/src/index.ts
+++ b/packages/beasties/src/index.ts
@@ -493,7 +493,7 @@ export default class Beasties {
const name = style.$$name ? style.$$name.replace(LEADING_SLASH_RE, '') : 'inline CSS'
const options = this.options
- const beastiesContainer = document.beastiesContainer!
+ const beastiesContainers = document.beastiesContainers!
let keyframesMode = options.keyframes ?? 'critical'
// we also accept a boolean value for options.keyframes
if (keyframesMode === true)
@@ -612,7 +612,7 @@ export default class Beasties {
return false
try {
- return beastiesContainer.exists(sel)
+ return beastiesContainers.some(container => container.exists(sel))
}
catch (e) {
failedSelectors.push(`${sel} -> ${(e as Error).message || (e as Error).toString()}`)
diff --git a/packages/beasties/test/beasties.test.ts b/packages/beasties/test/beasties.test.ts
index 2d2b21c..56c33af 100644
--- a/packages/beasties/test/beasties.test.ts
+++ b/packages/beasties/test/beasties.test.ts
@@ -78,6 +78,96 @@ describe('beasties', () => {
`)
})
+ it('should inline critical CSS from multiple beasties containers', async () => {
+ const beasties = new Beasties()
+ const result = await beasties.process(trim`
+
+
+
+