You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子元素CSS缩放后无法向上/向左滚动的问题及解决需求

基于光标位置缩放子元素后,父容器无法向上/向左滚动溢出内容

我给容器的子元素实现了基于光标位置的缩放功能,缩放本身正常工作,但当子元素缩放比例大于1时,尽管父容器设置了overflow: scroll,子元素向上、向左溢出的内容却无法通过滚动查看。

复现步骤

  • 运行下方的代码片段
  • 将鼠标悬浮在子元素上,按住ctrl + 鼠标滚轮缩放子元素
  • 缩放完成后,尝试向上或向左滚动,查看溢出的内容

期望行为

  • 子元素放大时,所有溢出的内容都能通过滚动查看
  • 不影响原有的光标缩放功能
  • 使用原生JavaScript/CSS实现,不依赖任何第三方库

曾尝试的解决方案思路

  • 设置transform-origin: 0 0;
  • 缩放时将容器的滚动位置设置为0, 0

我已经多次迭代这个光标缩放方案,但问题始终存在,怀疑无法通过单一代码修改解决。


代码片段

HTML

<div class="scroll-container">
  <div class="zoomable">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce tristique, ante ac cursus pulvinar, ligula nibh sodales purus, vitae tempus metus lacus et tortor. Integer ut hendrerit nisi. Curabitur metus lorem, egestas ut lacus semper, tristique
      condimentum nisi. In facilisis lorem sem, vel viverra quam convallis sed. Aenean porta sit amet ante ac condimentum. Vivamus molestie vehicula magna ut sagittis.</p>
    <p> Vestibulum ut felis convallis, fringilla neque eu, imperdiet ante. Proin venenatis orci arcu, eu rutrum quam consectetur sit amet. Aenean et dui vel eros sagittis facilisis. Curabitur aliquam felis in magna tempor tristique. Proin ac tellus gravida,
      viverra turpis id, posuere magna. Nunc mollis orci id erat fermentum, a consectetur massa sollicitudin. Maecenas fringilla nibh pulvinar tortor eleifend tincidunt in sed sapien. Suspendisse cursus gravida ante, finibus convallis nunc feugiat id.
    </p>
  </div>
</div>

CSS

* {
  box-sizing: border-box;
}

body {
  background-color: lightgrey;
  min-height: 100vh;
  margin: 0;
  display: grid;
  place-items: center;
}

.scroll-container {
  height: 400px;
  width: 400px;
  background-color: #222;
  overflow: scroll;
}

.zoomable {
  height: 100%;
  color: lightgrey;
  padding: 0.5rem;
  transform-origin: 0 0;
  transition: transform 300ms ease-in-out;
}

JavaScript

const zoomContainer = document.querySelector(".zoomable");
let zoom = 1;
let origin = {
  x: 0,
  y: 0
};

zoomContainer.addEventListener(
  "wheel",
  (e) => {
    if (e.ctrlKey) {
      e.preventDefault();
      const {
        width,
        height
      } = e.currentTarget.getBoundingClientRect();
      const {
        left,
        top
      } = e.currentTarget.parentElement.getBoundingClientRect();
      const {
        scrollLeft,
        scrollTop
      } = e.currentTarget.parentElement

      const mousePositionX = e.clientX - left + scrollLeft;
      const mousePositionY = e.clientY - top + scrollTop;

      const zoomX = (mousePositionX - origin.x) / zoom;
      const zoomY = (mousePositionY - origin.y) / zoom;

      zoom = zoom + -1 * Math.max(-1, Math.min(1, e.deltaY)) * 0.5 * zoom;
      zoom = Math.max(1, zoom);

      const zoomWidth = width * zoom;
      const zoomHeight = height * zoom;

      origin.x = -zoomX * zoom + mousePositionX;
      origin.y = -zoomY * zoom + mousePositionY;

      if (origin.x > 0) origin.x = 0;
      if (origin.x + zoomWidth < width) origin.x = -width * (zoom - 1);
      if (origin.y > 0) origin.y = 0;
      if (origin.y + zoomHeight < height) origin.y = -height * (zoom - 1);

      e.currentTarget.style.transform = `translate(${origin.x}px, ${origin.y}px) scale(${zoom})`;
    }
  }, {
    passive: false
  }
);

内容的提问来源于stack exchange,提问作者PsiKai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 15:18:05