A local load should not cover the whole page
Aliases: local spinner · full-page overlay · loading mask
What it is
A load usually refreshes one region: a table’s rows, a side panel’s detail, an image in a card. A local load should not cover the whole page means the indicator’s mask and its untouchable range must match the range of that update, not drop a window-wide overlay on every request. A full-page spinner locks still-live regions—navigation, a filled form, a cancel control—inside the wait. Wrong range turns a loading indicator from “this part is busy” into “the product has stopped.”
Why it happens
People judge the cost of waiting by what can still move. If a list is refreshing but the bar and filters still change, they can change the query or leave. A full-page lock makes waiting the only legal act. A mask also erases context: the row just selected is invisible, and coming back requires reorientation. A local indicator pins “busy” on the object, and that spatial ownership also says what will change when the wait ends. A page-wide indicator promotes ownership to the app; people infer that navigation, drafts, and other tabs have also stopped, so they freeze, or they go to another tab and submit again. Range is the subject of the loading sentence. The wrong subject aims an honest predicate at the wrong world.
Where it stops holding
First entry into a route that has no shell yet makes a page-wide indicator or skeleton reasonable: there is no “local” to keep. A submit inside a modal whose result decides whether the dialog still exists may lock the dialog without locking the app underneath. Several locals spinning at once look like a Christmas tree; indicate once on a shared parent rather than promoting that to a full page. Some safe transactions (waiting on a payment gateway after confirm) must block every other act; that is a transaction lock, not the default loading look. If a screen reader hears only “loading” and not which region, the load is local in pixels and still global in speech.
Applying it
- Label each request with its update range: control, card, list, page, app. The indicator and disabling apply only there.
- Keep navigation and cancel outside that range; a loading list should still show its title and current filters.
- Do not default to a page-wide translucent mask; default to a spinner on the object or a skeleton in that region.
- Verify by loading one region and trying to navigate, change a filter, or copy already-visible text. If all of that dies, the range has already swollen to the page.