据说响应式已经烂大街了,无非是 @media 调一调,合理使用 CSS 的层叠覆盖,
而响应式文字并不是大多数都懂的,也许他们就只是知道 em 和 rem 而已,
至少当初我就是个白痴,用了 rem 后还拉着浏览器边框又拖又是缩放,还纳闷字体大小怎么不响应呀。
PS: 现在 vw/vh 这些根据浏览器宽度来响应的单位兼容性已经相当不错了,用它来布局相比也是另一番风味。
今天还是主讲网易和淘宝各自的响应式文字解决方案:
1. 网易派:屏幕大了,字也大了
2. 淘宝派:始终保持文字为原大小
3. 简约派:让 viewport 和 html 宽度一致
先来看下如何使用(并非完全如此操作,毕竟我也没进过他们公司)
网易派做法:
html { font-size: 10px;}@media screen and (min-width: 376px) and (max-width: 414px) { html {font-size: 11px;}}@media screen and (min-width: 415px) and (max-width: 639px) { html {font-size: 13px;}}@media screen and (min-width: 640px) and (max-width: 719px) { html {font-size: 14px;}}@media screen and (min-width: 720px) and (max-width: 749px) { html {font-size: 15px;}}@media screen and (min-width: 750px) and (max-width: 799px) { html {font-size: 16px;}}@media screen and (min-width: 800px) and (max-width: 992px) { html {font-size: 20px;}}body { margin: 0; font-size: 1.6rem;}
显然是非常简单的,举个极端的例子,当我们的网页在 ipad 上浏览时,由于屏幕变大文字也相应变大,可见
主要使用 rem 来设置宽度和大小,讲究一种感觉,不会去精细到像素。
也就是,当我们设为 1rem 时,iPone4 上是 10px,但 iPad 就是 16px 了,但随着字体变大而布局不变,看上去的相对间隙是没有变化的。
淘宝派的做法:
计算 devicePixelRatio 和 viewport 的 scale 来使得字体无变化,可见
具体插件来自于 ,这里只粘贴压缩版代码吧
!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("将根据已有的meta标签来设置缩放比例");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
主要使用 em 来设置宽度和大小,讲究一种抠像素,设计说是 12px 那它就是 12px。
由于计算后 html 和 body 的文字大小以及 initial-scale 的改变,使得 1em(不叠加的时候) 就是 12px,那么我们只管去按设计稿给的数值来设定就好了。
而淘宝本尊说,其实我一直用的是 rem,虽然是串小数,但我有插件呀...对此只能表示大佬的世界我没看懂。
比较有趣的是,淘宝的这种做法是让字体大小始终保持 12px,但图片宽高根据 html 的字体变化来设定。
比如 iPhone6 的屏变成了 37.5px,那图片的 1.625rem 相应变宽,但文字还是 12px。
如果网易派的 body 不是设为 1.6rem 而是 12px 理论上也是这样的效果,只是淘宝多算了一个 dpr 而已。
简约派的做法:
不得不说,简约派绝对是最简约的做法,
主要使用 px 来设置宽度和大小,讲究一种我不听我不听的态度,反正我屏幕就是 750px 宽,到哪都是这么宽。
听上去好像反而是最佳的办法,其实我们选择用它只在 H5 上,因为都是图片不用考虑字体大小,而有了文字的网站最终也逃不开上面两种做法。
(这样说起来好像不叫响应式文字了咧,打脸打脸...)
另外 px 没有相对大小咯,相对大小爱不爱用这个就看个人喜好了。
其实三种都是很棒的解决方案,就看你自己更喜欢哪种吧,rem, em, 还是 px .... 亦或者奇葩版的 vw