Skip to content

ADR-011: Responsive Design Strategy (25%-200% Zoom Support)

Note: This ADR was originally numbered ADR-002 but was renumbered to ADR-011 during the 2026-01-28 namespace consolidation to resolve collision with ADR-002-cross-validation-strategy.md

Status: Accepted
Date: 2026-01-28
Deciders: @cloud-architect, @product-owner

Context

Manager Requirement R4 mandates "No scroll for KPI cards - single page scroll only" with support for browser zoom levels 25%-200%. The ITSM dashboard currently uses vm.Flex layout (Sprint 25A migration), but needs validation for extreme zoom scenarios.

Key Challenges: 1. Horizontal scroll must never appear (viewport width constraint) 2. KPI cards must remain visible and clickable at all zoom levels 3. Vertical scroll natural for full page content 4. Reference implementations: call-center (proven vm.Flex pattern), bi-dashboard (vm.Grid with explicit ratios)

Decision

Use vm.Flex for page layout + vm.Grid for KPI container (4 equal columns).

Implementation

Already implemented in Sprint 25A - validate continued compliance:

# src/app.py (line 502-581)
vm.Container(
    title="",
    layout=vm.Grid(grid=[[0, 1, 2, 3]], row_gap="0px", col_gap="20px"),
    components=[
        vm.Figure(id="kpi_open_items", figure=kpi_card(...)),
        vm.Figure(id="kpi_created_1m", figure=kpi_card(...)),
        vm.Figure(id="kpi_updated_1m", figure=kpi_card(...)),
        vm.Figure(id="kpi_p1_p2", figure=kpi_card(...)),
    ],
)

# Page layout (line 625)
page_overview = vm.Page(
    layout=vm.Flex(gap="20px"),  # Vertical stacking, natural scroll
    components=[kpi_container, trends_tabs, analysis_tabs, table]
)

Rationale

Layout Strategy Horizontal Scroll Risk Responsiveness Complexity Decision
vm.Flex (page) + vm.Grid (KPIs) NONE Excellent (auto-fit) Low (native Vizro) ✅ SELECTED
vm.Grid with explicit ratios MEDIUM (ratios may not sum to 100%) Good Medium ❌ Rejected
Pure CSS Grid (custom) LOW Excellent HIGH (non-Vizro) ❌ Rejected

Why vm.Grid [[0,1,2,3]] works: - Vizro auto-calculates equal column widths (25% each) - col_gap="20px" creates visual separation without overflow - Grid collapses gracefully on mobile (future enhancement)

Consequences

Positive

  • Zero Configuration: No custom CSS media queries needed
  • Call-Center Proven: Same pattern handles 5 KPIs without scroll
  • Future-Proof: Responsive by default for mobile viewports
  • KISS Principle: Native Vizro layout, no framework overrides

Negative

  • Mobile Limitation: At <768px, KPIs may stack (acceptable - not in scope)
  • Mitigation: Add responsive breakpoint in future sprint if needed
  • Extreme Zoom Edge Case: At 25% zoom, KPIs become very small
  • Mitigation: Accessibility guidelines recommend 100%-200% range (WCAG 2.1 AA)

Risks

Risk Probability Impact Mitigation
KPI text wraps at 200% zoom MEDIUM LOW 150px height + 0.75rem padding provides buffer (ADR-001)
Horizontal scroll on narrow displays LOW MEDIUM vm.Grid auto-fit columns within viewport
Gap pushes cards off-screen LOW LOW 20px gap tested in call-center (5 KPIs wider layout)

Alternatives Considered

  1. Fixed pixel widths for KPIs

    vm.Container(layout=vm.Grid(grid=[[0, 1, 2, 3]], col_min_width="300px"))
    
    - Rejected: Causes horizontal scroll on 1366px displays at 100% zoom

  2. Percentage-based Grid

    vm.Grid(grid=[[0, 0, 1, 1, 2, 2, 3, 3]])  # 25% per KPI
    
    - Rejected: More verbose, same outcome as auto-fit [[0,1,2,3]]

  3. Flexbox with explicit widths

    vm.Container(layout=vm.Flex(direction="row", gap="20px"))
    # Each KPI: flex-basis: 25%
    
    - Rejected: Requires custom CSS, not native Vizro pattern

References

  • call-center: /dashboards/call-center/app.py (line 44-98) - 5 KPIs in vm.Grid
  • bi-dashboard: /dashboards/bi-dashboard/app.py (line 71-81) - 4 KPIs in vm.Grid
  • Sprint 25A: Migration to vm.Flex for responsive layout
  • WCAG 2.1 AA: Resize text up to 200% without horizontal scroll

Evidence

  • E2E test: tests/e2e/test_dashboard_requirements.py::TestKPILayout::test_kpi_responsive_zoom
  • Playwright screenshots: 5 zoom levels (25%, 50%, 100%, 150%, 200%)
  • Evidence path: tmp/cloud-infrastructure/test-results/responsive-zoom-screenshots/

Validation Checklist

  • No horizontal scrollbar at 1920x1080 100% zoom
  • All 4 KPIs visible at 1366x768 100% zoom (common laptop resolution)
  • KPI cards do not overlap at 200% zoom
  • Vertical scroll functions naturally for full page content
  • Browser DevTools responsive mode: 375px mobile width (stacking acceptable)

Version: 1.0
Next Review: Post-Sprint 26 E2E validation
Related ADRs: ADR-001 (KPI dimensions affect responsiveness)