【问题标题】:Fluid Type with Zoom带缩放的流体类型
【发布时间】:2022-01-06 22:24:00
【问题描述】:

我的要求是:

  1. 从 1280 到 1920,字体大小应该在 14px 到 22px 之间流动
  2. 用户应该能够正常缩放

我还没有找到一个真正做到这两点的解决方案。是的,我已经看到 CSS Tricks 简化了流体,使用任何类型的 vw 都会使缩放无效。

  • clamp(0.875em, 1.146vw, 1.375em) - 缩放比例与常规缩放不同,它是 5% 而不是 50%。
  • clamp(0.875em, 1.4vw - 0.3em, 1.375em) - 遇到 min 和 max,但在缩放时会缩小。
  • calc(0.875em + 8 * (100vw - 1280) / 640) - 不缩放。

【问题讨论】:

    标签: css fluid-layout typography


    【解决方案1】:

    在 CSS 计算中存在限制,例如乘法要求其中一个数字是无单位的ref。所以我们所针对的公式无法在 CSS 中实现:

    clamp(14px, calc(1.09375vw + (0.05208vw * (100vw - 1280px) / 640)), 22px)
    

    为了满足我们需要使用 JavaScript 处理的所有要求:

    let element = document.querySelector('.scale');
    
    function updateFontSize() {
      let size = 14;
      let vpWidth = window.innerWidth;
      let zoom = ((window.outerWidth) / window.innerWidth);
    
      if (vpWidth >= 1920) {
        size = 22;
      } else if (vpWidth <= 1280) {
        size = 14;
      } else {
        //calculate
        size = 14 + (vpWidth - 1280) * 8 / 640;
      }
      //apply zoom
      size *= zoom;
    
      element.style.setProperty('--font-size', size + 'px');
    
      document.getElementById('stats').innerText = 'Viewport Width: ' + vpWidth + 'px  \nZoom: ' + (zoom.toFixed(2) * 100).toFixed(0) + '%';
    }
    
    
    window.addEventListener('resize', () => updateFontSize());
    updateFontSize();
    p {
      margin: 0;
      padding: 0;
    }
    
    .f14 {
      font-size: 14px;
    }
    
    .f22 {
      font-size: 1.376rem;
    }
    
    .scale {
      --font-size: 14px;
      font-size: var(--font-size);
    }
    
    @media screen and (min-width: 1280px) and (max-width: 1980px) {
      body {
        background-color: wheat;
      }
    }
    <div id=stats></div>
    <hr><br>
    <p class=f14>Lorem ipsum dolor sit amet.| 14px</p>
    <p class=scale>Lorem ipsum dolor sit amet.| scaling</p>
    <p class=f22>Lorem ipsum dolor sit amet.| 22px</p>

    因为 StackOverflow 将输出放在 iframe 中,所以您不会在此处看到运行 sn-p 的实际结果。切换到Full Page 或在单独的本地 HTML 文件中运行代码。
    我在上述代码中找到缩放级别的方式需要未放置在 iframe 中的代码。查找浏览器的缩放级别并非易事。有关更多信息,请参阅the thread。

    在 150% 缩放时,我没有得到感知与所需的字体大小。另外,让我们知道如果用户缩小到 50% 会发生什么。

    【讨论】:

    • 不幸的是,这不满足任何一个要求。在 1920 时,字体大小为 21.0521,而不是 22。放大到 150%,字体大小固定在 14。缩放时视口缩小。 14 * 150% = 21px 感知缩放 22 * 150% = 33px 需要缩放
    • 我认为纯 CSS 解决方案是不可能的,我们需要使用 JavaScript。你能给出1)1280宽视口缩放到150%和2)1920宽视口缩放到150%的字体大小用例吗?缩小到 50% 会发生什么?
    • 1280 视口 = 14px + 缩放 150% = 21px 1920 视口 = 22px + 缩放 150% = 33px 1280 视口 = 14px - 缩放 50% = 7px 1920 视口 = 22px - 缩放 50% = 11px跨度>
    【解决方案2】:

    我认为仅使用 CSS 是不可能实现的,但即使使用 JavaScript,它也是一个非常简单的解决方案。如果我对要求有什么误解,请告诉我。

    解决方案

    我正在通过运行resetFluidSize 函数在load 和resize 事件中重置--fluid-size CSS 变量(请注意,此过程会影响性能,因为它每次都会触发重排它运行了,为了简单起见,我这里没有做任何优化)。

    然后我使用outerWidth 来防止缩放级别(这会影响innerWidth)弄乱正确的比例,因此无论页面缩放如何,计算出来的样式都会是所需的样式。

    算完后,我将 CSS 变量更新为 document.body.style.setProperty。

    注意

    为了查看正确的值,运行代码 sn -p 整页。

    window.addEventListener('load', () => {
      resetFluidSize();
      window.addEventListener('resize', resetFluidSize);
    });
    
    const
      a = 14,
      b = 22;
    
    function resetFluidSize() {
      const
        factor = (window.outerWidth - 1280) / 640,
        lerp = a + (b - a) * factor,
        clamp = Math.max(a, Math.min(b, lerp)),
        fluidSize = `${clamp}px`;
    
      document.body.style.setProperty('--fluid-size', fluidSize);
    
      /* Just to update the feedback. */
      document.getElementById('fluid-text').setAttribute('currentSize', fluidSize);
    }
    :root {
      --fluid-size: 16px;
    }
    
    #fluid-text {
      font-size: var(--fluid-size);
    }
    
    
    /* Ignore the style below, its just for the feedback. */
    
    p {
      border-right: 1px solid black;
      margin: 0;
      width: fit-content;
      position: relative;
    }
    
    p::after {
      content: attr(currentSize);
      position: absolute;
      left: 100%;
    }
    <body>
      <p style="font-size: 14px;" currentSize="14px">
        Lorem ipsum
      </p>
      <p id="fluid-text">
        Lorem ipsum
      </p>
      <p style="font-size: 22px;" currentSize="22px">
        Lorem ipsum
      </p>
    </body>

    编辑

    如果你想在本地运行它,你可以使用这个index.html(GitHub Gist)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 2019-10-02
      • 1970-01-01
      • 2017-02-19
      • 1970-01-01
      相关资源
      最近更新 更多