Skip to content

Mobile Friendly Files

Ed Mozley edited this page Oct 10, 2026 · 1 revision

Mobile-Friendly: Files

Scope: the desktop page (files/index.php) and the viewer it opens. The guide and Files -> Settings are already answered by the shared help and settings layers. Layers: mobile.css LAYERS 45a-45d. No mobile.js layer - the phone list is drawn by files-desktop.js itself. Parent: Mobile-Friendly Β· Techniques: Β§3, Β§8, Β§13, Β§28, Β§30


Where it started

Files is a fake Windows desktop: fixed-position windows that drag and resize, a taskbar with hover previews, a start menu, right-click menus, rubber-band selection and drag and drop. None of that is a phone control. A desktop metaphor at 390px is a worse file manager than a list, so on a phone there is no desktop at all.

The page links mobile.css after files.css (Β§9), mobile.js last, and data-mobile-module="files" / data-mobile-page="files-desktop" on the <body>.

Desktop Phone
Desktop icons, windows, taskbar, start menu, previews Hidden (45a)
Documents (an Explorer window) .fd-mobile - a list of the same folders, files and shortcuts (45b)
The viewer in a window The same viewer, full screen (45d)
The person's navbar setting (on / auto-hide / off) Ignored - the header always shows
Fields at 13px 16px module-wide (45c)

The scrolling shell (45a)

On the desktop files.css gives body.fd-body height: 100vh; overflow: hidden - the desktop is the page, and windows scroll inside themselves. On a phone that is the wrong shape twice: 100vh runs under Safari's address bar, and there is nothing inside to scroll.

45a puts LAYER 2's shell back: the body is a 100dvh column, the header's wrapper (.fd-navwrap) is static and displayed, and .fd-mobile is the one scroller - flex: 1 1 auto; min-height: 0; overflow-y: auto. The min-height: 0 is the part that matters (Β§28).

The desktop, taskbar, start menu, preview and the auto-hide sensor are all display: none !important.

The header always shows

The Files desktop lets each person hide the top bar or have it appear when the mouse reaches the top. Both are mouse settings: on a phone there is no mouse to reach the top with, and the header is how you leave the module. So 45a overrides whatever the person chose:

body[data-mobile-page="files-desktop"] .fd-navwrap {
    position: static !important; transform: none !important; display: block !important;
    flex-shrink: 0; box-shadow: none;
}

!important is needed because the navbar modes in files.css are written against body[data-navbar], which is just as specific.

The list (45b)

files-desktop.js checks matchMedia('(max-width: 768px)') at start. On a phone it loads list.php?folder=0 into #fdMobile instead of opening an Explorer window - the same endpoint the desktop uses, so the same permissions, the same "Documents" top, and the same audit rows.

  • The bar (.fdm-bar) is sticky, the first child of the scroller, one line: Back (an arrow, when inside a folder), the folder's name (or "Documents"), then Upload (inside a folder you can upload to) and New folder (where you can create one - inside a folder with Upload, or at the top with the Folders permission). Each button is 44px square.
  • The rows (.fdm-row) are full-width 56px buttons: folders first, then files, then shortcuts. A folder seen out of context (shared with you without its parents) shows its path underneath; a file shows its size and date; a shortcut shows "Shortcut to" and the target's path.
  • Tapping a folder opens it, a file opens the viewer, and a shortcut opens its target - a folder in the list, a file in the viewer.
  • An empty folder says so, and an empty "Documents" says "Nothing has been shared with you yet."

Upload uses the same Uploads.pick() as the desktop, so the same 4 MB pieces, conflict question and size limit. A finished upload refreshes the list.

The viewer, full screen (45d)

On a phone viewFile() passes phone: true, and files-viewer.js builds .fdm-viewer on <body> instead of a window: its own bar with Back and the file's name, and the same renderInto() underneath. So PDFs, Word documents, spreadsheets, images, media, text and zips all work the same way, and View only and the watermark are exactly the desktop's - the token, the missing Download button, the tiled stamp.

It sits at z-index: 300000:

body[data-mobile-page="files-desktop"] .fdm-viewer {
    /* Above the header too (LAYER 1 lifts it): the viewer is full screen and
       carries its own Back, so nothing may sit on top of that bar. */
    position: fixed; inset: 0; z-index: 300000; display: flex; flex-direction: column; background: var(--surface);
}

LAYER 1 lifts the header above page content, and files.css already puts .fd-navwrap at 200000 for the desktop's auto-hide mode. Anything lower and the header sits on top of the viewer's own Back button - the one way out. The bar also pads for env(safe-area-inset-top).

Inside the overlay the viewer's toolbar may wrap, its buttons are at least 40px, and the Word page and PDF stage lose most of their desktop padding.

Fields (45c)

Every field in the module at 16px so iOS does not zoom in on focus (Β§3) - on this page that is the New folder name dialog. The dialog itself is the screen width less 24px, and its buttons are 44px tall.


What is not on the phone

Deliberately desktop-only, because each is a window or a gesture the list does not have: Recent, Search, desktop shortcuts, Permissions, Properties, Rename, Delete, Cut/Copy/Paste and drag and drop. The help page's On a phone section says what the phone can do.

Verification

Checked at 390px through an explicit-width iframe (Β§8, Β§30): the list in place of the desktop, into a folder and back, and a file opening full screen in the viewer. The things worth re-checking after any change here: the list's last row can be scrolled to under the sticky bar (Β§13), the header shows whatever the person's navbar setting is, and the viewer's Back sits above the header and works.

Still owed

  • A real device pass. Everything here is headless; iOS gesture handling, the real address bar and the safe-area insets are not.
  • A stale comment. LAYER 45's header in mobile.css still says tapping a file downloads it, and lists only 45a-45c. Tapping a file opens the viewer (45d).

See also: Files Β· Files - Developer Guide Β· Mobile-Friendly Β· Techniques

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally