Repository navigation
Issue 122 Description Box Was A Stub In The Corner
Reported: #122 by tjedelhauser, August 2026 Β· Module: SelfβService Portal Β· Fixed in: #1389, #1390
Raising a ticket from the portal on an ordinary desktop screen, the box you type your problem into was about 300px wide and 62px tall, tucked into the topβright corner β while Mailbox, Priority and Attachments, the things you barely interact with, had the entire width of the page beneath it.
The reporter's screenshot was taken at 1888px, and it shows the shape precisely: a large empty area on the left where the message should be, and the editor squeezed into the corner.
The compose screen is a twoβcolumn layout β the message on the left, the settings panel on the right:
.compose-body {
display: grid;
grid-template-columns: 1fr 300px;
}That container has three children, not two:
<div class="compose-body">
<div class="compose-label-row"> Description β¦ </div>
<div class="compose-editor"> the TinyMCE box </div>
<aside class="compose-side"> mailbox, priority, attachments </aside>
</div>CSS Grid does not leave a gap when it runs out of the cells you described. It autoβplaces each child into the next free cell, creating implicit rows as it goes:
| cell | got | width |
|---|---|---|
row 1, col 1 (1fr) |
.compose-label-row |
1476px |
row 1, col 2 (300px) |
.compose-editor |
300 Γ 62 |
row 2, col 1 (1fr) |
.compose-side |
1476px |
So the label took the column meant for the message, the message was pushed into the column meant for the panel, and the panel dropped to a row of its own. Every element did exactly what it was told; nothing errored.
π Adding a child to a grid is a layout change, even when it is "just a label". Autoβplacement fills the next cell with whatever comes next β it has no notion of which child was supposed to be where.
.compose-label-row was added in #1284, part of the portal's mobile round, and for a good reason: the message body was the only field on the form with nothing naming it.
It is correct on a phone. Below 900px the layout collapses to a single column:
@media (max-width: 900px) { .compose-body { grid-template-columns: 1fr; } }β¦and in a oneβcolumn grid, autoβplacement stacks all three children in DOM order β label, editor, panel β which is exactly right. The twoβcolumn desktop arrangement is the only one where a third child has anywhere wrong to go, and no phoneβwidth test could have revealed it.
π A change that is correct in the layout you are testing can be wrong in the layout you are not. A media query does not only change sizes; it changes how many cells there are, and therefore what a new child does.
Stated placement instead of autoβplacement, so the arrangement no longer depends on how many children happen to be present:
.compose-body {
grid-template-columns: 1fr 300px;
grid-template-rows: auto 1fr; /* label sized to content, editor takes the rest */
}
.compose-label-row { grid-column: 1; grid-row: 1; }
.compose-editor { grid-column: 1; grid-row: 2; }
.compose-side { grid-column: 2; grid-row: 1 / -1; }A fourth child added later cannot repeat this: unplaced children now flow past the stated cells rather than displacing them.
grid-row: 1 / -1 on the panel would otherwise sit it beside the label in a oneβcolumn grid, and grid-template-rows: auto 1fr would hand the editor's row all the leftover height:
@media (max-width: 900px) {
.compose-body { grid-template-columns: 1fr; grid-template-rows: none; }
.compose-label-row, .compose-editor, .compose-side { grid-column: auto; grid-row: auto; }
}Between 769px and 900px β where a tablet held upright lands β the editor measured 806 Γ 49: a toolbar with a sliver underneath.
In a single column the flex chain has no leftover height to distribute, so flex: 1 on the editor resolves to almost nothing. That had been found and fixed during the phone round, with the symptom recorded in the stylesheet in as many words ("measured on a phone it was 266x50") β but the remedy was written into the max-width: 768px block, while the singleβcolumn layout it was remedying starts at 900px.
So the fix was right and its media query was one breakpoint too narrow, leaving 131px of widths uncovered. It predates #122 rather than being caused by it.
π A rule that fixes a layout belongs at the breakpoint that introduces that layout, not at the width you happened to be testing at.
| File | What |
|---|---|
π© self-service/new-ticket.php
|
Stated grid placement for the three panes; the mobile block resets it; the editor's minimum height moved from the 768px block to the 900px one |
One file, CSS only. No markup, no JavaScript, no other page.
Measured at eleven widths from 1888px down to 360px, driving the real page behind a portal session.
| before | after | |
|---|---|---|
| 1888px | editor 300 Γ 62 at x=1541 | editor 1476 Γ 609 at x=47 |
| 900px | editor 806 Γ 49 | editor 806 Γ 240 |
| 360px | editor 310 Γ 240 | editor 310 Γ 240 β unchanged |
The 360px row is the control that matters: the phone layout is byteβidentical before and after, which is the whole point of the fix being placement rather than a rewrite.
The wiki's usual finding is "it was N places, not one". Here it genuinely was one, and that is worth showing rather than asserting. A detector was written for the shape β a multiβtrack grid with more visible children than tracks, no declared rows to hold them, and no explicit placement β and run across the portal and ten analyst screens.
Its first form was too blunt: it flagged the waffle menu's 3Γ3 dot grid, a 22βmodule launcher and a 26βfield detail grid, all of which are meant to wrap onto many rows. Narrowing it to grids that have not declared enough rows for their children and have not placed them explicitly left:
-
self-service/new-ticket.phpβ clean after the fix (the stated placement reads as deliberate, which is what it is); -
.waffle-modulesβrepeat(4, 1fr)with 22 children, an intentionally wrapping launcher; - one twoβcolumn settings form with 7 fields, likewise intentional.
No other instance of the fault.
If you raise tickets from the portal on a desktop or a laptop, the description box now fills the leftβhand side of the screen at full height, and the settings sit in a panel on the right. On a phone nothing changes. If you are on a tablet in portrait, the message box is no longer a sliver.
- MobileβFriendly β the rollout this came out of, and its one hard rule, which this is a reminder applies in both directions
- Bugs resolved
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
-
Architecture
- β³ π§Ή Root folder tidy (URL routing)
- β³ π Database Integrity (FKs & constraints)
- β³ π οΈ Database Verification β Developer Guide
- β³ π§© Service Layer (UI + API share code)
- β³ πͺ€ Code traps (the TRAP: comments)
- β³ π Commenting for the Engineering wiki
- β³ π οΈ Engineering wiki scanner - Developer Guide
- β³ π Service-Layer progress
- π§ͺ Developer tests
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- π± Currencies
- π Display order (modules, Watchtower cards) β Developer Guide
- Theming & Dark Mode
- ποΈ Recent β getting back to what you were doing
- β¨οΈ 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: Forms
- β³ π Mobile: Contracts
- β³ π Mobile: Domains
- β³ π Mobile: People
- β³ π Mobile: Projects
- β³ ποΈ Mobile: Files
- β³ π Mobile: LMS
- β³ πΊοΈ Mobile: CMDB
- β³ πΊοΈ Mobile: Network Mapper
- β³ π§ Mobile: Process Mapper
- β³ βοΈ Mobile: Workflow
- β³ π₯οΈ Mobile: System
- β³ π Mobile: Reporting
- β³ π Mobile: System Wiki
- β³ π Mobile: Self-Service Portal
- β³ π§° 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
- β³ π‘οΈ CSRF protection (S4) β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- π CardDAV contact sync
- 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: Domains
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ π·οΈ REST API: Cost centres
- β³ π§βπΌ REST API: Analysts
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ π Rota copy and paste β Developer Deep Dive
- β³ β Checklists & SOPs
- β³ βοΈ Mandatory fields
- β³ π§Ύ Custom ticket fields
- β³ π·οΈ Ticket categories
- β³ π₯ Assigning tickets to a team, and escalation
- β³ π’ One board across every company
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ π Attachment size limits and large emails
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
-
β³
βοΈ Telegram channel - β³ β CSAT company scope and filters β Developer Guide
- β³ π₯ Microsoft Teams channel
- β³ π¨οΈ Mattermost channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ β Record previews
- β³ π Ticket notes: internal or shared
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ π¨ Telling the analyst a ticket is theirs
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ π Confidential tickets
- β³ π₯ Portal managers
- β³ π Who has seen a ticket
- β³ π Reading long tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ ποΈ The folder pane
- β³ π½ Just my tickets, or no closed ones
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- β³ π Scheduled work in your own calendar
- Problem Management
- Tasks
- π Projects
-
Assets
- β³ π’ Moving an asset between companies
- β³ π Shared asset locations
- β³ π§βπΌ Assigning assets to analysts
- β³ π Warranty and lease alerts
- β³ π Leases
- β³ π Saved table views
- β³ π¨οΈ Recording anything, and importing it
- β³ π·οΈ QR asset labels
- β³ π Who holds what, and handover documents
- β³ π₯οΈ The inventory agent (PowerShell)
- β³ ποΈ Proxmox VE servers
- β³ βοΈ VMware Cloud Director servers
- β³ π Linking equipment to tickets
- β³ βοΈ Follow-up tasks on a ticket
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
-
Forms
- β³ π¨ The form designer β Developer Guide
- β³ π Layout & the grid β Developer Guide
- β³ ποΈ Collections β grouping submissions
- β³ π Submissions as PDFs
- β³ β‘ What happens next β a form's own actions
- β³ π οΈ Sections & conditional logic β Developer Guide
- β³ π οΈ Lookup fields β Developer Guide
- β³ π‘οΈ Catalogue request approvals
- People
- Domains
- ποΈ Files
- 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
- β³ π’ One board across every company
- β³ 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)
- What this is
-
π Bugs resolved
- β³ π¬ #183 Mailbox checks overlapped
- β³ π #188 Transfer lock shown off when unknown
- β³ β #184 Subtask names and Overdue
- β³ π§© #186 Teams: the buttons did nothing
- β³ π Text in a change could run script
- β³ π AI settings changed without the AI permission
- β³ πͺ #178 Deleting an analyst failed
- β³ π« A team with no departments showed 0 tickets
- β³ π Projects: adding a phase did nothing on Save
- β³ π Leavers could still sign in
- β³ πΌοΈ Logo and courses broke on Apache with PHP-FPM
- β³ π’ Chat tickets ignored your ticket numbering
- β³ π Dates shown as a dash, or in server time
- β³ π Assets β Users showed people from other companies
- β³ π Restricted analysts could read other modules' data
- β³ πΌοΈ Replies with a picture in the thread failed to send
- β³ π Reply attachments never reached the customer
- β³ π οΈ Outbound email attachments β Developer Guide
- β³ π A global SSO provider was missing from the portal
- β³ π Behind a proxy, the SSO redirect said http
- β³ βοΈ The portal tagline moved when you saved it
- β³ π¨ The portal settings screen forgot what you saved
- β³ π‘οΈ The approvals inbox said "Error" and nothing else
- β³ π A table's answers were missing from the PDF
- β³ β A single-select column let you tick every option
- β³ π The portal ignored a form's field widths
- β³ π The tasks board stopped taking clicks
- β³ ποΈ #121 The index list is out of date after upgrading
- β³ π #133 The calendar subscription was empty
- β³ π #131 Tasks always reopened on the board
- β³ π₯ #129 Every page returned HTTP 500 after upgrading
- β³ π³ #127 A PHP warning above the System page
- β³ π #126 Notes stamped with the server's clock
- β³ π Storing every date in UTC
- β³ πͺ The portal was down for everyone signed in
- β³ βοΈ #120 Workflow notes could never be written
- β³ βοΈ #123 Three errors when running Database Verification
- β³ π #122 The description box was a stub in the corner
- β³ π£ Demo data deleted real accounts
- β³ π #117 Sign-in redirected to the wrong address
- β³ π¨ #108 The priority dot was invisible
- β³ β±οΈ #116 Time logged from the right-click menu
- β³ π #114 API keys refused by our own guard
- β³ ποΈ #110 Assigning a task told nobody
- β³ πͺ #107 Signed out while still working
- β³ π #103 "Share with Requester" reached nobody
- β³ π #102 Search found nothing for hyphens
- β³ πͺ #101 Source code editor opened behind
- β³ βοΈ #88 Subtasks could not be ticked off
- β³ π» #84 Asset deep link selected nothing
- β³ π« #79 A new ticket arrived with no status
- β³ π§ #79 A ticket from email did not say so
- β³ π #78 Bell opened to nothing
- β³ π¬ #77 Mail only collected from Inbox
- β³ π #74 The default password could not be changed
- β³ π¦ #70 Renaming an impact level
- β³ π€ #67 App-only mailboxes could not send
- β³ π #45 Verify only ever worked for Microsoft
- β³ π #45 IMAP reported as not authenticated
- β³ βοΈ An email template stopped escaping itself
- β³ π The portal dashboard showed the wrong time
- β³ π’ The folder said 99 and the list showed 96