用 sortablejs 拖拽时元素样式错乱怎么办?

闲人艺菲 阅读 68

我在用 SortableJS 做一个可拖拽的列表,但一拖起来 item 的宽度就变窄了,布局直接崩掉。试过加 fixed 宽度也不行,是不是我 CSS 写得有问题?

这是我的 item 样式:

.drag-item {
  display: flex;
  padding: 12px;
  background: #f5f5f5;
  border: 1px solid #ddd;
  width: 100%;
  box-sizing: border-box;
}
我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
美玲🍀
哈哈这个坑我踩过,SortableJS拖拽时样式崩掉的问题太常见了。你漏了两个关键属性:

第一是 flex-shrink: 0,不加这个的话flex元素被拖拽时会自动压缩宽度。第二要给拖拽的克隆元素设置同样的宽度。

试试这样改:
.drag-item {
display: flex;
padding: 12px;
background: #f5f5f5;
border: 1px solid #ddd;
width: 100%;
box-sizing: border-box;
flex-shrink: 0; /* 关键在这里 */
}

.sortable-chosen {
width: 100% !important; /* 拖拽时的克隆元素 */
}


我之前也死活找不到原因,后来发现SortableJS会在拖拽时创建一个克隆元素,如果不强制指定宽度,它就会用默认值。记得把这两行加上应该就能解决。
点赞
2026-03-06 17:25
ლ雪利
ლ雪利 Lv1
这个问题我之前踩过坑,折腾了大半天才发现原因。

问题出在 SortableJS 拖拽时会创建一个"幽灵元素"跟随鼠标移动,这个元素默认是被 append 到 body 上的。你想想,它脱离了原来的父容器,那 width: 100% 自然就失效了,变成 body 的 100% 或者干脆没有宽度。

别走弯路,直接用 forceFallback 配合 fallbackOnBody 解决:

new Sortable(yourContainer, {
forceFallback: true,
fallbackOnBody: true,
fallbackClass: 'drag-item-ghost',
// 其他配置...
});


然后 CSS 里给幽灵元素一个明确的宽度:

.drag-item-ghost {
width: 你容器的实际宽度 !important;
opacity: 0.5;
background: #f5f5f5;
}


如果你容器宽度是动态的,不想写死,还有个骚操作。用 JS 在初始化时动态获取:

const containerWidth = document.querySelector('.your-container').offsetWidth + 'px';


然后动态设置 ghost 样式,或者直接用 CSS 变量也行。

我当时就是死活没想到元素会被扔到 body 外面去,一直以为是 flex 布局的问题,后来用 DevTools 一看元素结构才恍然大悟。以后遇到拖拽样式问题,先看元素实际被放哪了。
点赞 5
2026-02-28 15:11