Browser window resizing is a key aspect of responsive web development. The resize
event allows you to execute JavaScript when the viewport changes size. In this comprehensive guide, we’ll dig into use cases, optimizations, caveats, and cutting-edge techniques for leveraging resize events effectively.
Why Resize Events Matter for Responsive Web Design
Resize events are the backbone of responsive web design. They allow you to gracefully handle changes in browser width and height across devices and orientations.
Some key advantages:
- Adjust layouts – Responsively update grid column counts, text sizes, padding, and more as space changes.
- Resize media – Scale videos, maps, visualizations, and images to fit new container dimensions.
- Modify UI – Show, hide, collapse, or shift page elements based on available room.
- Analytics – Track viewport sizes and usage trends to guide responsive changes.
Without resize event handling, websites would simply break instead of intelligently adapting.
83% of web traffic now comes from smartphones and tablets. Supporting these fluid viewports requires resize event expertise.
Comparison of Resize and Other Size Change Events
The resize event fires when the interior window dimensions change. Some other events to be aware of:
orientationchange: Occurs when mobile devices shift between landscape and portrait modes.
DevicePixelRatio change: Density of pixels can change on zoom.
Visual Viewport: On mobile browsers, resizing doesn‘t affect the visual viewport size which requires special handling.
So while the raw browser window resizes, what users actually see on-page may not correlate due to mobile browser URL bars and zooming complexities.
Resize Event Use Cases
Now let’s explore some practical examples of handling window.resize
events:
Flexbox Layout Adjustments
Use resize events for column and layout changes with Flexbox or CSS grids:
window.addEventListener(‘resize‘, () => {
let width = window.innerWidth
if (width >= 1000) {
// Apply class with wider column layout
} else {
// Switch to single column mobile layout
}
})
Then write CSS like:
.wide-layout {
display: flex;
flex-wrap: nowrap;
}
.mobile-layout {
display: block;
}
This allows fluid column and content reflowing as the browser width shifts.
Typography and Spacing
Resize events also enable modifying text size and spacing responsively.
As an example:
let width = window.innerWidth
if (width < 500) {
document.body.style.fontSize = "14px";
} else {
document.body.style.fontSize = "18px";
}
Now text resize adjusts seamlessly across breakpoints for improved readability.
Charts and Graphs
Data visualizations like charts must fit available space:
function resizeCharts() {
// Recalc chart sizes
let charts = document.querySelectorAll(‘.chart‘)
charts.forEach(chart => {
chart.style.width = window.innerWidth + ‘px‘
})
}
window.addEventListener(‘resize‘, resizeCharts)
This scales graphic elements proportionally without loss of aspect ratio.
Image and Video Dimensions
For embedded video players, maps, or hero images, resize events keep things sized correctly:
let media = document.getElementById(‘hero-image‘)
function scaleMedia() {
media.style.height = window.innerHeight + ‘px‘
}
window.addEventListener(‘resize‘, scaleMedia)
Now they‘ll fluidly occupy the maximum space available.
Mobile Browser Idiosyncrasies
On mobile devices, the address bar and toolbars shift page content on scroll. innerHeight
won‘t account for those changing values.
Use window.visualViewport
readings with resize events for mobile cross-browser support:
if (‘visualViewport‘ in window) {
// Visual Viewport API supported
} else {
// Use window.innerWidth/Height
}
This checks for visual viewport support first.
You can even set the scale:
window.visualViewport.scale = 1.5
Scrollable Elements
The resize event also works on scrollable container elements:
let container = document.getElementById(‘scroll‘)
container.addEventListener(‘resize‘, () => {
if (container.offsetWidth <= 500) {
container.classList.add(‘mobile-view‘)
} else {
container.classList.remove(‘mobile-view‘)
}
})
Now child content can adapt layouts, text sizes, etc per that container’s width.
Performance Considerations
Due to rapid succession of events during intensive window resizing, the callback function may hinder performance if doing complex work.
Debouncing Events
Debouncing accumulates processing to occur once per graceful period versus constant firing:
let debounceTimer
function resizeHandler(){
// Processing logic
}
window.addEventListener(‘resize‘, () => {
clearTimeout(debounceTimer)
debounceTimer = setTimeout(resizeHandler, 100)
})
Now resizeHandler
won‘t invoke more than once per 100ms.
Throttling Frequency
Throttling guarantees a maximum invocation allowance per timeframe:
function handleResize() {
// Logic
}
let throttleTimer
window.addEventListener(‘resize‘, () => {
if (!throttleTimer) {
handleResize()
throttleTimer = setTimeout(() => {
throttleTimer = null
}, 1000 / 60) // max 60 fps
}
})
This throttle pattern plays nicely with requestAnimationFrame
too.
Request Animation Frame
Use window.requestAnimationFrame
for visual updates rather than running logic on every resize event:
function resizeVisualUpdates() {
// Update visuals
document.body.style.color = ‘red‘
}
window.addEventListener(‘resize‘, () => {
window.requestAnimationFrame(resizeVisualUpdates)
})
This cues changes right before repaints for optimization.
Memory Leak Avoidance
Be sure to clean up unneeded listeners by calling removeEventListener
when you‘re done:
function handleResize() {
// ...
}
window.addEventListener(‘resize‘, handleResize)
// Remove later during cleanup
window.removeEventListener(‘resize‘, handleResize)
Stale resize event listeners floating around contribute to memory leaks over prolonged usage.
Accessibility Considerations
Resize events alter dimensions, impacting usability:
- Text size changes can increase/decrease legibility
- Layout flows may confuse users that depend on stability
- Color contrast issues may emerge on width shifts
- Ensure tap targets remain large enough on narrow views
- Announce significant layout changes to screen readers with ARIA
Set minimum text sizes, test contrast changes, watch tap target spacing, and announce shifts with live regions.
Browser Support and Workarounds
The resize event enjoys excellent browser support, with the exception of old IE versions:
Browser | Lowest Supported Version |
---|---|
Chrome | Yes |
Firefox | Yes |
Safari | Yes |
Opera | Yes |
Edge | Yes |
IE | 11 |
For IE 9, the resize event will not work unless CSS references the documentElement
like:
html {
box-sizing: border-box;
}
IE 8 has no support. The best option is a JavaScript Resize Observer polyfill.
The ResizeObserver API
Beyond raw resize events, the newer ResizeObserver API offers an alternative for detecting size changes on elements:
import ResizeObserver from ‘resize-observer-polyfill‘
const ro = new ResizeObserver((entries) => {
entries.forEach(entry => {
let {width, height} = entry.contentRect
})
})
ro.observe(document.body)
Benefits over resize events:
- Observe specific elements rather than just viewport
- More detail on sizing and positioning changes
- Fires less frequently for better performance
This opens additional possibilities like advanced responsive components tracking their own size adjustments separate from window changes.
I suggest polyfilling for full support today, but native browser adoption continues ramping up.
Conclusion
I hope this guide gave you a comprehensive perspective on handling browser window resize events in JavaScript. They serve as the foundation for responsive web UIs that adapt across device sizes, orientations, feature presences, and other ergonomic factors.
Combine native events with requestAnimationFrame, debouncing, media queries, and other tools covered here to build the robust, flowing multi-device interfaces that users expect in the modern era.
Let me know if you have any other questions!