-
Notifications
You must be signed in to change notification settings - Fork 50
/
README.md
135 lines (98 loc) · 4.33 KB
/
README.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Container Query Polyfill
*Please note that this polyfill is now in maintenance mode, as of Nov, 2022. We are not planning to add more features or enhancements.*
____________________________
A small (9 kB compressed) polyfill for CSS Container Queries using [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) and [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) supporting the full [`@container`](https://drafts.csswg.org/css-contain-3/) query syntax:
- Discrete queries (`width: 300` and `min-width: 300px`)
- Range queries (`200px < width < 400px` and `width < 400px`)
- Container relative length units (`cqw`, `cqh`, `cqi`, `cqb`, `cqmin`, and `cqmax`) in properties and keyframes
## Browser Support
- Firefox 69+
- Chrome 79+
- Edge 79+
- Safari 13.4+
## Getting Started
### Installation
```bash
npm install --save container-query-polyfill
```
Alternatively, you can use it directly from a CDN:
```js
<script src="https://cdn.jsdelivr.net/npm/container-query-polyfill@1/dist/container-query-polyfill.modern.js"></script>
```
For the best user experience, it's recommended that you initially only use the polyfill for content below-the-fold and use `@supports` queries to temporarily replace it with a loading indicator until the polyfill is ready to display it:
```css
@supports not (container-type: inline-size) {
.container,
footer {
display: none;
}
.loader {
display: flex;
}
}
```
You can view a more complete demo [here](https://codesandbox.io/s/smoosh-glitter-m2ub4w?file=/index.html). On sufficiently fast networks and devices, or devices that natively support Container Queries, this loading indicator will never be displayed.
> **Note**
> Keep in mind that this technique effectively limits impact on FID and CLS, potentially at the expense of LCP. You may see regressions in the latter as a result, particularly on lower end devices or in poor network conditions.
## Limitations
- **CSS first**: The polyfill currently only supports `<style>` and same-origin `<link>` elements. Inline styles via the `style` attribute or CSSOM methods are not polyfilled. Likewise, JavaScript APIs like `CSSContainerRule` are not polyfilled, and APIs like `CSS.supports()` are not monkey-patched.
- **Best effort**: Style changes that do not lead to observable DOM or layout mutations (e.g. changing `font-size` in a container without content) may not be detected, or may be detected a frame late on some browsers. [Complex sibling CSS selectors](https://github.com/GoogleChromeLabs/container-query-polyfill/issues/56) aren't supported.
- Currently, there is no support for Shadow DOM, or functions like `calc(...)` in container conditions. Your contribution would be welcome!
## Supporting browsers without `:where()`
The polyfill uses the CSS [`:where()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:where) pseudo-class to avoid changing the specificity of your rules. This pseudo-class is relatively new, however. If you need to support browsers without it, you will need to append the dummy `:not(container-query-polyfill)` pseudo-class to the originating element of every selector under a `@container` block:
<table>
<tr>
<td> Before </td> <td> After </td>
</tr>
<tr>
<td>
```css
@container (min-width: 200px) {
#foo {
/* ... */
}
.bar {
/* ... */
}
#foo,
.bar {
/* ... */
}
ul > li {
/* ... */
}
::before {
/* ... */
}
}
```
</td>
<td>
```css
@container (min-width: 200px) {
#foo:not(.container-query-polyfill) {
/* ... */
}
.bar:not(.container-query-polyfill) {
/* ... */
}
#foo:not(.container-query-polyfill),
.bar:not(.container-query-polyfill) {
/* ... */
}
ul > li:not(.container-query-polyfill) {
/* ... */
}
:not(.container-query-polyfill)::before {
/* ... */
}
}
```
</td>
</tr>
</table>
This is to ensure the specificity of your rules never changes (e.g. while the polyfill is loading, or on browsers with native support for container queries). On browsers without `:where()` supports, rules without the dummy will be ignored.
## ResizeObserver Loop Errors
When using the polyfill, you may observe reports of errors like `ResizeObserver loop completed with undelivered notifications` or `ResizeObserver loop limit exceeded`. These are expected, and may safely be ignored.
## License
[Apache 2.0](LICENSE)