Skip to content

1px

在移动端 web 开发中,UI 设计稿中设置边框为 1 像素,前端在开发过程中如果出现 border:1px,测试会发现在某些机型上,1px 会比较粗,即是较经典的 移动端 1px 像素问题。

下面我们以 Iphone 6 为例子进行说明:

iphone6

在图中我们可以找到几个关键的信息:

Iphone 6 的物理像素为 750 * 1334, 逻辑像素为 375 * 667 , DPR 为 2。

那么其中这几个概念就是:

  • 物理像素:设备屏幕实际拥有的像素点。比如 iPhone 6 的屏幕在宽度方向有 750 个像素点,高度方向有 1334 个像素点,所以 iPhone 6 总共有 750*1334 个物理像素。

  • 逻辑像素:也叫“设备独立像素”(Device Independent Pixel, DIP),可以理解为反映在 CSS/JS 代码里的像素点数(1px 的大小)。

  • 设备像素比(Device Pixel Ratio, DPR):一个设备的物理像素与逻辑像素之比。

移动端 1px 变粗的原因?

在Iphone6中其逻辑像素为 375*667,那么我们在设置content = "width=device-width",那么就代表css的宽度为375(document.documentElement.clientWidth === 375),但是在其他的手机如Phone 6Plus设备屏幕宽度414px(document.documentElement.clientWidth === 375),这时候我们占据整行的元素就不够了,所以单独使用content = "width=device-width"是无法使得所有的页面像素都相同的,所以出现了手淘的Flexiable布局。

其原理是借助于 window.devicePixelRatio

在移动端的 meta 中总有这么一句话

首先我们看 viewport 这个是用来设置浏览器在网页上的可视区域的。但是其有不局限于可视区域的大小,其可能比浏览器的可视区域大,也有可能比可视区域小。 我们一般分 3 种 viewport

  1. layout viewport

如果将移动端的浏览器的可视区域设为 viewport,PC 网页就会因为太窄而显示错乱。所以这些浏览器会将 viewport 设为一个较宽的值。 这时候 viewport = document.documentElement.clientWidth;

  1. visual viewport layout viewport 的宽度是大于浏览器可视区域的宽度的,所以还需要一个 viewport 来代表浏览器可视区域的大小,这个 viewport 叫做 visual viewport。 visual viewport 的宽度可以通过  document.documentElement.innerWidth 来获取。

  2. ideal viewport ideal viewport 是一个能完美适配移动设备的 viewport。 首先,不需要缩放和横向滚动条就能正常查看网站的所有内容;其次,显示的文字、图片大小合适,如 14px 的文字不会因为在一个高密度像素的屏幕里显示得太小而无法看清,无论是在何种密度屏幕,何种分辨率下,显示出来的大小都差不多。 这个 viewport 叫做 ideal viewport。

PC 端

在 PC 端我们不需要考虑 retina 的问题,但是我们可以看下面几个了解以下几个信息

涉及到的元素 : window、document、window.screen 涉及到的属性:

  • clientWidth、clientHeight
  • offsetWidth 、 offsetHeight
  • scrollWidth 、 scrollHeight
  • scrollTop

在浏览器中,一般 client[Width|Height] 代表元素的内容宽高(不包含滚动条,包含 padding), offset[Width|Height] 代表元素的占位宽高(包含 padding、包含滚动条、包含边框、不包含 margin 外边距),scroll[Width|Height] 代表元素的内容全文宽高,那么对于浏览器中 window、document 这些分别代表什么意思

  • 网页可见区域宽度 clientWidth: ${document.body.clientWidth},
  • 网页可见区域高度 clientHeight: ${document.body.clientHeight},
  • 网页可见区域宽度 offsetWidth: ${document.body.offsetWidth} (包括边线和滚动条宽度),
  • 网页可见区域高度 offsetHeight: ${document.body.offsetHeight} (包括边线的宽度),
  • 网页正文全文宽度 scrollWidth: ${document.body.scrollWidth},
  • 网页正文全文高度 scrollHeight: ${document.body.scrollHeight},
  • 网页内容被卷去的高度 scrollTop: ${document.body.scrollTop} (Firefox 浏览器),
  • 网页内容被卷去的高度 scrollTop: ${document.documentElement.scrollTop} (IE 浏览器),
  • 网页内容被卷去的宽度 scrollLeft: ${document.body.scrollLeft},
  • 网页内容正文部分上 screenTop: ${window.screenTop},
  • 网页内容正文部分左 screenLeft: ${window.screenLeft},
  • 屏幕分辨率的高度 height: ${window.screen.height},
  • 屏幕分辨率的宽度 width: ${window.screen.width},
  • 屏幕可用区域高度 availHeight: ${window.screen.availHeight},
  • 屏幕可用区域宽度 availWidth: ${window.screen.availWidth}`

视窗:

说明 : 浏览器用户可见区域的大小

有关的属性 有 viewport document.documentElement.clientWidth/Height

viewport 指网页的显示区域,

html
<meta name="viewport" content="width=device-width,initial-scale=1.0, user-scalable=no" />
  • width : viewport 的宽度
  • height : viewport 的高度
  • initial-scale : viewport 的初试缩放比例
  • maximum-scale : viewport 的最大缩放比例
  • minimum-scale : viewport 的最小缩放比例
  • user-scalable : viewport 是否允许缩放

1、正常情况下 viewport 跟浏览器的显示窗口是一样大小的,但是在移动设备上可能不一样大。

手机浏览器的窗口为 640px 宽,网页的宽度为 1200px,如果设置 width = device-width,那么 viewport 的宽度就是 640px 那么就会出现横向滚动条;如果我们将 viewport 的宽度设置成 1200px,那么浏览器的显示宽度还是 640px,但是显示区域宽度达到 1200px,整个页面缩小了,也就不需要滚动条了。

console.log('clientWidth = ' + document.documentElement.clientWidth)
//在 Iphone 6 为 375px;
// Chrome、FF、IE9+ 为 1423px 浏览器实际宽度为 1440px 所以 document.documentElement.clientWidth 为 浏览器可视区域宽度 - 滚动条的宽度 console.log('clientHeight = ' + document.documentElement.clientHeight);

console.log('window.innerWidth = ' + window.innerWidth); // Chrome、FF、IE9+ 都是 1440px window.innerWidth 浏览器的可视区的宽度 包含滚动条
// IE8- undefined
console.log('window.outerWidth = ' + window.outerWidth); // Chrome、FF、IE9+ 都是 1440px window.outerWidth 浏览器的的宽度 // IE8- undefined
console.log('clientWidth = ' + document.body.clientWidth) // Chrome 为 1343px 1440- htmlmargin 15*2 - 10 - 17 //

/* 跟元素大小,位置有关的属性方法 1、offsetParent,offsetTop,offsetLeft,offsetWidth,offsetHeight; 2、scrollTop,scrollLeft,scrollWidth,scrollHeight; 3、clientTop,clientLeft,clientWidth,clientHeight 4、getBoundingClientRect(); 5、style.width,style.height

影响其有   滚动条、box-sizing、position、layout

*/

// 元素的大小 // offsetWidth、 offsetHeight // clientWidth、 clientHeight // scrollWidht、 scrollHeight // width、height (css/style) // getBoundingClientRect() // 影响其计算的 box-sizing 滚动条

// offsetWidth、 offsetHeight // 说明 : 元素的布局宽度 包含元素的边框、内边距、滚动条、css 宽高