Ranking
Allows users to order a list of items by preference or priority via drag interaction. Use in survey or consultation contexts where relative ordering is the required input. Don't use for lists longer than 7–10 items.
FigmaDescription
Presents a list of items that participants can reorder by dragging to reflect their ranked preference or priority. Each item displays its current position number alongside its label.
Community consultation surveys in Social Point (e.g. budget priority exercises, strategic planning input). Less commonly in Open Point admin interfaces for configuring display order of survey options or report categories.
Many government engagement exercises ask residents to rank priorities — infrastructure spending, service improvements, planning options — rather than simply select one. A drag-to-rank control captures nuanced preference data that radio buttons or checkboxes cannot.
Anatomy
| Part | Required? | Notes |
|---|---|---|
| List container | Required | Wraps all rankable items. Has a visible boundary and accessible ARIA list role. Manages drag state and announces reorder events to screen readers. |
| Rank item | Required | Individual row containing the drag handle, position badge, and item label. Minimum height 48px to meet touch target requirements. |
| Drag handle | Required | Icon affordance (typically a six-dot grip) on the leading edge of each row. Communicates draggability. Must have its own focusable target and keyboard instructions. |
| Position badge | Required | Numeric label showing the item's current rank (1, 2, 3…). Updates live as items are reordered. Communicates current state to all users including screen reader users. |
| Item label | Required | Plain text description of the option being ranked. Should be concise — ideally under 60 characters — to avoid wrapping inside the constrained row. |
| Field label | Recommended | Heading above the list explaining the ranking task (e.g. 'Rank these priorities from most to least important'). Should set clear expectations about how many items are shown. |
| Helper text | Optional | Secondary instruction below the field label, e.g. 'Drag items or use arrow keys to reorder'. Particularly important because many users are unfamiliar with drag-to-rank controls. |
| Validation message | Optional | Error or success feedback displayed below the list. Required when the field is mandatory in a form. |
Variants
Default
Standard drag-to-rank list with visible handles and position badges.
Use in most consultation and survey contexts where participants need to express preference order across a full set of options.
Top-N only
Participant ranks only the top N items from a longer list (e.g. pick and rank your top 3 from 8 options).
Use when requiring a full ranking of all items would create excessive cognitive load. Makes the task more manageable while still capturing priority signal.
Read-only
Displays a completed or locked ranking without interactive controls. Handles are hidden; position badges remain visible.
Use to show a participant their previously submitted ranking in a review step, or to display aggregate results in a results summary.
States
| State | Behaviour |
|---|---|
| Default | All items are shown in their initial order (typically randomised to avoid order bias). Drag handles are visible. No item is active. |
| Hover | The hovered rank item and its drag handle receive a subtle background highlight using --op-color-bg-secondary. The cursor changes to grab. |
| Dragging | The item being dragged appears elevated (box-shadow token) and semi-transparent (opacity 0.85). A drop target indicator — a 2px line in --op-color-interactive-default — shows where the item will land. |
| Keyboard focused | The focused item receives a 3px focus ring in --op-color-interactive-focus. Arrow key instructions are surfaced via helper text or a live region announcement on first focus. |
| Reordered | After a drop or keyboard move, the position badges update immediately. A live region announces the new position to screen readers (e.g. 'Parks moved to position 2 of 5'). |
| Disabled | All items are non-interactive. Drag handles are hidden or visually muted using --op-color-text-disabled. The list retains its current order but cannot be changed. |
| Error | A validation message appears below the list with --op-color-status-error styling. The list container border changes to --op-color-status-error. Used when the field is required and the participant has not completed the ranking. |
| Read-only | Items are displayed in their final order without drag handles. Position badges remain. No interactive affordances are shown. |
Usage guidelines
When to use
- Community consultation surveys asking residents to prioritise competing budget allocations, infrastructure projects, or service improvements.
- Strategic planning input where stakeholders must rank objectives or themes by importance.
- Configuration screens where an admin sets the display order of survey options or report categories (Open Point).
- When the research question specifically requires ranked preference data, not just selection or rating.
When not to use
- Lists of more than 7–10 items — the cognitive load becomes too high and rankings become unreliable. Consider grouping, filtering, or a dot-voting approach instead.
- When participants only need to select one best option — use radio buttons instead.
- When all options are equally acceptable and order does not matter — use a checkbox group instead.
- When the participant should weight items numerically — use a rating scale or slider instead.
- Mobile-first public surveys where drag interaction is unreliable on touch — ensure keyboard and button-based reorder alternatives are always present.
Do / Don't
Do
Randomise the initial order of items across participants to prevent order bias in aggregated results.
Don't
Present items in a fixed order (alphabetical or logical) that may systematically influence responses.
Do
Limit the list to 5–7 items for public-facing surveys where participants may have low digital literacy.
Don't
Ask participants to rank 10+ items in a single list, particularly in a community engagement context.
Do
Provide explicit written instructions — 'Drag items or use the arrow keys' — in helper text above the list.
Don't
Assume participants will discover the drag interaction without prompting.
Do
Always provide a keyboard-operable reorder mechanism (arrow keys or up/down buttons) as a full alternative to drag.
Don't
Rely solely on drag-and-drop — this excludes keyboard-only users and many mobile users.
Do
Announce position changes to screen readers using a live region after each reorder action.
Don't
Silently update the visual order without a corresponding accessible notification.
Layout & Spacing
List container: padding: --op-space-8 (8px) vertical, --op-space-12 (12px) horizontal border: 1px solid --op-color-border-default border-radius: --op-radius-md (8px) gap between items: --op-space-4 (4px)
Rank item row: min-height: 48px (touch target compliance) padding: --op-space-8 (8px) --op-space-12 (12px) border-radius: --op-radius-sm (4px) gap between drag handle, badge, label: --op-space-8 (8px)
Drag handle icon: size: 20x20px padding: --op-space-8 (8px) to expand touch target to 44x44px
Position badge: min-width: 24px padding: 2px --op-space-8 (8px) border-radius: --op-radius-pill (999px) font: --op-text-sm, --op-font-body, medium weight
Field label: font: --op-text-base, --op-font-body, semibold margin-bottom: --op-space-4 (4px)
Helper text: font: --op-text-sm, --op-font-body margin-bottom: --op-space-8 (8px)
Tokens
| Part | Token | Value |
|---|---|---|
| List container border (default) | --op-color-border-default | Standard border for form field containers. |
| List container border (error) | --op-color-status-error | Applied to the container border when validation fails. |
| Rank item background (default) | --op-color-bg-primary | Inherits page background; no explicit fill in default state. |
| Rank item background (hover) | --op-color-bg-secondary | Subtle hover highlight for the full item row. |
| Drop target indicator | --op-color-interactive-default | 2px horizontal line showing the drop position. |
| Position badge background | --op-color-interactive-default | Green-400 fill for the position number badge. |
| Position badge text | --op-color-text-on-interactive | High-contrast text on the green badge. |
| Drag handle icon | --op-color-text-secondary | Muted icon colour; darkens to --op-color-text-primary on hover. |
| Drag handle icon (disabled) | --op-color-text-disabled | Non-interactive state. |
| Item label text | --op-color-text-primary | Primary text colour for item labels. |
| Helper text | --op-color-text-secondary | Secondary colour for instructional helper text. |
| Focus ring | --op-color-interactive-focus | 3px solid focus ring on focused rank items and drag handles. |
| Validation message (error) | --op-color-status-error | Error text and icon below the list. |
Engineering notes
- The ranking component is not currently backed by a Web Awesome (wa-*) primitive. Implement using the HTML Drag and Drop API or a library such as SortableJS, with keyboard event listeners as a mandatory complement.
- Wrap the list in a
- or manage ARIA roles explicitly. Each item should be
- .
- Implement an aria-live='polite' region outside the list to announce reorder events: 'Item moved to position N of M.' Fire this after each drag-drop or keyboard move completes.
- Keyboard reorder pattern: Space or Enter enters move mode; Up/Down Arrow moves the item; Space or Enter confirms; Escape cancels and returns the item to its original position.
- On touch devices, supplement drag with visible Up/Down reorder buttons on each item as an explicit alternative — do not rely on touch-drag alone.
- Randomise the initial item order server-side or at survey initialisation time. Do not randomise on every render as this resets participant progress.
- Serialise the final order as an array of item IDs (not labels) for form submission. Maintain a stable ID for each option independent of its current rank position.
- When used in a form with validation, mark the fieldset as required and surface errors via aria-describedby linking the list container to the validation message element.
Keyboard interaction
| Key | Action |
|---|---|
| Tab | Moves focus to the next drag handle (or rank item if handles are not separately focusable). |
| Shift + Tab | Moves focus to the previous drag handle. |
| Space / Enter | Activates move mode on the focused item. The item is visually highlighted and keyboard move instructions are announced to screen readers. |
| Arrow Up | In move mode, moves the focused item one position up in the list. Announces the new position via live region. |
| Arrow Down | In move mode, moves the focused item one position down in the list. Announces the new position via live region. |
| Escape | Cancels move mode and returns the item to the position it occupied when move mode was activated. |
Why it matters
Government consultation surveys are required to meet WCAG 2.1 AA and often serve participants who use assistive technology, older devices, or have motor impairments that prevent reliable drag interaction. A keyboard-operable ranking mechanism is not optional — it is a legal accessibility obligation in most jurisdictions where Openpoint operates.
Focus
Focus is placed on the drag handle of each rank item. When move mode is active, focus remains on the item being moved and does not shift to other elements. After a drop or keyboard move, focus stays with the moved item at its new position. If move mode is cancelled with Escape, focus returns to the item's drag handle. A visible 3px focus ring using --op-color-interactive-focus is always shown — never suppressed.
ARIA
| Role or attribute | When to use | Example |
|---|---|---|
role="listbox" | Applied to the
| <ul role="listbox" aria-label="Rank your top priorities"> |
role="option" | Applied to each | <li role="option" aria-posinset="2" aria-setsize="5"> |
aria-posinset | Current rank position of the item within the list. Updated dynamically after each reorder. | aria-posinset="2" |
aria-setsize | Total number of items in the ranking list. | aria-setsize="5" |
aria-live="polite" | Applied to an off-screen announcement region. Fires a plain-language message after each reorder, e.g. 'Public transport moved to position 1 of 5.' | <div aria-live="polite" class="sr-only" id="rank-announcer"></div> |
aria-describedby | Links the list container to the helper text and/or validation message element. | aria-describedby="rank-helper rank-error" |
aria-disabled="true" | Applied to the list container and each item in the disabled state. | aria-disabled="true" |
aria-invalid="true" | Applied to the list container when validation fails. | aria-invalid="true" |
Contrast
Position badge: --op-color-interactive-default (green-400) background with --op-color-text-on-interactive. The numeric label at --op-text-sm must meet 4.5:1. Verify the specific green-400 value meets this ratio — if not, increase badge text weight or use a darker ramp step. Item label text: --op-color-text-primary on --op-color-bg-primary. Standard body text contrast, typically exceeds 7:1. Helper text: --op-color-text-secondary on --op-color-bg-primary. Must meet 4.5:1 minimum. Drag handle icon: --op-color-text-secondary at rest. As a non-text element, must meet 3:1 against its background per WCAG 1.4.11. Error state: --op-color-status-error for both the container border and error message text. Text must meet 4.5:1.
Touch targets
Each rank item row has a minimum height of 48px, exceeding the 44px minimum touch target requirement. Drag handles have a minimum interactive area of 44x44px achieved via padding. On touch devices, Up/Down reorder buttons must also meet the 44x44px minimum. Do not reduce row height in dense display modes without providing an alternative reorder mechanism.
Things to avoid
- Do not rely solely on drag-and-drop interaction. Always provide a keyboard-operable and touch-button alternative.
- Do not suppress the focus ring on drag handles or rank items for aesthetic reasons.
- Do not use placeholder position labels like 'Most important' and 'Least important' as the only indication of direction — state the full instruction explicitly in field label or helper text.
- Do not animate reorder transitions in a way that cannot be disabled. Use @media (prefers-reduced-motion: reduce) to suppress list animations.
- Do not let the list exceed 10 items. Ranking long lists produces unreliable data and is inaccessible to keyboard users.