动态rem

layout 和 screen的宽度

在比较遥远的时候,网页还是在pc端流行,很少有人开发移动端网页,所有网页的宽度比较大。 随着移动端开发的慢慢崛起,我们就想把pc端的页面放到移动端也能正常的查看,但是手机屏幕那么小,怎么才能完全的显示整个页面的布局呢?

我们通过手机浏览器打开网页,尽然手机屏幕的大小改变不了,那么有没有一种办法,让手机浏览器的内部宽度变得和pc端的大小相近呢?浏览器的厂商开始发现了这个商机,纷纷的开始开发,终于达成了,在一般情况下,手机浏览器的内置宽度是980px。这样,我们用手机浏览器打开pc端的页面也可以看了,但是需要用户滚动和缩放才可以清除的查看网页,但是作为一个开发人员,对用户这么不友好,饭碗都没有了。

// iphone 7
document.documentElement.clientWidth  // 980px
screen.width // 375px

上面提到了2个宽度,屏幕宽度(visual width)和手机浏览器内部宽度(layout width)


1.png

之后出现了<meta name='viewport>可以进行设置和开发, 下面再探讨。

通过meta改变layout width

我们从上面知道,如果不设置,浏览器默认的layout width的值是980px,但是我们在移动端开发的时候,不希望用户非要通过方法页面和滚动页面来展示内容,有没有一种方法,让我们的在开发移动端页面的时候layout widthvisual width一样呢?这样我们设置的css的像素就会很清晰的反应在页面中。用户也可以不需要缩放的查看页面。

这个时候meta标签就登场了。

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

通过上面代码layout width===visual width

initial-scale缩放什么

直接上公式:

initial-scale = layout width(布局宽度) / visual width(视口宽度)

我是这样理解的,如果我们设置了initial-scale = 0.5,意味着缩小一半,那应该是什么缩小呢? 通过测试,我得到是页面的元素缩小了,例如:本来10px可以展示30长度,现在要缩小一半,10px不能变,30长度也不能变,要让30长度在layout width中显示的区域缩小一半,只能是放大layout width了

动态REM移动端方案

1. 把html的font-size设置成设计稿的宽度

<meta name="viewport" content="width=device-width ,initial-scale=1,maximum-scale=1,minimum-scale=1" >  <!--如果不设置width= device-width,则浏览器默认模拟的是980px-->
<script>
  var css = `html{
    font-size: 320px
  }`    
  document.write(`<style>${css}</style>`)
<script>  
  1. 设计稿页面的宽度 === 320px === html的font-size
  2. 1rem === html的font-size
  3. 由1和2 推出 1rem = 设计稿页面的宽度

2. 根据设备的尺寸调正html的font-size

把html的font-size*修改后的数据

<meta name="viewport" content="width=device-width ,initial-scale=1,maximum-scale=1,minimum-scale=1" >  <!--如果不设置width= device-width,则浏览器默认模拟的是980px-->
<script>
  var width = document.documentElement.clientWidth  //如果不设置宽度,浏览器默认模拟的是980px
  var scale = width/320;
  console.log(scale)
  var css = `html{
    font-size: ${320*scale}px
  }`    
  document.write(`<style>${css}</style>`)
</script>  
  1. 实际页面的宽度 === ? === html的font-size
  2. 1rem === 实际页面的宽度

3. 设置好font-size后根据比例换成rem

统一根据自身尺寸/设计稿尺寸来设置rem

  1. 由于1rem=320px(设计稿尺寸) ,所有我们需要把对应的比例px变成rem
  2. 例如原来的16px的margin-top,变成现在的16/320rem 是不是觉得会变得很小,不方便计算,所以又有一个方案,统一的把html的font-size除以10,然后我们在转换的时候再乘以10
<!-- 防止数据太小,统一变化下 -->
<script>
  var width = document.documentElement.clientWidth  //如果不设置宽度,浏览器默认模拟的是980px
  var css = `html{
    font-size: ${width/10}px
  }`
  document.write(`<style>${css}</style>`)
</script>

<!--使用css函数来统一变化rem-->
rem($px)
   ($px/320*10)rem

<!-- 是不是好奇为什么不除以100,因为除以100的话,font-size=320/100 = 3.2px -->
<!-- 3.2px???你想想浏览器的最小像素是多少?是多少?默认的是12px,你设置的话,最小也是6px,所以不行 -->

4. 结尾

到这里,其实已经做好了手机端的rem,但是由于设计师的职业病,就出现了border1px的小小小bug,你如果觉得1px不重要,到这里就可以了。下面我将要解析下设计师的处女座情节

相关文章

  1. 腾讯rem
  2. 阿里巴巴UED
  3. 腾讯app-rem变革

border-1px的问题

这个问题的来源

  1. 人有富贫,屏幕也一样,好的屏幕的dpr是不同的,展示在我们面前的色彩,清晰度都是不一样的。
  2. retina屏幕下,dpr = 2或3,但是在普通的屏下面dpr=1
苹果手机dpr.png

dpr(设备像素比)

devicePixelRatio = 物理像素 / 独立像素 
// 我们的css中的px === 独立像素
// 实际屏幕像素  ===  物理像素
  1. 首先我们手机的分辨率高,就看的东西越仔细,这是为什么呢? 分辨率和我们的dpr又有什么联系呢?

    在屏幕大小都差不多的情况下,一个分辨率为750的, 一个分辨率为640的手机,都要展示一个长度为30px的物体,让这个物体占有同样的面积,所以只有高分辨率(750)的1物理像素对应的独立像素多,也就是dpr高。不然的话,在同等dpr中,css的1px对应相同的物理像素,在750的分辨率中就会变小。

  2. 通过dpr,我们可以知道该设备上一个css像素代表多少个物理像素。例如,在Retina屏的iphone上,dpr的值为2,也就是说1个css像素相当于2个物理像素。

  3. 然后得说一下,为什么存在retina下,border: 1px这一说?

我们正常的写css,像这样border: 1px;,在retina屏幕下,会有什么问题吗?

设备像素比

在retina屏幕下,我们设计师想要的1px,其实是1物理像素,但是对于css而言,只需要显示0.5px,但是在普通的屏下面的,css的0.5px会被默认的当成0px处理,这就是一个矛盾了。

解决border 1px

  1. 通过windon.devicePixelRatio获取页面的设备像素比
  2. 通过<meta name="viewport" content="width=device-width ,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}" > scale来缩放比例
    var scale = 1 / window.devicePixelRatio; //获取对应的缩放比例
  3. 由于initial-scale的改变,引起了设备独立像素的改变,也就是document.documentElement.clientWidth的改变。第二步 把initial-scale变小了,引起了document.documentElement.clientWidth的变大对应的倍数,所以这一缩小,一放大就抵消了。
  4. 获取正确的document.documentElement宽度
没有设置width=device-width.png
<!-- 由于我们在meta中没有设置width=device-width 所以我们
  通过document.documentElement.clientWidth获取的宽度是物理像素 * dpr 
-->
<script>
  var scale = 1 / window.devicePixelRatio; //获取对应的缩放比例
  var meta = `<meta name="viewport" content="initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale} user-scalable=no">`
  document.write(meta);
  var width = document.documentElement.clientWidth 
  var css = `html{
font-size: ${width / 10}px
}`
  document.write(`<style>${css}</style>`)
</script>

最后链接

芳姐线上浏览地址加上1px
移动前端开发之viewport的深入理解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容