移动端 rem 布局小数换行,溢出

发布于 2022-09-07 12:32:15 字数 4230 浏览 33 评论 0

最近研究移动端布局,rem 布局,总体思路是把页面放大到 DPR*device-width 然后缩放 1/DPR 来解决问题,但是这样做发现一个问题。比如:

我照着 iPhone6 375*667 开发一个导航条,在苹果产品上都没有问题,

clipboard.png

但是换到 Pixel 2 上就有问题,如图:

clipboard.png

原因很明显,小数误差舍入问题因为5个导航条最终宽度 1078.85,而屏幕宽度 1078 放不下,所以换行了。

已有的方案:

  1. 最后一个 nav margin-right:auto
  2. 增加盒子容器宽度,然后父盒子overflow:hidden
  3. inline-block 布局强制不换行而不是 float 布局

当然,我知道,可以通过 flex 解决这个问题, vw 或许可以缓解这个问题,但是我没采用,因为在使用 rem 布局的年代,vwflex 的兼容性应该是不可以接受的,如果 vwflex 的兼容性可以接受的话,也没有必要使用 rem 布局了,不是么?

所以我想问,当时你们有什么更好的解决方案么?

代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script>
    document.addEventListener(
      'DOMContentLoaded',
      () => {
        let dpr = window.devicePixelRatio
        let html = document.documentElement
        let body = document.body
        let deviceWidth = window.innerWidth || html.clientWidth
        html.style.fontSize = (deviceWidth * dpr) / 10 + 'px'
        html.setAttribute('data-dpr', dpr)
        body.style.fontSize = 'initial'
        body.style.fontSize = parseInt(getComputedStyle(body).fontSize) * dpr + 'px'
        let metaViewport = document.querySelector('meta[name=viewport]')
        metaViewport.setAttribute(
          'content',
          `width=${dpr * deviceWidth},initial-scale=${1 / dpr}`
        )
      },
      { capture: true },
      true
    )
  </script>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link rel="stylesheet/less" href="./less.less">
  <script src="http://cdnjs.cloudflare.com/ajax/libs/less.js/3.0.2/less.min.js"></script>
</head>

<body>
  <nav class="nav">
    <ul class="nav__list">
      <li class="nav__item">
        <a href="#" class="nav__link">nav1</a>
      </li>
      <li class="nav__item">
        <a href="#" class="nav__link">nav2</a>
      </li>
      <li class="nav__item">
        <a href="#" class="nav__link">nav3</a>
      </li>
      <li class="nav__item">
        <a href="#" class="nav__link">nav4</a>
      </li>
      <li class="nav__item">
        <a href="#" class="nav__link">nav5</a>
      </li>
    </ul>
  </nav>
</body>
/* reset.css */

* {
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
}

li {
  list-style: none;
}

a {
  text-decoration: none;

  color: inherit;
}
.px2px(@name, @px) {
  @{name}: round(@px) * 1px;
  [data-dpr='2'] & {
    @{name}: round(@px*2) * 1px;
  }
  // for mx3
  [data-dpr='2.5'] & {
    @{name}: round(@px * 2.5) * 1px;
  }
  //for Pixel2
  [data-dpr='2.625'] & {
    @{name}: round(@px * 2.625) * 1px;
  }
  // for XiaoMi note
  [data-dpr='2.75'] & {
    @{name}: round(@px * 2.75) * 1px;
  }
  [data-dpr='3'] & {
    @{name}: round(@px * 3) * 1px;
  }
  //for Pixel2 XL
  [data-dpr='3.5'] & {
    @{name}: round(@px * 3.5) * 1px;
  }
  // for Samsung note4
  [data-dpr='4'] & {
    @{name}: @px * 4px;
  }
}

/* base.css */

.nav {
  //suggest use em not px otherwise have to set different font-size for different DPR
  .px2px(font-size, 16px);
  overflow: hidden;
  width: 100%;
}

.nav__list {
  // width: 110%;
  width: 100%;
  height: 100%;
  // for inline-block
  // white-space: nowrap;
  overflow: hidden;
  background-color: pink;
  letter-spacing: -0.5em;
}

.nav__item {
  letter-spacing: normal;
  float: left;
  // display: inline-block;
  color: white;
  background-color: yellowgreen;

  width: 65/375 * 10rem;
  height: 40/375 * 10rem;

  margin: 5/375 * 10rem;
  line-height: 40/375 * 10rem;
}

.nav__link {
  display: block;

  width: 100%;
  height: 100%;

  text-align: center;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小女人ら 2022-09-14 12:32:16

clipboard.png

抱歉 可能有点跑题 如果我遇到这个问题 可能不会用rem来做

如果是导航条的话,我用 inline-block + 百分比宽度来做

<div class="outer">
    <div style="background-color: red"></div>
    <div style="background-color: orange"></div>
    <div style="background-color: yellow"></div>
    <div style="background-color: green"></div>
    <div style="background-color: blue"></div>
</div>

<style>
    .outer {
        /* 去掉inline-block中间的间隙 */
        font-size: 0;
    }

    .outer div {
        display: inline-block;
        width: 20%;
        height: 10px;
    }
</style>

或者是 float

<div class="outer">
    <div style="background-color: red"></div>
    <div style="background-color: orange"></div>
    <div style="background-color: yellow"></div>
    <div style="background-color: green"></div>
    <div style="background-color: blue"></div>
</div>


<style>
    .outer div {
        float: left;
        width: 20%;
        height: 10px;
    }

    .outer:after {
        /* 清除浮动 */
        content: '';
        display: table;
        clear: both;
    }
</style>

效果:

clipboard.png

妥活 2022-09-14 12:32:16

不清楚位置 用flex 或者100%来做 如果用flex记得加上前缀
附上链接: https://www.cnblogs.com/xiaoh...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文