前端之旅——HTML篇

      HTML无非就是由许多标签构造而成,这些标签拥有许多属性,属性之中又有一部分属于内置样式。在真正进行页面制作的时候,标签自带的样式几乎都要被重置,它比CSS更无话可说。无话可说在于,有些网站可以直接用div走完,当然这是不科学的,不然造就那么多标签为了好看吗?!这就涉及到语义化:方便在没有外部引入的情况下,页面不会出现混乱,能平稳过渡到有样式的效果上;利于爬虫抓取,SEO;各类人群都能浏览;最关键的是代码可读性高,便于团队合作。了解标签语义是基础,还有什么可说的呢?除了meta稍微难理解一点,的确也就没有什么难点了。

      HTML与CSS是相辅相成的,它们分开了看很简单,放在一起就会产生一些化学反应。PC端主要问题来自于浏览器不做赘述,今天主说移动端,它不只有浏览器的问题。

      说起移动端,最让人烦躁的莫过于适配,网上也提出了不少适配方案,不过都不是那么尽人意。为什么会出现这种情况呢?市场上的手机种类繁多,手机分辨率也是各有千秋,以前以为苹果算是比较规矩的,现在也不规矩起来。而网页的适配多依赖于相对单位,于是就有了浮点数进行计量从而导致效果并不太理想,再加上字体之间的差异又加剧了适配的难度,这是我的个人理解。通常适配方案里面会规避对字体使用相对单位,改用dpr来控制字体。对于很多设计不规范的公司来说无疑增加了成本,它们不管三七二十一一股脑的用相对单位,不较真的话也没有太大的毛病。

      关于移动端适配方案很多,不同的适配方案实现的方法不同,处理复杂度也有差异,还原度自然也不完全一样。

      方案一:垂直方向使用固定值,水平方向使用弹性布局进行自适应,这种操作方式很简单,也很明显还原度非常不理想。

      方案二:使用固定宽度,使用viewport进行缩放,这种方式没有做字体适配。

// 荔枝FM的执行方案
if(/Android (\d+\.\d+)/.test(navigator.userAgent)){
  var version = parseFloat(RegExp.$1);
  if(version>2.3){
    var phoneScale = parseInt(window.screen.width)/640;
    if(/MZ-M571C/.test(navigator.userAgent)){
      document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
    }else if(/M571C/.test(navigator.userAgent)&&/LizhiFM/.test(navigator.userAgent)){
      document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
    }else{
      document.write('<meta name="viewport" content="width=640, minimum-scale = '+ phoneScale +', maximum-scale = '+ phoneScale +', target-densitydpi=device-dpi">');
    }
  }else{
    document.write('<meta name="viewport" content="width=640, target-densitydpi=device-dpi">');
  }
}else{
  document.write('<meta name="viewport" content="width=640, user-scalable=no, target-densitydpi=device-dpi">');
}

// 网易的执行方案
var win = window, width = 640, iw = win.innerWidth || width, ow = win.outerHeight || iw, sw = win.screen.width || iw, saw = win.screen.availWidth || iw, ih = win.innerHeight || width, oh = win.outerHeight || ih, ish = win.screen.height || ih, sah = win.screen.availHeight || ih, w = Math.min(iw, ow, sw, saw, ih, oh, ish, sah), ratio = w / width, dpr = win.devicePixelRatio;
if (ratio = Math.min(ratio, dpr), 1 > ratio) {
  var ctt = ",initial-scale=" + ratio + ",maximum-scale=" + ratio, metas = document.getElementsByTagName("meta");ctt += "";
  for (var i = 0, meta; i < metas.length; i++) meta = metas[i], "viewport" == meta.name && (meta.content += ctt)
}

      方案三:使用固定宽度,以rem单位进行适配,动态写入跟字体大小。以750px设计稿为例,获取手机屏幕宽度除上设计宽度得出一个缩放因子,在1:1的情况下设置1rem=100px,根据这个规则在不同的分辨率上100乘上缩放因子从而出根字体的大小。换一个理解方式就是,将750px的视宽分成7.5份,屏幕宽度除上7.5就是根字体的大小。这种方式最字体大小做了适配,对于1px的情况需要做特殊处理。

