These guidelines provide an opinionated way to implement drag and drop experiences with Pragmatic drag and drop for Atlassian interfaces. These guidelines work within web platform design constraints for drag and drop, and aim to optimise clarity and performance. Non-Atlassian consumers are welcome to use these guidelines, or create their own visual language for drag and drop. The core package does not have any baked in design opinions, but some of the optional packages embody these design choices.

These design decisions are available in our Pragmatic drag drop Figma UI Kit (Atlassian only).

We plan on soon making this Figma public soon.

Cards, lists, and other UI can often be dragged and reordered. Design clear and consistent drag and drop experiences in Atlassian products following these principles:

Which parts of an entity should be draggable?

As a starting position, if an entity is draggable (eg a card), then make the whole entity draggable. If the entity has other interactive parts (eg buttons, dropdowns), then just make the drag handle icon the draggable part of the entity.

Something to keep in mind is that making an entire entity draggable will prevent text selection inside that entity (platform limitation)

Show what is draggable

It should be clear to a user that an entity is draggable by using the following:

  • a drag handle icon
  • cursor changes
  • background color changes

Please also see our accessibility guide which talks about our guidance for placing an action menu trigger on draggable entities.

Drag handle icons

A drag handle icon helps people understand what is draggable. Use the DragHandlerIcon from @atlaskit/icon as your drag handle icon. Please use "color.icon" as the icon color as it provides the greatest contrast for accessibility.

import DragHandlerIcon from '@atlaskit/icon/glyph/drag-handler';
import { token } from '@atlaskit/tokens';

function App() {
    return <DragHandlerIcon label="Drag list item" primaryColor={token('color.icon')} />;
}

Our drag handle icon button uses "color.text" as the icon color (rather than "color.icon") to align with other icon buttons in our system, and for correct colors for different states. We expect this minor mismatch will be corrected during our upcoming icon work.

When dragging is a primary action of an entity, there should be a visible drag handle on the left hand side of the entity at all times.

Dark theme
Entire entity is draggable

If dragging is possible on the item, but dragging is not considered a primary action (it is a "delighter"), then you can just show the drag handle icon on focus and hover.

Dark theme
Drag handle visible on :hover and :focus-within

When the drag handle is a delighter, it can drop down to a minium of 16px in width. Try to keep the whole entity draggable so that the draggable touch target is greater than 24px x 24px. 16px is the size of a "small" @atlaskit/icon.

Dark theme
Drag handle (16px) visible on :hover and :focus-within

16px needs to be reserved for the drag handle

When the drag handle is the only part of an entity that is draggable, it's touch target size should be at least 24px x 24px in size (which is the size of a @atlaskit/icon). You will see that the spacing of our example item has changed to give the drag handle more breathing room.

Dark theme
Only draggable from drag handle

Some entities are considered to be "implied" to be draggable (eg cards, columns, tree items) and these entities do not require a drag handle icon - although you can still add them. Implied draggable entities should use background color and cursor changes to make it clear which part of the entity is draggable, and there should be a strong preference to make as much of the entity draggable as possible.

Dark theme
AlizaSenior Engineer

Sometimes, your drag handle icon should be a button for triggering actions too (see our accessibility guide). In those cases, please use our drag handle icon button.

Dark theme
Using drag handle button

Cursor changes

Use cursor:grab as a signal that an entity is draggable. Only the draggable part of an entity should have cursor:grab. So when a draggable is only draggable from a drag handle, only the drag handle should have cursor:grab.

Dark theme
Entire entity is draggable
Drag handle visible on :hover and :focus-within
Drag handle (16px) visible on :hover and :focus-within
Only draggable from drag handle

When dragging is a secondary action, and the entity has multiple operations, it might be appropriate to delay the cursor:grab by 800ms.

Dark theme
cursor:drag delayed by 800ms

You can implement this behaviour just using CSS (no JS needed!)

.item:hover {
    animation-duration: 0s;
    animation-name: change-cursor;
    animation-delay: 800ms;
    animation-fill-mode: forwards;
}

@keyframes change-cursor {
    to {
        cursor: grab;
    }
}

Background color changes

The draggable part of an entity should have a background color change applied when hovering over it.

Please use the appropriate hover token for the entity.

Usually for a draggable entity you will be using:

  • elevation.surface as the background color.
  • elevation.surface.hovered on as the hover background color on the draggable part of the entity.
Dark theme
Entire entity is draggable
Drag handle visible on :hover and :focus-within
Drag handle (16px) visible on :hover and :focus-within
Only draggable from drag handle

For some situations it might be appriopriate to use a different color pairing. Please try to use a ".background" color token for the draggable entity, and a matching ".hovered" token for the hover.

Give feedback during a drag

While an item is being dragged, it is important that you give clear feedback to the user about what is being dragged, and what will occur when the user completes the drag.

Drag previews

A drag preview is a representation of the item being dragged. Generally a drag preview is a picture of the item being dragged around the page, and not the draggable item itself.

When an item is small and simple, the drag preview can be an exact copy of the item being dragged. If an item is larger or more complex, you should simplify the drag preview.

Simplification suggestions:

Standard

Drag previews should generally be pushed away from the users pointer by space.100 vertically, and space.200 horizontally.

{
  x: token('space.200', '16px'),
  y: token('space.100', '8px'),
}
A drag preview of a list item with an offset

Cards

Cards are to be dragged from the point they're grabbed from (no offset).

A drag preview of a card with no offset

Cursor

Due to web platform constraints, we have limited control of the cursor during a drag operation. The cursor will generally be cursor:default during a drag operation.

More information about cursors.

The draggable item

While an item is being dragged, the original item should stay in place and dim to 40% opacity (opacity: 0.4) while the drag preview is being moved around.

