useSortable: dragged table row/column is offset when border-spacing is set
Description
When using useSortable on <tr> / <th> elements inside a <table> with border-collapse: separate and a non-zero border-spacing, the dragged element is visually offset by roughly the border-spacing amount during the drag.
Setting border-spacing: 0 removes the offset.
This looks related to how the drag feedback positioning / geometry is calculated for table layout — similar in spirit to margin-related positioning issues (e.g. #2092), but specific to CSS border-spacing on tables.
Reproduction
- Open the sandbox: https://codesandbox.io/p/sandbox/dnd-kit-bug-border-spacing-qcmq2k
- Drag a row (via the handle) or a column header.
- Observe that the dragged element is shifted by the
border-spacingamount (12px in the demo). - Change
borderSpacingto0intableStyles— the offset no longer occurs.
Expected behavior
The dragged row/column should stay aligned under the pointer / original position, regardless of border-spacing.
Actual behavior
The dragged element is offset by approximately the table’s border-spacing value for the duration of the drag.
Environment
@dnd-kit/react:0.5.0@dnd-kit/helpers:0.5.0- React:
18.2.0 - Browser: (fill in — e.g. Chrome 139 / macOS)
Minimal CSS that triggers the bug
table {
border-collapse: separate;
border-spacing: 12px; /* non-zero triggers the offset */
}Workaround
Avoid border-spacing and simulate the gap with transparent borders on cells instead (keep border-spacing: 0):
table {
border-collapse: separate;
border-spacing: 0;
}
tr > td {
background-clip: padding-box;
border-top: 12px solid transparent;
}This preserves visual spacing between rows without triggering the drag offset.
Notes
- Reproduced with both row sorting (
<tr>+handleRef) and column sorting (<th>). - Based on the docs Table example; the only meaningful change for the bug is non-zero
border-spacing.
Source: clauderic/dnd-kit