ホームページ  >  記事  >  ウェブフロントエンド  >  モバイルH5ページの1px枠の解決について

モバイルH5ページの1px枠の解決について

不言
不言オリジナル
2018-07-24 10:15:014444ブラウズ

この記事で共有した内容は、モバイル H5 ページの 1px 境界線の解決策に関するもので、困っている友人に役立つことを願っています。

質問

これは古い質問ですが、最初に気づいたとき、私を困らせたのはUIデザイナーでした。そうですね、当時私はフロントエンドの職場に入ったばかりで、何も理解していませんでした。ああ、状況は次のとおりです:
デザイナーが携帯電話を持ってやって来ました: これらの境界線はすべて太くて、私のデザインドラフトは 1px です
私:? ? ? ?私が書いたのは 1px です。信じられない場合は、見てください。 (そう言えば、CSS コードを取り出しました
デザイナー: それは違います。私の目には、デザイン草案の境界線よりもはるかに太く見えます。奇妙に見えます。(うーん、本当にピクセル化されています。) 私: じゃあ、それを 0.5 ピクセルに変更します。ほら、彼はコードを変更しました
デザイナーはそれを見てうなずきました。確かにはるかに良くなりました。その後、同じコードが一部の Android マシンで問題があることが判明しました。 0.5px の線が見えなくなりました。明らかに 0.5px に変更しても問題は解決しませんでしたが、1px の境界線がデザイン ドラフトよりもはるかに太く見えます。その理由は何でしょうか。 1px border

CSS を直接使用して 1px の境界線を設定します。
html:


      
  • 1
  •   
  • 2

css:

    * {
      margin: 0;
      padding: 0;
    }
    ul, li{
      list-style: none;
    }
    .hairlines {
      width: 300px;
      margin: 100px auto;
    }
    .hairlines li{
      position: relative;
      margin-top: 10px;
      border-bottom: 1px solid #cccccc; // 边框设置成1px
    }

で取得したスクリーンショットは次のとおりです:

デザイン案よりもかなり太く見えます。次のようになります。

モバイルH5ページの1px枠の解決について

解決策 1: 疑似クラス + 変換モバイルH5ページの1px枠の解決について 問題を解決するという心構えで、当時は理由について明確に考えていませんでしたが、関連する解決策はまだ見つかっており、そのうちのいくつかは border-image または box-shadow を使用して、目的の 1px 境界効果をシミュレートすることもできますが、個人的には、これは普遍的ではなく、従来の解決策ではないと考えています 最後の選択は、を使用することです。疑似クラス + 変換メソッド:

原則は、元の要素の境界線を削除し、:before または :after を使用して境界線をやり直し、元の要素の位置を相対的に半分に縮小します。そして新しい境界線は絶対に配置されます

htmlは上記と同じです

cssは次のとおりです:

    * {
      margin: 0;
      padding: 0;
    }
    ul, li{
      list-style: none;
    }
    .hairlines {
      width: 300px;
      margin: 100px auto;
    }
    .hairlines li{
      position: relative;
      border:none;
      margin-top: 10px;
    }
    .hairlines li:after{
      content: '';
      position: absolute;
      left: 0;
      bottom: 0;
      background: #cccccc;
      width: 100%;
      height: 1px;
      -webkit-transform: scaleY(0.5);
      transform: scaleY(0.5);
      -webkit-transform-origin: 0 0;
      transform-origin: 0 0;
    }
この場合、実際には上記の方法を使用して解決します。 1 年間 1px の境界線の問題を抱えていましたが、使用してみていくつかの問題を発見しました: 1. なぜscaleY (0.5) を取得するのですか? つまり、すべてのモデルを半分に縮小する必要がありますか?普遍的ですか?
2. コンテナーの 4 つの境界線を同時に描画したい場合はどうすればよいですか?
最後の 2 つの質問は、上記のコードを変更することで解決できますか?効果を見やすくするために、通常の書き方で得られる効果と疑似クラスを使用して得られる効果を並べて違いをわかりやすくしました):
nbsp;html>


  <meta>
  <meta>
  <title>移动端1px边框问题</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    ul, li{
      list-style: none;
    }
    .lines {
      width: 200px;
      margin: 0 auto;
    }
    .lines li {
      border: 1px solid #cccccc;
      height: 50px;
      line-height: 50px;
      text-align: center;
      border-radius: 13px;
      margin-top: 10px;
    }
    .hairlines {
      width: 200px;
      margin: 0 auto;
      border-radius: 3px;
    }
    .hairlines li{
      height: 50px;
      line-height: 50px;
      border:none;
      text-align: center;
      position: relative;
      margin-top: 10px;
    }
    .hairlines li:after{
      content: &#39;&#39;;
      position: absolute;
      left: 0;
      top: 0;
      border: 1px solid #cccccc;
      border-radius: 26px;
      width: 200%;
      height: 200%;
      -webkit-transform: scale(0.5);
      transform: scale(0.5);
      -webkit-transform-origin: left top;
      transform-origin: left top;
    }
  </style>