A draggable item left in place during a drag

Multiple-item drag previews

For multi-item drag previews, use a stacked appearance with a badge indicating the number of items being dragged.

  • Four or more small items such as list items should appear as a stacked preview under the first item. Less than four small items can appear separately where space allows (all items showing in the preview).
  • Any more than one large item (card) should show as a stack with a badge indicating the number underneath.

A stack of multiple cards being dragged across a board, with a badge indicating there are two cards being moved.

Implement with native drag previews, or use the Figma kit (Atlassian only) in designs.

Drop placement indication

It is important to communicate during a drag operation, what the result of the operation will be. There are two signals you can use to indicate drop placement:

  1. Drop indicator (a line)
  2. Background color (color.background.selected.hovered)

Drop indicator

The drop indicator line is used to communicate relative placement (for example, before or after an item in a list)

A list of items where one is being dragged over a new location. The location where the item would drop if released is marked with a blue line and dot.

A drop indicator line should have the following properties:

PropertyValue
Stroke size2px
Color"color.border.selected"
Terminal diameter8px ("space.100")
Border radius on right hand sidenone

The terminal should bleed 4px outwards on the left hand side of the target item. When this bleeding is not possible due to UI constraints (such as the element appearing in a scroll container which would cause the terminal to be cut off) then the terminal "bleeding" can be disabled and the terminal can sit against the left edge of the entity

For stacked items, the line should appear in the middle of the gap between the items.

Dark theme
Organize a team-building event
1
Todo
Create and maintain office inventory
1
Todo
Update company website content
1
Todo
Plan and execute marketing campaigns
1
Todo
Coordinate employee training sessions
1
Todo
Manage facility maintenance
1
Todo
Organize customer feedback surveys
1
Todo
Coordinate travel arrangements
1
Todo

A drop indicator line should not be used when a draggable item is being dragged over a droppable area where there is no relative placement possible (for example, dropping into an empty sibling list).

dragging over an empty column should not print a line

Background color

A background color change is used to communicate that an item will be placed within a particular droppable area. Background color changes should be used when there are multiple possible areas of the page a draggable item can be dropped on. The droppable area that the user is currently over should have its background color changed. A background color change should also occur when a draggable item starts in a droppable area, when there are multiple possible droppable areas.

dragging over a populated column, where a line and background color change is being displayed

A background color change to communicate that dropping is possible should only be applied when a user can perform a drop operation. Sometimes an entity (eg a column) only allows dropping on a subset of that entity. Only the subset that allows dropping should have a background color change, and only when the user is dragging over that subset. We don't want to have a situation where a background color changes, but when the user drops, nothing happens.

Background color change animation details:

PropertyValue
Background color"color.background.selected.hovered"
Easingcubic-bezier(0.15, 1.0, 0.3, 1.0) (import {easeInOut} from '@atlaskit/motion')
Duration350ms (import {mediumDurationMs} from '@atlaskit/motion')

When draggable items can only be moved relatively within a single container, then no background color change should be used when the user is dragging something within the experience.

A list being reordered, where only a drop indication line is being shown and there is no background changes

After a drop, show the item in its new position

After a drop, the drag preview disappears and the original item should to it's new location. To improve clarity about what the user achieved, the background color of the moved item should flash once it has been moved.

A series of actions shown in four slides. Hover state is grey, the drag indicator appears once drag begins, upon drop the color of the item flashes blue, then returns to its normal color..

We have implemented this flash in our flourish package for you to use with any framework.

Background color flash details:

PropertyValue
Background color"color.background.selected"
Easingcubic-bezier(0.25, 0.1, 0.25, 1.0) (not available in @atlaskit/motion)
Duration700ms (import {largeDurationMs} from '@atlaskit/motion')

Provide accessible controls

Be sure to see our accessibility guidelines

All draggable items should also have the ability to trigger the same outcomes using assistive technology friendly controls.

Visible drag handle icons

Please make drag handle icons visible (where possible) as this is a helpful signal for people that an item is draggable.

Action menus for move actions

If the item already has a more actions (…) menu, put the move actions inside of the menu. This provides a keyboard accessible way to move items that doesn’t rely on mouse clicking and dragging.

A Jira issue list view where a more actions button appears on the items. The button has three dots as a label ...

Drag handle icon menus for move actions

If the entity does not have any more actions (…), make the drag handle icon into a menu button. When triggered, the drag handle button opens a menu that allows the users to move the item.

An issue details view in Jira. A drag handle icon appears at the left of the assignee field. It is focussable, and opens a menu with options to move the field up or down in the view.

Use the drag handle menu component in code or the Figma kit drag handle menu (Atlassian only) in designs.

Trees

This design pattern has not yet been converted into a spec. Please refer to the following tree example as our current design guidance.
Dark theme

Dragging multiple items

This design pattern is under construction

How to show when more than one element is selected to be dragged.

Cards and boards

Use color.background.selected and color.border.selected to show the elements that have been selected, then change to the typical background color at 40% opacity once dragging begins. This shows where the objects are currently, and where they'll return if no drag location is chosen.

Because cards are larger, multiple cards should be stacked under the first card in the preview. Use a badge to show how many items are being moved.

A stack of multiple cards being dragged across a board, with a badge indicating there are two cards being moved.

Checkboxes are highly recommended to show when one or more items are selected.

List items

Use the selected background color token to indicate which items have been selected. Use drag previews as usual, with all items being dragged in a column in the order they’d appear when dropped.

A list of draggable items where some are selected, shown in blue.

For more than three or four items, show a badge indicating the number and an implied stack beneath the top item.


Was this page helpful?

We use this feedback to improve our documentation.