0
# matchMedia Polyfill
1
2
The matchMedia polyfill provides window.matchMedia functionality for browsers that don't support it natively. This enables testing CSS media queries programmatically in JavaScript, essential for responsive JavaScript behavior.
3
4
## Capabilities
5
6
### window.matchMedia Function
7
8
Creates MediaQueryList objects for testing media queries in JavaScript.
9
10
```javascript { .api }
11
/**
12
* Test a CSS media query in JavaScript
13
* Creates a temporary DOM element to test if the media query matches
14
* @param query - CSS media query string to test
15
* @returns MediaQueryList object with match result and query string
16
*/
17
declare function matchMedia(query: string): MediaQueryList;
18
19
interface MediaQueryList {
20
/** Whether the media query currently matches the viewport */
21
matches: boolean;
22
/** The original media query string that was tested */
23
media: string;
24
}
25
```
26
27
**Usage Examples:**
28
29
```javascript
30
// Test viewport width
31
var mql = matchMedia('(min-width: 768px)');
32
if (mql.matches) {
33
console.log('Viewport is at least 768px wide');
34
} else {
35
console.log('Viewport is less than 768px wide');
36
}
37
38
// Test different media types
39
var printQuery = matchMedia('print');
40
if (printQuery.matches) {
41
console.log('Print styles are active');
42
}
43
44
// Test complex queries
45
var complexQuery = matchMedia('screen and (min-width: 480px) and (max-width: 1024px)');
46
if (complexQuery.matches) {
47
console.log('Medium-sized screen detected');
48
}
49
```
50
51
### MediaQueryList Interface
52
53
Result object returned by matchMedia calls.
54
55
```javascript { .api }
56
interface MediaQueryList {
57
/**
58
* Boolean indicating whether the media query matches current conditions
59
* Updated each time matchMedia is called with the same query
60
*/
61
matches: boolean;
62
63
/**
64
* The original media query string passed to matchMedia
65
* Preserved exactly as provided
66
*/
67
media: string;
68
}
69
```
70
71
## Implementation Details
72
73
### Testing Mechanism
74
75
The polyfill works by creating a temporary DOM structure to test media queries:
76
77
1. **Temporary Elements**: Creates a hidden div and style element
78
2. **CSS Injection**: Injects a test CSS rule with the media query
79
3. **Dimension Check**: Measures the test element to determine if the query matches
80
4. **Cleanup**: Removes temporary elements after testing
81
82
### Browser Compatibility
83
84
- **IE 9+**: Native matchMedia support (polyfill not used)
85
- **IE 6-8**: Polyfill provides full functionality
86
- **Modern Browsers**: Native implementation used when available
87
- **Early Exit**: Polyfill detects native support and defers to it
88
89
### Test CSS Pattern
90
91
```css
92
/* Example of injected test CSS */
93
@media (min-width: 768px) {
94
#mq-test-1 { width: 42px; }
95
}
96
```
97
98
The polyfill checks if the test element (#mq-test-1) has a width of 42px to determine if the media query matches.
99
100
### Supported Query Types
101
102
The matchMedia polyfill supports the same media query features as the main respond.js library:
103
104
- **Width queries**: min-width, max-width
105
- **Media types**: screen, print, all, etc.
106
- **Units**: px, em
107
- **Complex queries**: Multiple conditions with 'and'
108
109
### Query Parsing Examples
110
111
```javascript
112
// Simple width queries
113
matchMedia('(min-width: 600px)').matches;
114
matchMedia('(max-width: 1200px)').matches;
115
116
// Media type queries
117
matchMedia('screen').matches;
118
matchMedia('print').matches;
119
120
// Complex combined queries
121
matchMedia('screen and (min-width: 768px)').matches;
122
matchMedia('screen and (min-width: 480px) and (max-width: 1024px)').matches;
123
124
// Em-based queries
125
matchMedia('(min-width: 30em)').matches;
126
matchMedia('(max-width: 60em)').matches;
127
```
128
129
## Integration with Respond.js
130
131
### Bundled Versions
132
133
The matchMedia polyfill is included in certain respond.js distributions:
134
135
- **respond.src.js**: Includes matchMedia polyfill + core respond.js
136
- **respond.matchmedia.addListener.src.js**: Includes matchMedia + addListener + core
137
138
### Standalone Usage
139
140
The matchMedia polyfill can be used independently of respond.js for projects that only need programmatic media query testing without CSS polyfill functionality.
141
142
```html
143
<!-- Standalone matchMedia polyfill -->
144
<script src="matchmedia.polyfill.js"></script>
145
146
<script>
147
// Now available in all browsers
148
if (matchMedia('(min-width: 768px)').matches) {
149
// JavaScript for larger screens
150
}
151
</script>
152
```
153
154
### Conditional Loading
155
156
```javascript
157
// Check if matchMedia is already available
158
if (!window.matchMedia) {
159
// Load polyfill only if needed
160
var script = document.createElement('script');
161
script.src = 'matchmedia.polyfill.js';
162
document.head.appendChild(script);
163
}
164
```
165
166
## Performance Considerations
167
168
### Caching
169
170
The polyfill creates fresh DOM elements for each test, so frequent matchMedia calls with the same query should store the result:
171
172
```javascript
173
// Inefficient - creates new test elements each time
174
function checkViewport() {
175
return matchMedia('(min-width: 768px)').matches;
176
}
177
178
// Better - cache the MediaQueryList object
179
var desktopQuery = matchMedia('(min-width: 768px)');
180
function checkViewport() {
181
return desktopQuery.matches;
182
}
183
```
184
185
### Timing
186
187
The polyfill involves DOM manipulation, so it's best called:
188
- During initialization
189
- In response to resize events (with throttling)
190
- Before layout-dependent operations
191
192
```javascript
193
// Good usage pattern
194
var queries = {
195
mobile: matchMedia('(max-width: 767px)'),
196
tablet: matchMedia('(min-width: 768px) and (max-width: 1023px)'),
197
desktop: matchMedia('(min-width: 1024px)')
198
};
199
200
function handleResize() {
201
if (queries.mobile.matches) {
202
// Mobile layout
203
} else if (queries.tablet.matches) {
204
// Tablet layout
205
} else if (queries.desktop.matches) {
206
// Desktop layout
207
}
208
}
209
```