この記事で共有した内容は、モバイル H5 ページの 1px 境界線の解決策に関するもので、困っている友人に役立つことを願っています。
これは古い質問ですが、最初に気づいたとき、私を困らせたのはUIデザイナーでした。そうですね、当時私はフロントエンドの職場に入ったばかりで、何も理解していませんでした。ああ、状況は次のとおりです:
デザイナーが携帯電話を持ってやって来ました: これらの境界線はすべて太くて、私のデザインドラフトは 1px です
私:? ? ? ?私が書いたのは 1px です。信じられない場合は、見てください。 (そう言えば、CSS コードを取り出しました
デザイナー: それは違います。私の目には、デザイン草案の境界線よりもはるかに太く見えます。奇妙に見えます。(うーん、本当にピクセル化されています。) 私: じゃあ、それを 0.5 ピクセルに変更します。ほら、彼はコードを変更しました
デザイナーはそれを見てうなずきました。確かにはるかに良くなりました。その後、同じコードが一部の Android マシンで問題があることが判明しました。 0.5px の線が見えなくなりました。明らかに 0.5px に変更しても問題は解決しませんでしたが、1px の境界線がデザイン ドラフトよりもはるかに太く見えます。その理由は何でしょうか。 1px border
CSS を直接使用して 1px の境界線を設定します。
html:
* { 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 }
で取得したスクリーンショットは次のとおりです:
解決策 1: 疑似クラス + 変換 問題を解決するという心構えで、当時は理由について明確に考えていませんでしたが、関連する解決策はまだ見つかっており、そのうちのいくつかは 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; }
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: ''; 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.为什么是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物理像素。
说到这里,解决方法就很明了了:我们可以在运行的时候拿到设备的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('meta'); document.documentElement.style.fontSize = clientWidth > 414 ? '20px' : 20 * dpr * clientWidth / 360 + 'px'; vp.name = 'viewport'; 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('meta')[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.为什么是scaleY(0.5)?这个0.5是怎么得出的?是不是所有机型都是要scale缩小到一半,换句话说是不是通用?"其实并不一定是0.5,在dpr为3的设备上其实应该是0.3333……,也不通用,因为每个手机的dpr可能不一样,但是方法一中的0.5一般因为至少比1px细,所以也差不多可以满足设计师的要求了。
相关推荐:
以上がモバイルH5ページの1px枠の解決についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。