粗线
      
  • 1
  •   
  • 2
细线
      
  • 3
  •   
  • 4

このようにして得られたレンダリングは以下の通りです:



下面的边框明显细很多,更贴近于设计稿。
那么“1.为什么是scaleY(0.5)?这个0.5是怎么得出的?是不是所有机型都是要scale缩小到一半,换句话说是不是通用?”这个问题该怎么回答呢?
这就要回到问题的本质,为什么我明明在css里面写了1px,但是仍然会出现“看起来比平时要粗很多的效果”?
查了资料看了下,原来css中设置的像素并不是跟设备的像素点一一对应,这就是说,我在css中写明1px,实际在手机上,看到的有可能并不是一个像素点占据的宽度。
css的像素是一个抽象的相对的概念,在不同的设备和环境中,所表示的物理像素点是不一样的,在比较老的设备上,屏幕像素密度比较低,这样,确实一个1px的像素就是一个物理像素,但是技术飞速发展,现在的手机屏幕都是高分辨率,在尺寸未变化的情况下,一个屏幕上将充满着更多的像素点,这时一个css的像素(通常称为逻辑像素)将对应多个物理像素点。
那到底一个css的像素宽度上对应多少个物理像素点呢?
这就要提到devicePixelRatio(设备像素比)
devicePixelRatio = 设备上物理像素/独立像素,可以通过window.devicePixelRatio获取,这个像素比恰好可以描述一个css的像素宽度上对应多少个物理像素点,其实就是对应devicePixelRatio个像素点。
当viewport的属性initial-scale为1时,页面大小正常,但initial-scale为0.5时,页面被缩小了1倍,devicePixelRatio为2的设备本来1个CSS像素宽度占2个物理像素宽度,缩小后的1个CSS像素宽度就只占1个物理像素,即实现了真正的1物理像素。

解决方法二:rem + viewport

说到这里,解决方法就很明了了:我们可以在运行的时候拿到设备的devicePixelRatio,动态改变viewport的initial-scale为 1/devicePixelRatio,这样就能保证1px的宽度就是真正的1物理像素宽。其他适配使用rem(因为使用px的话都会被缩小)
代码如下:

nbsp;html>


  <meta>
  <!--<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, width=device-width">-->
  <title>移动端1px边框问题</title>
  <script>
    (function () {
      var clientWidth = window.screen.width;
      var dpr = window.devicePixelRatio;
      var vp = document.createElement(&#39;meta&#39;);
      document.documentElement.style.fontSize = clientWidth > 414 ? &#39;20px&#39; : 20 * dpr * clientWidth / 360 + &#39;px&#39;;
      vp.name = &#39;viewport&#39;;
      vp.content = `initial-scale=${1.0 * 1 / dpr}, maximum-scale=${1.0 * 1 / dpr}, minimum-scale=${1.0 * 1 / dpr}, user-scalable=no, width=device-width`;
      var m = document.getElementsByTagName(&#39;meta&#39;)[0];
      m.parentNode.insertBefore(vp, m);
    })();
  </script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    ul, li{
      list-style: none;
    }
    .lines {
      width: 10rem;
      margin: 0 auto;
    }
    .lines li {
      border: 1px solid #cccccc;
      height: 2.5rem;
      line-height: 2.5rem;
      text-align: center;
      border-radius: 0.6rem;
      margin-top: 0.5rem;
    }
  </style>


      
  • 1
  •   
  • 2

得到的效果可以看下图(手机上看更明显一些):

モバイルH5ページの1px枠の解決について

从上来看,回到之前的问题,"1.为什么是scaleY(0.5)?这个0.5是怎么得出的?是不是所有机型都是要scale缩小到一半,换句话说是不是通用?"其实并不一定是0.5,在dpr为3的设备上其实应该是0.3333……,也不通用,因为每个手机的dpr可能不一样,但是方法一中的0.5一般因为至少比1px细,所以也差不多可以满足设计师的要求了。

相关推荐:

HTML5中新增的标签和属性的总结

js和HTML5基于过滤器从摄像头中捕获视频的方法

以上がモバイルH5ページの1px枠の解決についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。