<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
;(function(doc, win) {
  var docEl = doc.documentElement;
  var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
  var recalc = function() {
    var clientWidth = docEl.clientWidth || doc.body.clientWidth;
    docEl.style.fontSize = (clientWidth > 750 ? 100 : clientWidth / 7.5) + 'px';
  };
  win.addEventListener(resizeEvt, recalc, false);
  doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

      方案四:以rem单位进行适配,动态变换viewport,根据dpr设置根字体的大小。根字体按比例放大,viewport按比例对页面相应缩小。该方案不能百分比还原设计稿,对于布局元素须进行弹性布局自适应,而不能用rem。

var scale = 1.0;
var dpr = 1;
var isAndroid = window.navigator.appVersion.match(/android/gi);
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = window.devicePixelRatio;
if ( isIPhone ) scale /= devicePixelRatio, dpr *= devicePixelRatio;
var viewport = document.getElementById('viewport');
var content = 'initial-scale=' + scale + ', maximum-scale=' + scale + ',minimum-scale=' + scale + ', width=device-width, user-scalable=no';
viewport.setAttribute('content', content);
document.documentElement.style.fontSize = 50 * dpr + 'px';
document.documentElement.setAttribute('data-dpr', dpr);

     方案五:以rem单位进行适配,根据屏幕大小动态设置根字体的大小,变换viewport。将屏幕分成固定的份数,根据这个分割得出根字体大小,这与方案三相似,不同是多了对viewport进行缩放,百分比还原设计图。

// 将屏幕固定分为10分
var width = document.documentElement.clientWidth; 
var rem = width / 10;

// 然后设置viewport
var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale;
if (isIPhone) {
  if (devicePixelRatio >=3) {
    dpr = 3;
  } else if (devicePixelRatio >=2) {
    dpr = 2;
  } else {
    dpr = 1;
  }
} else {
  dpr = 1;
}
scale = 1 / dpr;

      移动端的适配总结来说就是:或固定某些宽度,或使用viewport进行缩放,或使用媒体查询,使用flex或百分比弹性,使用rem单位产生相应变换。移动端适配主要解决正常显示页面的问题,还有些小需求需要注意到:

      1、1px线条在不同屏幕上看着粗细有差异,有伪类+transform、viewport+rem、0.5px等等解决办法,各有利弊,我认为1px换算成rem是不靠谱的,在某些手机换成rem之后压根儿看不见。这就是我前面提到的浮点数问题,还原为像素之后不等于1,有些向上取整有些向下取整。

      2、字体处理为rem会出现一些问题,因为rem是百分比放大,那么一行文字在不同分辨率下字数是相同的。这对于设计图是还原的,但理论上手机屏幕越大一行字数应该越多才对。可以通过媒体查询或者想淘宝类似的做法,通过dpr对字体使用像素。

      3、字体行高问题,同样的设置在电脑上是居中,在某些手机上有时不居中,有时是居中的,我认为和rem和字体有关。为什么我这样认为?第一,这我还没找到解决办法,有人认为用line-height:1加上padding等距就可以轻松搞定,我试过只能说相对好一点,这和字体还是多少有点关系。但不能说它偏那一边就少加点,它在其它手机或许本来就正常显示。第二,让我对rem怀疑是因为我用css写的圆点不圆,换成px就正常。对于字体行高的问题,网上有人说是奇数字号的问题,在rem单位下是很难保证奇偶的。

      顺便解释一下rem这个单位,这个单位是css3新增的,比em优秀。em是基于最近的设置有字体大小的父元素计算的相对单位,稍不注意它就变得跟想的不一样。rem基于根字体,更加稳定,不用担心变数。

      在适配中比较流行是淘宝的flexible,算是比较完善的,配合px2rem在移动端是可以称霸的,因各自需求而定吧。不过淘宝已经放弃了这个方案,转而推荐使用vw和vh进行适配,如果不考虑低版本的浏览器这种适配方式更优。关于这种方式就不多做解释,只不过换个更靠近栅格化布局(上面的某些方案也是这个思路)的单位罢了。它和百分比的区别在于:前者依据浏览器窗口,后者依据父级容器。

转载于:https://my.oschina.net/u/3830333/blog/3085415

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值