网络知识 娱乐 [ CSS ] H5 移动端适配与通用样式配置总结

[ CSS ] H5 移动端适配与通用样式配置总结

重置和配置通用样式

css 样式重置实质上就是对不同浏览器的样式使用一个统一的标准,他的目的在于减少 css 的样式代码。css reset 也有比较常见的“库”,比如,normalize.css 或者是 meyerweb.css。在早期的一些简单的项目开发,css reset 直接可以了引用这样的文件,因为这是一些比较标准的写法。

但是,随着 web 的发展,出现了更多样式个性化的网站和 H5,css reset 除了对基本的样式做一个统一之外,更多的也是根据业务需求的编写定制化的基础样式,相当于一个最基本的默认通用样式,举个例子:

/* 基础的样式配置*/
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
  margin: 0;
  padding: 0;
}

/* 定制化的的样式配置*/
button {
    padding: 5px 10px;
    margin: 0;
   	color: #dddddd;
    font-size: 16px;
    font-weight: bold;
    line-height: 1.0;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    border: 2px solid rgba(255, 255, 255, 0.8);
    border-radius: 0.25em;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

当然,除了 button 还有 input ,input 的 active和,textarea 等等,都可以根据业务的设计稿来做一些配置。

retina 下 1 像素适配问题

由于 retina 屏幕是高清屏幕,显示的 1px 看起来就会很不协调。需要使用一个高清屏幕下的适配方法,方法也有几种,这里只用一种比较好配置的方法。

既然是 retina 屏幕下要显示 1px 的线条,那么只需要将 1px 的线缩放为 0.5 即可。适配的方法就是使用 ::after 或者是 ::before 伪类方法,画出一条边再将这一条边缩放 0.5 倍即可。

假设以 border-right 画一条边,那么就是

.div::after {
  content: '';
  position: absolute;
  height: 200%;
  top: -50%;
  right: 0;
  border-right: 1px solid #bfbfbf;
  -webkit-transform: scale(0.5);
  transform: scale(0.5);
  -webkit-transform-origin: right center;
}

设置绝对定位,将高度放大为 200% ,再往回移 50%的距离,此时线条顶部是溢出的,相当于现在底部移回了 100% 。这时再将线条缩放 0.5 ,就可以还原回一个 1px 的线条。如果是利用 border-top 画边,那么可以:

.div::before {
  content: '';
  position: absolute;
  width: 200%;
  left: -50%;
  top: 0;
  border-top: 1px solid #bfbfbf;
  -webkit-transform: scale(0.5);
  transform: scale(0.5);
  -webkit-transform-origin: center top;
}

方法基本上是一样的,可以使用 scss 封装一个 @mixin 方法 ,在需要使用的地方使用 @include xx( top or left or right or bottom) 引入就行。

横竖屏问题

首先,横竖屏的适配可能可以做,但是不是特别建议在一套样式里面做这样的适配,以为不论从维护或者是体验都不会特别友好,而且,根据之前开发的 H5 来看,横屏展示在业务上的需求一般也是比较少的。所以,如果确实需要做的话可以单独的写一套适用于横屏的缩放样式。

js 获取屏幕的转向方法 :

window.orientation;

在link中通过media筛选加载 :

<link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css">

高清图问题

所谓高清,就是在原来那么大的一块地方,再放一张更大的图片。标准是 2倍 或者 3倍。

高清图这个可以根据业务需求来定,但是,图片的尺寸一般 2 倍图即可,以我之前的开发经验,2 倍图是最常用也是体验效果还不错的标准。

3 倍图一般也没有在一个 h5 中去使用,就算是一些比较长期的 H5 ,也比较少使用到。最近的一次是在微信小程序的开发中想尝试一下,毕竟展示类图片较多,但实际上手机端的大小看2倍图已经足够,3倍图可能会好一点但是,也不会说特别的好。同时也要考虑性能的问题。所以,最后还是使用了 2 倍图实现。

@media only screen and (-webkit-min-device-pixel-ratio:3){
    .css{
        background-image: url(images_3x.png);
    }
}

3 倍图使用媒体查询实现,也可以通过后面将会提到了 rem 适配,在 dpr 为 3 的时候,做样式上处理。

通用样式封装

封装通用的样式函数,我一直使用的是 scss ,就还是以 sass 为例子,一般我会把非常常用的样式组合现在一个 @mixin 中,方便后面的地方调用。

比如说,单行省略号的 scss:

@mixin over-single-line{
  overflow: hidden;
  text-overflow:ellipsis;
  white-space: nowrap;
}

或者多行省略号的 scss:

@mixin over-single-line($num){
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: $num;
  overflow: hidden;
}

特殊字体样式 scss :

@mixin font-style-light {
   font-family: '666666';
   src: url('....')
}

处理一些特有样式问题的css,像 ios 上点击 btn 有时候会现阴影,那么就封住一个用于 fix 的 scss :

@mixin fix-ios-grey {
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  -webkit-tap-highlight-color: transparent;
}

按自己开发习惯针对不同模块的样式给封装样式,或者是按按照设计稿编写出通用模块,节省在开发过程之中的时间。

@mixin images($width,$height) {
  width:$width,
  height:$height,
  img{
  	width:100%;
  	height:100%;
  }
}

rem 样式转换

这个是整个样式适配的核心,我就从概念入手说明,也是对样式适配这个问题进行一个梳理总结。

基础概念-物理像素

phyysical pixel ,简称 pp 。物理像素就是屏幕上面的每一个发亮的点,顾名思义物理就是硬件层面的东西,和软件没有关系。

基础概念-分辨率

resolution ,也是一个物理像素resolution ,也是一个物理像素他指的是屏幕宽和高像素点排列数量,例如 1920 X 1080 值得就是宽有 1920 个像素点 高有1080 个像素点。

基础概念-CSS像素

CSS 像素指的就是UI的逻辑像素,1个 px 的 CSS 对应的就是一点的物理像素。在以前开发PC系统界面的时候,这个是像素是一一对应的。但是,自从苹果出了 retina 屏幕之后就变得不一样了,他的逻辑像素 1px 是使用了,2个点的物理像素,换句话说就是 1 px 的 css 用了更加精细的效果去呈现它。

基础概念-设备像素比

设备像素比指的就是设备的 (物理像素 / 逻辑像素) 的一个比值。在 JavaScript 之中是可以使用 window.devicePixelRatio 去获取,css 也有一些方法可以获取到,目前,大部分的是 2 倍 dpr。

当为 dpr 为 2 的时候,指的就是 1 个 CSS的像素 = 4 个物理像素,原因是长和宽都增加了一倍,那么实际上就是原来的 2 倍。

基础概念-像素密度

像素密度称为 ppi 或者是 dpi ,指的物理像素,在一个手机上物理像素在屏幕占的一个密度。比如:

A 手机 4.7 英寸,ppi 320 ; B 手机 4.7 英寸,ppi 620;

很明显,B的手机会更加的细腻,理论上是 ppi 愈高愈好,但也不是绝对。它更是一个相对的比较。

使用 rem 进行缩放适配

使用 rem 的方式进行适配,利用媒体查询针对不同的设备做 rem 的缩放。以 iphone 6 宽度为 375px 为准,则设计稿需要的默认宽度就是 750。

第一步还是要在 meta 标签中设置宽度等于物理像素比

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

第二步是用媒体查询配置好不同设备的情况下根节点的基准字体大小

html {
  font-size: 10;
  @media screen and (min-width: 320px) {
    font-size: 20 * (320 * 2 / 750);
  }
  @media screen and (min-width: 360px) {
    font-size: 20 * (360 * 2 / 750);
  }
  @media screen and (min-width: 375px) {
    font-size: 20 * (375 * 2 / 750);
  }
  @media screen and (min-width: 410px) {
    font-size: 20 * (410 * 2 / 750);
  }
}

比如在宽度为 375 的 iphone6 情况下,他的基准样式就是 20。写一个 width 为 343 的 div, 那么他的宽度是 17.15 rem 。但我们不需要自己去计算得到 rem,而是可以使用scss 可以写一个函数进行封装。

reset($size){
	$rem = ( $size / 20 / 2 )* 1rem ;
}
return $size

使用的时候 就可以按设计稿的实际尺寸进行填写像上面的例子就可以写成

width: reset(343);

当然,这只是举个例子,像上面的 reset 其实还可以丰富一下逻辑的,比如 pt 格式的转换,有些设计稿是以 ios 的单位 pt 备注的,那么就可以 加上 $size * 2 的逻辑或者是说判断如果有 % 或者 0 ,是做一个怎样的处理等等。

其他需要注意的问题

例如禁止用户缩放,和防止抖动

const scale  = 1;
document.getElementsByName('viewport')[0].setAttribute('content','width=device-width,initial-scale='+scale+',maximum-scale='+scale+',minimum-scale='+scale+',user-scalable=no');
    var tid;
    window.addEventListener('resize', function() {
        clearTimeout(tid);
        tid = setTimeout(setBaseFontSize, 300);
    }, false);
    window.addEventListener('pageshow', function(e) {
        if (e.persisted) {
            clearTimeout(tid);
            tid = setTimeout(setBaseFontSize, 300);
        };

入口样式文件

最后,将上面的文件 @import 整理成一个入口文件 utils.scss 即可。

// utils.css
@import style1.scss
@import style2.scss
@import style3.scss
@import style4.scss
@import style5.scss

新的样式适配方式

最为简单的方式是使用 vw 的方案,但是这个我没有实践过,毕竟现在更多的是处理系统级的项目了,抽空我过一遍再写一篇文章。

结语

样式适配在现在也有很多库可以用, 而且使用 rem 的方式也是相对于现在比较旧的方法,但是还是需要动手实现了解一下移动端的适配,毕竟做前端开发并不是一有什么新的东西就可以拿来用。除非是不停的做新的项目,否则更多的是在原有的项目上做拓展或者维护,所以,原理相当于基础知识还是必须掌握的,有问题才知道怎么解决或者是写出更好更简洁的 CSS 和节省找 BUG 的时间。