-
Notifications
You must be signed in to change notification settings - Fork 16
Mobile Friendly Tasks
Tasks is the tenth module made mobileβfriendly, after Tickets, Assets, Calendar, Knowledge, Service Status, Watchtower, Problem Management, Change Management and Software. Same hard rule: one @media (max-width: 768px) block, desktop byteβidentical.
π§° Codeβlevel catalogue of the techniques: Mobile: Techniques & Tricks.
Shipped as #1205, commit a8ea82fa, plus #1206, commit 28471532. LAYER 25.
viewport = 360 docScrollW = 1144 β on ALL SIX pages, identically
The tenth module, and the tenth time the same number appeared on every page at once β nav.header-nav at 730px in the shared header, the iOS reflowβtoβdesktop trap. The module had never opted in. Three tags per page took all six to docScrollW === 360.
| Page | State |
|---|---|
tasks/ β the Kanban board |
Done β one column per screen with snap, plus a dots indicator (25a, 25b) |
tasks/ β the list view |
Done β table β card feed (25c) |
tasks/table/ |
Done by opting in β the shared .dt-wrap scroller from the Assets round |
tasks/calendar/ |
Done by opting in, plus the view switcher (25e) |
tasks/timeline/ β the Gantt |
Done by opting in β a Gantt keeps its columns and scrolls, as it should |
tasks/settings/ |
Done by opting in + data-mobile-page="settings"
|
tasks/help.php |
Done by opting in β inherits the contents strip |
The detail panel needed no width work at all: tasks.css already carries its own @media (max-width: 900px) { .detail-panel { width: 100% } }. That turned out to be the trap rather than the gift β see below.
At 240px a column showed 1.5 of them on a phone: one column and a distracting sliver of the next. Too narrow to read, too wide to be a clean screen.
.board-view { scroll-snap-type: x mandatory; scroll-padding-left: 12px; }
.board-view .board-column { flex: 0 0 100%; min-width: 0; scroll-snap-align: start; }A sideways drag now turns the page β To Do β In Progress β Blocked.
π
min-width: 0is loadβbearing.tasks.csssets a 240β280px floor and a flex item cannot shrink below itsmin-widthhowever small the basis. Invisible to adocScrollW === innerWidthcheck, because the board scrolls, not the page.
Dragβandβdrop between columns stays a desktop interaction. This makes the board readable on a phone, not draggable.
Fullβwidth columns cost the one thing the 1.5βcolumn view gave for free: the visible edge of the next column. A dot per column, injected by mobile.js, restores it.
Appended inside mobile.js's main IIFE, which returns early on line 159:
if (!mc || !document.querySelector('.email-list-container')) return; // tickets inbox wiringThey were absent, not broken β so a parse check passed and the CSS was fine. Only asking the live page "is renderBoard wrapped?" found it. Moved to its own topβlevel IIFE with its own mq.
π A wrapβdon'tβedit block belongs in its own IIFE. Sharing one with another module's wiring means inheriting that module's early return.
The list table was 593px of Title / Assignee / Due / Priority / Status in 360px, and the Title column holds prose β so a card feed, not a scroller. This deliberately differs from the table view one page over, which keeps its columns: the two views exist precisely because one is for reading and the other for comparing.
.view-toggle / .view-btn are four modules' class names (Β§15); the existing rule was scoped to .calendar-main, which the Tasks calendar does not have. Scoped here to .tasks-main.
This is the part worth reading. The panel is the module's most-used screen on a phone and it took three attempts and two corrections from Ed.
Ed reported "just a hint of left to right scroll but then it kind of rubber bands back". I measured "does anything cross the panel's right edge" β none β and concluded the drag came from scrollports behind the fixed panel, so I contained their overscroll:
.detail-panel { overscroll-behavior: contain; overflow-x: hidden; }Which is true and worth having, and was not the cause.
"on task details the due date form field is spilling off to the right"
.detail-row is a flex pair β Status+Priority, Assignee+Team, Start+Due β with .detail-field { flex: 1 }. Two date fields could not fit. Measured properly:
row 2 content needs 330px but has 312 β SHRINK FLOOR of 18px
elements crossing the panel's right edge: NONE
The panel clips it, so the outer check reports nothing. Β§14 says this in as many words β "whenever a child measures wider than its parent and the page is still contained, look for a shrink floor before looking for the overflow" β and I had run the outer comparison instead. The knowledge was on this wiki and I did not consult it.
Worse: I had already bumped every field to 16px for the antiβzoom fix while the dates were still side by side, and 16px makes a date field wider. For the few minutes that state was on disk it was a genuine regression, and Ed caught it β "we're still not there and it's arguably worse".
Fix: stack every pair.
.detail-panel .detail-row { flex-direction: column; gap: 12px; }
.detail-panel .detail-row .detail-field { flex: 1 1 auto; min-width: 0; width: 100%; }"the start date and due date form fields are wider than the dropdowns (status, priority etc) why is this?"
Nothing in the CSS makes them differ β tasks.css gives .detail-select and .detail-input one shared rule. The difference is the control: a native date input ignores the width you give it, and iOS spells the month out (12 May 2026) where Chrome on Windows draws 12/05/2026.
That is why my desktop harness kept clearing a panel that was broken on his phone β it was measuring a different control. Written up as Β§20, the fifth place in mobile.css to need the same reset.
π A field being wider than its neighbours is the same fault as a field spilling off the right β and it is the tell that shows at rest, without a gesture. Ed spotted it by looking; I had three harnesses that could not.
Ed: "when adding a task on mobile can you use that trick to stop it zooming in". Adding a task in Tasks is not a dialog β it is an inline .quick-add-input that unfolds under a column heading β so LAYER 3's rule, which knows .modal-content and .modal .form-group, could never reach it. Same shape as the .search-modal fix in #1193.
The reported field was one of nine. tasks.css sets 13px on every field in the module, so the search box, three sidebar filters, the subtask box, the comment box, the tag picker, both link searches and the panel's selects and dates all zoomed identically. Only .detail-title-input (18px) was safe.
Two scopes were needed, not one: .detail-panel is a sibling of .tasks-container, not a child, so a single container scope silently misses most of the fields. .search-input is four modules' class and is scoped accordingly.
| Check | Result |
|---|---|
docScrollW === innerWidth at 360px |
β all six pages β 1144 β 360 |
| Board column width | 336px = viewport β padding; snap x mandatory; lands flush left |
| Dots | follow the scroll; display: none on desktop |
| List view | cell heights unequal β the cardβfeed signature, not a crushed row |
| Detail panel @ 320px and 390px | panel and page contained; zero shrink floors on any row |
| β¦with date fields forced to 210px each | still contained β the check that does not trust the desktop rendering |
| Every panel field | 342w Γ 44h, identical; dates appearance: none
|
| Desktop @ 1280px | snap none; columns 280px, 4.6 visible; dots hidden; thead table-header-group; fields 210w at 13px, appearance: auto
|
-
The sidebar is
display: noneunder 600px (tasks.css, preβexisting). So on a phone there is no way to search or filter tasks β the board's status columns are the only filter. That is a real gap, not a mobileβlayout one, and it is why 25f still styles the sidebar fields: they are reachable in the 601β768px band. - Dragging cards between columns remains desktopβonly.
- The task title truncates with an ellipsis in the panel rather than wrapping; the full title is on the card and on focus.
- MobileβFriendly β the overview and the rollout state
- Mobile: Techniques & Tricks β the codeβlevel catalogue, incl. Β§20 native date inputs
- Mobile: Assets β the round that built the table scroller this module inherited
- Tasks β the module itself
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- Theming & Dark Mode
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
-
MobileβFriendly
- β³ π« Mobile: Tickets
- β³ π» Mobile: Assets
- β³ π Mobile: Calendar
- β³ π Mobile: Knowledge
- β³ π¦ Mobile: Service Status
- β³ πΌ Mobile: Watchtower
- β³ π§© Mobile: Problem Management
- β³ π Mobile: Change Management
- β³ πΏ Mobile: Software
- β³ β Mobile: Tasks
- β³ π§° Mobile: Techniques & Tricks
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ π Ticket notes: internal or shared
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ ποΈ The folder pane
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- β³ π Scheduled work in your own calendar
- Problem Management
- Tasks
- Assets
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
- Forms
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)