Skip to content
KONIGI Patterns

Dashboards / Managing screen space / Mobile adaptation

‹ 3 of 6 ›

Mobile adaptation

People need to check important dashboard information on a phone.

Updated September 10, 2026

Problem

A desktop dashboard can become a long, hard-to-use page on a phone, hiding the information people need first.

Solution

Design the phone view around the task people need to complete there. For alert follow-up, prioritize the current problem, its severity, and a route to details.

Set the panel order deliberately rather than relying on the desktop grid’s source order. Keep essential values visible and replace hover-only details with tap or on-page access.

Use touch-friendly controls. Adapt wide tables and legends to preserve important content. Provide a clear path to a fuller view when the task needs more space.

Use when

People use the dashboard on a phone and there is a useful task the smaller view can support.

Don’t use when

The page’s whole value is density and comparison. Better to show a deliberate summary with a “open on desktop” path than a technically-responsive page nobody can use.

Trade-offs

A separate layout needs maintenance and careful decisions about what to omit. A concise summary can encourage decisions that require more detail. Testing needs to include real devices and viewing conditions.

Checklist

  • What are the two or three questions someone on a phone actually has?
  • Does panel order in the collapsed layout reflect priority, or source order?
  • Is anything essential only reachable by hover?
  • Do interactive targets meet the minimum size for fingers?
  • What happens to wide tables and long legends?
  • Is chart text legible at phone size, or scaled-down desktop type?
  • How does this behave over a bad mobile connection?
  • Is there a clear route to the full version when the summary is not enough?
  • Has anyone opened this on a phone, at night, at low brightness?
  • Should this dashboard have a mobile version at all?

Compare

Grafana reflows its grid to a single column below a breakpoint, which keeps every dashboard technically usable on a phone and rarely produces a priority order anyone chose. Datadog and most modern observability products ship dedicated mobile apps rather than responsive dashboards, which is an admission that triage on a phone is a different product rather than a narrower page. Sentry ports well by accident, because its primary surface is a list of issues and lists are what phones are good at. Public status pages are again the best-adapted example, since they are frequently read on a phone by someone who just found out something is broken, and they carry roughly three pieces of information for exactly that reason.

Panel grid supplies the desktop arrangement. Hover detail needs a touch-accessible alternative. Sidebar and canvas needs navigation that fits the smaller screen.

Detail on demand reveals secondary information. Header KPI strip can provide a compact starting summary.

Mobile adaptation anatomy A twelve-panel desktop grid, the same grid reflowed to one column where the panel that mattered lands eighth, and a phone page designed for triage instead, which answers three questions and stops. One dashboard, three phones' worth of it Twelve columns Reflowed Is it real yes How bad 4.1% of checkouts Can it wait no Designed for triage 1 2 3 1 NOTHING DECLARED PRIORITY The desktop layout expressed importance through size and position, and neither survives a reflow to one column. 2 SO IT LANDS EIGHTH The order comes from the source, which is usually the order panels were added. 3 TRIAGE, NOT ANALYSIS Is this real, how bad, can it wait. Hover is gone, so anything that lived in a tooltip has to be on the page. Some dashboards should have no phone version. A forty-panel surface has no fifteen-second story.
Wireframe — the pattern's anatomy, not any one product's version of it

Implementation

An on-call engineer at 3 a.m. holding a phone. Reflow to one column is the easy half; the hard half is deciding which two panels come first, and a phone layout that is the desktop order squeezed is a decision nobody made.

Tokens
--card--card-foreground--foreground--muted-foreground--border--status-critical

Checkout failures

Is it real
yes
How bad
4.1% of checkouts
Can it wait
no
Open the full dashboard

TriagePage.tsxThree answers the caller must supply, a share computed from the counts, and one thumb-sized route to the full page. Nothing in a tooltip.

import { cn } from "@/lib/utils";

/**
 * The phone version, designed for triage rather than reflowed from the grid.
 *
 * Three questions and a way out. Is it real, how bad, can it wait, then a
 * route to the full dashboard for the case where the answer is "open the
 * laptop". Every answer is a prop the caller has to supply, so a page that
 * cannot answer one of them is a page that should not have a phone version.
 * Nothing lives in a tooltip, because there is no hover, and the one target
 * is tall enough for a thumb.
 */
type Props = {
  title: string;
  /** Has the alert been corroborated by a second signal? A single rule
   *  firing is a claim; two is a fact. */
  real: boolean;
  /** How bad, as a share of a named thing. Rendered as "4.1% of checkouts",
   *  computed here so the page and the source cannot disagree. */
  affected: number;
  total: number;
  of: string;
  /** Whether it can wait until morning. The rule that decides lives with
   *  the alert, not here. */
  canWait: boolean;
  /** The full desktop page. Required: a summary with no way past it is a
   *  dead end at 3 a.m. */
  fullHref: string;
  onOpenFull?: () => void;
};

const yesNo = (b: boolean) => (b ? "yes" : "no");

export function TriagePage({ title, real, affected, total, of, canWait, fullHref, onOpenFull }: Props) {
  const share = `${((affected / total) * 100).toFixed(1)}% of ${of}`;

  return (
    <div className="flex flex-col gap-2 rounded-lg border bg-card p-3">
      <p className="truncate text-[11px] text-muted-foreground">{title}</p>

      <dl className="flex flex-col gap-2">
        <div className={cn("rounded-[2px] border p-2", real && "border-foreground")}>
          <dt className="text-[10px] text-muted-foreground">Is it real</dt>
          <dd className="text-base font-medium text-card-foreground">{yesNo(real)}</dd>
        </div>
        <div className="rounded-[2px] border p-2">
          <dt className="text-[10px] text-muted-foreground">How bad</dt>
          <dd className="text-[11px] tabular-nums text-card-foreground">{share}</dd>
        </div>
        <div className="rounded-[2px] border p-2">
          <dt className="text-[10px] text-muted-foreground">Can it wait</dt>
          <dd className={cn("text-base font-medium", canWait ? "text-card-foreground" : "text-status-critical")}>{yesNo(canWait)}</dd>
        </div>
      </dl>

      {/* 44px tall: the WCAG minimum for a finger, and the one control on the page. */}
      <a
        href={fullHref}
        onClick={onOpenFull}
        className="flex min-h-11 items-center justify-center rounded-md border text-xs text-card-foreground"
      >
        Open the full dashboard
      </a>
    </div>
  );
}

demo.tsxHow it is called: a checkout alert, 287 of 7,000 failed, corroborated, cannot wait.

import { TriagePage } from "./TriagePage";

/**
 * The page an alert links to. 287 of the last 7,000 checkouts failed, which
 * the page states as 4.1%, a second signal agrees, and it cannot wait.
 */
export default function Demo() {
  return (
    <div className="w-[180px]">
      <TriagePage
        title="Checkout failures"
        real={true}
        affected={287}
        total={7000}
        of="checkouts"
        canWait={false}
        fullHref="/dashboards/checkout"
      />
    </div>
  );
}
What it renders. Identical markup in both panes, with only the token values changing.

Examples

Screenshots are grouped by product and include the capture date. Dashed boxes highlight this pattern. Notes appear below each screenshot and when you hover over a box.

Home Assistant

Room-based card layouts combine household device states with controls.

Demo dashboard at phone width September 10, 2026 Home Assistant public demo (signed out, 390px viewport) medium · light · mobile
The desktop dashboard reflows into a narrow phone layout while keeping its room sections and controls. Cards remain in two columns within sections, limiting the page’s length. The section order differs from the desktop columns, so the responsive layout changes what people encounter first. Navigation moves behind a menu button, while the summary chips remain at the top.