CSS实现可滚动div:React购物车商品列表滚动失效问题
React购物车商品区纵向滚动失效修复
问题现象
- 需求:不改动现有父子组件DOM结构,仅为左侧承载购物商品的容器添加纵向滚动效果
- 异常:给目标元素设置
overflow-y: scroll属性后,页面仅渲染出滚动条样式,即使手动设置任意高度值也无法触发滚动交互,未定位到问题根源 - 问题界面:

关联代码
父组件CartModal实现
const CartModal = () => { const { totalPrice, totalAmount } = useSelector((state) => state.cart); return ( <div className={classes["cart-modal"]}> <div className={classes["cart-modal__navbar"]}></div> <div className={classes["cart-modal__body"]}> <div className={classes["body__left-side"]}> <h1>ORDERS</h1> <CartModalFoodList /> </div> <div className={classes["body__right-side"]}> <div> <img src={BigCart} /> </div> <div> <h2>Total price:</h2> <h2>{totalPrice}$</h2> </div> <div> <h2>Total amount:</h2> <h2>{totalAmount}</h2> </div> </div> </div> </div> ); };
父组件样式代码
.cart-modal { z-index: 100; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 65vw; height: 75vh; background-color: var(--main-bg-color); border-radius: 10px; box-shadow: 1px 2px 5px; overflow: hidden; } .cart-modal__navbar { width: 100%; height: 15vh; background: radial-gradient( 50% 50% at 50% 50%, var(--gradient-color-one) 0%, var(--gradient-color-two) 100% ); } .cart-modal__body { display: flex; height: 100%; } .body__left-side { height: 100%; width: 55%; background-color: white; padding: 0 3.5%; } .body__left-side h1 { color: var(--strong-yellow); text-align: center; border-bottom: 1px solid var(--weak-yellow); padding-bottom: 2%; } .body__right-side { width: 45%; height: 100%; display: flex; flex-direction: column; } .body__right-side div:first-child { height: 50%; width: 100%; } .body__right-side div:first-child img { height: 100%; width: 100%; } .body__right-side *:not(:first-child) { display: flex; justify-content: space-around; } .body__right-side *:not(:first-child) h2 { font-size: 2vw; margin: 2.5% 0; }
左侧商品列表MenuList组件实现
const MenuList = (props) => { const page = props.page; const dispatch = useDispatch(); const foodArray = props.foodList; const navigate = useNavigate(); const location = useLocation(); const params = useParams(); const [foodList, setFoodList] = useState([]); useEffect(() => { setFoodList(formatArray(foodArray)); }, [foodArray]); const queryPrams = new URLSearchParams(location.search); const sort = queryPrams.get("sort"); const onNextPageHandler = () => { dispatch(uiSliceActions.updatePage("forward")); }; const onPreviousPageHandler = () => { dispatch(uiSliceActions.updatePage("backward")); }; const onSortPageHandler = () => { navigate( `/menu/${params.foodId ? params.foodId + "/" : ""}?sort=${ sort === "asc" ? "desc" : "asc" }` ); let foodListPart = foodList[page]; let foodListSort = foodList; const sortFoodList = (sort) => { foodListPart = foodListPart.sort((a, b) => sort === "asc" ? a.foodPrice - b.foodPrice : b.foodPrice - a.foodPrice ); foodListSort[page] = foodListPart; setFoodList(foodListSort); }; sort === "asc" ? sortFoodList("asc") : sortFoodList("desc"); }; return ( <Fragment> <div className={classes["menu-list"]}> {foodList[page] ? foodList[page].map((foodObj) => ( <MenuItem key={foodObj.id} foodObj={foodObj} /> )) : ""} </div> <div className={classes["menu-list__buttons"]}> {page >= 1 && ( <Button type="button" onClick={onPreviousPageHandler}> Page {page} </Button> )} <Button type="button" onClick={onSortPageHandler} className={classes["sort-button"]} > {sort === "asc" ? `Descending` : `Ascending`} </Button> <Button type="button" onClick={onNextPageHandler}> Page {page + 2} </Button> </div> </Fragment> ); };
商品列表容器现有样式
.menu-list { overflow-y: scroll; }
问题根因
滚动不生效的核心是设置了滚动属性的元素没有被限制高度,会被内部内容完全撑开,不存在内容溢出容器的场景,具体问题点:
- 高度计算错误:
.cart-modal__body设置height: 100%是相对于父容器.cart-modal的75vh高度计算,但它的上一个兄弟节点.cart-modal__navbar已经占据了15vh高度,最终body区域实际总高度超出模态框范围,只是被父级的overflow: hidden裁剪没有显示溢出 - 滚动容器无高度约束:
.menu-list没有设置固定高度/弹性分配高度,高度完全由内部商品项撑开,即使设置overflow-y: scroll也没有滚动的空间 - 存在属性拼写错误:代码中书写的
overwflow-y是笔误,正确属性名为overflow-y
修复方案(无需改动组件DOM结构)
从父层到子层修正高度计算逻辑,给滚动容器分配明确的受限高度即可:
- 修正body区域高度,减去顶部导航栏占据的高度:
.cart-modal__body { display: flex; height: calc(100% - 15vh); }
- 给左侧容器开启纵向弹性布局,让内部子元素可以自动分配剩余空间,避免内容撑开容器:
.body__left-side { height: 100%; width: 55%; background-color: white; padding: 0 3.5%; display: flex; flex-direction: column; }
- 给商品列表容器设置弹性占满剩余空间,开启自动滚动:
.menu-list { flex: 1; overflow-y: auto; }
修改后商品列表的高度会被自动限制在左侧区域扣除标题、底部按钮后的剩余空间内,商品内容超出容器高度时即可正常纵向滚动,全程不需要调整现有组件的DOM结构。
内容的提问来源于stack exchange,提问作者Nijaz
相关产品推荐
相关产品推荐

