2

viewport 适配

原理:

通过设置 initial-scale , 将所有设备布局视口的宽度调整为设计图的宽度

实现:

(function(){
  // 设置设计稿的宽度
    var targetW = 375;    

  // 计算当前视口与设计稿的比值
    var scale = document.documentElement.clientWidth / targetW;

  // 获取 meta[name='viewport'] 元素
  var meta = document.querySelector("meta[name='viewport']");

  // 设置meta元素 content的值,重点是设置 initial-scale 的值为前面计算的比例
  meta.content="initial-scale="+scale+",minimum-scale="+scale+",maximum-scale="+scale+",user-scalable=no";
})()

优点:

所量即所得避免复杂的计算,直接使用UI的标准像素值

缺点:

没有使用完美视口, 在一些设备上会出现问题

图片无法进行适配,可能会造成失真

rem 适配

em 和 rem

em : CSS长度单位, 默认字体大小的倍数; 如果元素上默认字体大小为 16px,2em 的长度就是 32px;

rem: CSS长度单位, 根元素字体大小的倍数,只有根元素字体大小有关; html 中的根元素即 html 元素

大部分浏览器默认字体大小为 16px;

rem 适配原理

长度单位都是用 rem 来就行设置
当屏幕尺寸改变,只有修改 html 元素的 font-size 即可实现等比适配
我们在制作页面的时候,只考虑跟设计稿相同的屏幕尺寸即可,其他尺寸屏幕自动适配

方案一 借助media
@media screen and (min-width: 320px) {html{font-size:50px;}}
@media screen and (min-width: 360px) {html{font-size:56.25px;}}
@media screen and (min-width: 375px) {html{font-size:58.59375px;}}
@media screen and (min-width: 400px) {html{font-size:62.5px;}}
@media screen and (min-width: 414px) {html{font-size:64.6875px;}}
@media screen and (min-width: 440px) {html{font-size:68.75px;}}
@media screen and (min-width: 480px) {html{font-size:75px;}}
@media screen and (min-width: 520px) {html{font-size:81.25px;}}
@media screen and (min-width: 560px) {html{font-size:87.5px;}}
@media screen and (min-width: 600px) {html{font-size:93.75px;}}
@media screen and (min-width: 640px) {html{font-size:100px;}}
@media screen and (min-width: 680px) {html{font-size:106.25px;}}
@media screen and (min-width: 720px) {html{font-size:112.5px;}}
@media screen and (min-width: 760px) {html{font-size:118.75px;}}
@media screen and (min-width: 800px) {html{font-size:125px;}}
@media screen and (min-width: 960px) {html{font-size:150px;}}

此种方式,对屏幕划分了不同的范围

方案二 JS动态修改根元素字体大小
var designWidth = 375;  // 设计稿宽度
var rem2px = 100;                // 在屏幕宽度375px,的时候,设置根元素字体大小 100px

// 根据屏幕宽度 动态计算根元素的 字体大小
document.documentElement.style.fontSize = ((window.innerWidth / designWidth) * rem2px) + 'px';

上面代码,我们设置根元素 font-size 为 100px;100计算比较容易;

比如某个元素,设计稿设计宽度为 300px, 我们需要设置 width: 3rem

比如某个元素,设计稿设计字体大小是 14px, 我们需要设置 font-size:0.14rem

方案三 JS动态修改配合CSS预处理器 (推荐)
@rem:750/16rem;

.header {
  width: 750/@rem;

  .header-image {
    margin:48/@rem 32/@rem 36/@rem 48/@rem;
    width: 128/@rem;
    height:128/@rem;
    border-radius: 4/@rem;
  }
}
(function(){
  //屏幕宽度
  var width = window.innerWidth;
  //创建style标签
  var styleNode = document.createElement('style');
  //设置 font-size 的值, 会根据屏幕动态变化
  styleNode.innerHTML = 'html{font-size: '+ width/16 +'px !important;}'; 
  document.head.appendChild(styleNode);        
})();

此种方式,理解起来较为复杂

但是,制作页面过程为无需对设计稿的 px 大小进行转换, 只要把单位变成 /@rem 即可,数值不变

当然,此种方式必须借助于CSS预处理器,像less、sass、stylus等

rem适配的优缺点

优点: 使用了完美视口,实现了等比缩放

缺点: 换算稍微复杂(相对)

建议

尽量不要对html设置百分比字号

原因如下:
1、并不能保证所有的浏览器的默认字体大小都是 16px;
用户是可以设置浏览器默认大小的;
2、字体大小不要小于 12 px
Chrome 浏览器字体大小小于 12px, 会按照12px进行计算;

图片适配

原理:根据设备像素比适配图片

方案一 媒体查询+背景图
.box{
    margin: 0 auto;
    width: 414px;
    height: 650px;
    background-image: url('images/1.png');
    background-size: 414px 650px;
}
@media (-webkit-min-device-pixel-ratio: 2),(min-resolution: 2dppx) {
    .box {
        background-image: url('images/1_2x.png');
    }
}
方案二 <picture>标签
<picture>
    <source srcset="images/1_2x.png" media="(-webkit-min-device-pixel-ratio: 2),(min-resolution: 2dppx) ">
    <source srcset="images/1.png">
    <img src="images/1.png" alt="music">
</picture>
方案三 <img>标签
<img srcset="images/1.png,images/1_2x.png 2x,
   images/1_3x.png 3x"
   src="images/1.png"
   alt="图片适配">

1px物理像素边框

很多时候,我们希望页面中有非常细的边框,但是如果小于1px,并不是所有的浏览器都能正确显示。

其实,我们可以通过各种办法把边框边度设置为1个物理像素大小,现在的手机屏幕设备像素比都是 2DPR,3DPR的,也就是1个css像素要用多个物理像素去显示,如果设置为1个物理像素大小,就会细很多。

伪元素 scale 配合 media
.box2 {
  float: right;
  position: relative;
  margin-top: 20px;
  padding:20px 0;
  width: 50%;
}
.box2::after {
  content: '';
  display: block;
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: 1px;
  background: #333;
}


@media only screen and (-webkit-device-pixel-ratio: 2) {
  .box2::after {
    transform:scaleY(.5);
  }
}
@media only screen and (-webkit-device-pixel-ratio: 3) {
  .box2::after {
    transform: scaleY(.33333333333);
  }
}
@media only screen and (-webkit-device-pixel-ratio: 3.5) {
  .box2::after {
    transform: scaleY(.28571429);
  }
}
@media only screen and (-webkit-device-pixel-ratio: 4) {
  .box2::after {
    transform: scaleY(.25);
  }
}

上面的方式,无法覆盖所有的设备屏幕,可以向下面这样设置查询范围

 @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 2dppx) {
   .box2::after {
     transform:scaleY(.5);
   }

}
@media only screen and (-webkit-min-device-pixel-ratio: 3),only screen and (min-resolution: 3dppx) {
  .box2::after {
    transform: scaleY(.33333333333);
  }
}

说明:笔者只是个在前端道路上默默摸索的初学者,若本文涉及错误请及时给予纠正,如果本文对您有帮助的话,点击铭哥哥网址 http://learn.fuming.site/ 学习更多!


捕猹少年闰土
42 声望0 粉丝