CSS Grid Overlap Demo - Online Layered Layout Techniques
Place multiple grid items into the same cells to create overlapping layouts. Learn the technique visually. Copy code.
UD5 Toolkit
Real-time monitoring of XHR & Fetch upload progress with live speed, ETA, and detailed logs
Drag & drop a file here
Tap to select or drop file
or click to browse files
Max 50MB for real upload Β· Any size for simulation
function xhrUploadWithProgress(url, file, onProgress) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
// Track upload progress via xhr.upload
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
onProgress(e.loaded, e.total);
}
});
xhr.addEventListener('load', () => {
if (xhr.status >= 200 && xhr.status < 300) resolve(xhr);
else reject(new Error(`HTTP ${xhr.status}`));
});
xhr.addEventListener('error', () => reject(new Error('Network error')));
xhr.addEventListener('abort', () => reject(new Error('Upload aborted')));
xhr.open('POST', url);
xhr.send(file); // Native progress events fire automatically
});
}
// Fetch API has NO native upload progress events.
// We wrap the file stream with ReadableStream to track bytes sent.
async function fetchUploadWithProgress(url, file, onProgress, signal) {
const fileStream = file.stream();
const reader = fileStream.getReader();
let uploaded = 0;
const trackingStream = new ReadableStream({
async pull(controller) {
const { done, value } = await reader.read();
if (done) { controller.close(); return; }
uploaded += value.byteLength;
onProgress(uploaded, file.size);
controller.enqueue(value);
}
});
const response = await fetch(url, {
method: 'POST',
body: trackingStream,
duplex: 'half', // Required for streaming body
signal,
headers: {
'Content-Type': file.type || 'application/octet-stream',
'Content-Length': String(file.size),
}
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response;
}
progress events on xhr.upload, fetch treats the request body as a stream. To track upload progress, you need to wrap the body stream with a ReadableStream and count bytes as they are read β this is the modern, composable approach. Browser vendors opted for stream-based APIs over event-based ones for greater flexibility.
duplex: 'half' and why is it required?
duplex: 'half' tells the browser that the request body is a half-duplex stream β data flows in one direction (client β server). This is required when using a ReadableStream as the fetch body. Without it, the browser will throw a TypeError. This option was introduced to support streaming request bodies while maintaining backward compatibility. It's supported in Chrome 105+, Firefox 120+, Safari 17+, and Edge 105+.
xhr.upload.onprogress event is supported in all browsers and gives accurate, real-time progress data. Fetch with ReadableStream wrapping is the modern equivalent but requires newer browser APIs. For production applications targeting all browsers, XHR remains the safer choice. For modern SPAs, the Fetch + ReadableStream pattern works well with proper feature detection.
xhr.abort() β this triggers the abort event. For Fetch, create an AbortController, pass its signal to the fetch options, and call controller.abort() to cancel. When using ReadableStream for upload tracking, the stream's pull() method will stop being called after cancellation. Both methods cleanly terminate the upload.
speed = deltaBytes / deltaTime. This provides a smooth, responsive speed reading that adapts to network fluctuations without excessive jitter. ETA is then derived as remainingBytes / currentSpeed.
pull() is called once, reads the whole file, and progress jumps from 0% to 100% instantly. This is expected behavior. For meaningful progress tracking, files should be at least a few hundred KB. Use the simulation mode in this tool to see granular progress with any file size.
xhr.upload.onprogress. In Fetch, wrap the request body stream. Download progress tracks data received from server to client (response body). In XHR, use xhr.onprogress. In Fetch, read response.body.getReader() and count bytes. These are separate concerns β don't confuse them!
FormData for multipart uploads?
FormData, the browser constructs the multipart body internally. You cannot easily wrap it with a ReadableStream for progress tracking. The best approach is to either: (a) use XHR with FormData (native progress events work), or (b) construct the multipart body manually as a Blob or stream. For simple file uploads, sending the raw file with Content-Type is simpler and fully trackable.
Place multiple grid items into the same cells to create overlapping layouts. Learn the technique visually. Copy code.
Control imageβorientation: from-image vs none. See how the browser interprets EXIF rotation. Fix portrait photos.
Experiment with scrollβstate container queries to style elements when they are stuck, snapped, or overflowed. Experimental.
Hover over tiles to see every CSS cursor value in action. Quick visual reference for choosing the right UI feedback.
Configure how your PWA launches: focus existing or create new. Test with the launch_handler manifest field.
Build a horizontal scrollβsnap container with configurable snapβtype and alignment. Perfect for image galleries.
Compare all CSS easing presets side by side on a bouncing ball. See which curve fits your UI animation.
Query the permission state of camera, microphone, geolocation, and more. See the response and learn the API.
Process audio faster than realβtime with OfflineAudioContext. Apply filters and export the result. Dev tool.
Drop files onto a zone and see a preview with name, size, and type. Copy the JavaScript pattern for your site.
Start a fetch request and cancel it with AbortController. See how to implement request cancellation. Interactive.
Demonstrate how to add custom headers and POSTβlike functionality to EventSource using a polyfill. Code and example.
Scroll a container and see how sticky elements behave. Adjust top, bottom, and scroll margins. Copy the code.
See how overflow: visible, hidden, scroll, and auto behave with real content. Clone to test with your text.
Try all objectβfit values (fill, contain, cover, scaleβdown) on an image. Adjust objectβposition. Copy the CSS.
See the difference between clone and slice on inline boxes that break across lines. Useful for multiβline headings.
Use CSS masks and fixed backgrounds to create a unique parallax reveal effect. Copy the code. No JavaScript.
Render the classic Stanford Bunny with a basic WebGPU pipeline. Rotate and zoom. Check if your browser supports WebGPU.
See how scrollβpadding and scrollβmargin affect the position of elements when using anchor links or scrollβsnap. Visual.
See how alignβitems: baseline works in grid to align different font sizes on the same baseline. Visual guide.
Test the experimental Translation API to translate text between languages directly in the browser, without cloud calls. Check support and copy the JavaScript starter.
Apply a convolution filter (blur, sharpen) using a Web Worker. See the UI stay responsive while processing. Learn multithreading in the browser.
Toggle scrollbarβgutter: stable to reserve space for the scrollbar and avoid content jumps. Visual demo with two columns.
Acquire and release locks across tabs. Prevent race conditions in IndexedDB or localStorage. Visual queue and lock state.
Register a periodic background sync to fetch fresh data even when the tab is closed. Understand the API and limits.
Test the Fullscreen API: request fullscreen on a colored div, detect changes, and copy the JavaScript boilerplate.
See the View Transitions API in action. Crossβfade and morph between two states. Copy the JavaScript starter code.
Measure your internet connection speed by downloading and uploading a small test file. Works from your browser.
Apply a simple aging effect to a portrait: add wrinkles and grey hair. Just for laughs. Canvas manipulation.
Find safe mixing ratios for the classic elephant toothpaste demonstration. Volume adjustments for different container sizes.