CSS的 calc() 函数与100% 值

前端开发 2026-07-10

在这个示例中,我创建了一个 div 元素,其宽度为100%。然后我用两种不同的方式计算鼠标在该div内的位置:最左端的位置应该得到值0,而最右端的位置应该得到值1(偏移量与宽度的比值)。

我用JavaScript进行计算,结果符合预期。我也用CSS进行了计算,但得到的结果却完全不同。关于CSS,这里似乎有我遗漏的地方。

下面是我的代码:

<html>
  <head>
    <style>
      @property --x-offset {
        syntax: '<number>';
        inherits: true;
        initial-value: 0;
      }
      @property --cssVal {
        syntax: '<number>';
        inherits: true;
        initial-value: 0;
      }

      body {
        margin: 0;
        padding: 0;
      }
      div {
        width: 100%;
        height: 100vh;

        --cssVal: calc(var(--x-offset) * 1px / 100%);
      }
    </style>
  </head>
  <body>
    <div></div>
    <script type="module">
      const div = document.querySelector('div')

      div.addEventListener('mousemove', (evt) => {
        const width = window
          .getComputedStyle(div)
          .getPropertyValue('width')
          .slice(0, -2)
        const offset = evt.offsetX
        const jsVal = offset / width

        div.style.setProperty('--x-offset', `${offset}`)
        const cssVal = window.getComputedStyle(div).getPropertyValue('--cssVal')

        // expected to be equal, but are very different
        console.log(cssVal, jsVal)
      })
    </script>
  </body>
</html>

更新:

使用CSS时,最左端确实得到0(符合预期);但最右端的结果取决于窗口大小(并且无论如何,与我预期的1 相差很大)。

假设:我在Chrome上,并且假设浏览器支持calc()。

我的问题:为什么CSS的计算结果不是1?

解决方案

不要使用百分比,这样会走向歧路(参考不清楚)。考虑改用 100vw 代替

const div = document.querySelector('div')

div.addEventListener('click', (evt) => {
  const width = window
    .getComputedStyle(div)
    .getPropertyValue('width')
    .slice(0, -2)
  const offset = evt.offsetX
  const jsVal = offset / width

  div.style.setProperty('--x-offset', `${offset}`)
  const cssVal = window.getComputedStyle(div).getPropertyValue('--cssVal')

  // expected to be equal, but are very different
  console.log(cssVal, jsVal)
})
@property --x-offset {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

@property --cssVal {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

body {
  margin: 0;
  padding: 0;
}

div {
  height: 100vh;

  --cssVal: calc(var(--x-offset) * 1px / 100vw);
}
<div></div>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章