整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

如何让网页更机智地,适配不同的尺寸 - css进阶

如何让网页更机智地,适配不同的尺寸 - css进阶


体查询

响应式网页是这几年很流行的网页风格之一,他能够以一套网页代码,面对不同的条件,例如改变浏览器的宽度,手机横竖屏,作出不同的样式调整。


一套代码走天下


最出名的响应式框架是Bootstrap,来自Twitter。也是每个刚入门前端开发师必学的框架,利用这个框架可以很轻松实现响应式效果。


面对不同的浏览器宽度,作出界面调整


要实现响应式,关键在于使用媒体查询 Media!


语法


@media媒体特性and 媒体特性) {你的样式}


看起来好像很复杂,先看完整的代码

@media  (max-width:480px){ 
    body{background-color:green}
 }

上面这句话的意思,浏览器的宽度小于或等于480px时,背景颜色是绿色。


再来多一个,如下

@media  (min-width:481px){ 
    body{background-color:red}
}

上面这句话的意思,浏览器的宽度大于或等于481px时,背景颜色是红色。


媒体特性

媒体特性就是依据什么样的条件来进行更改样式,是根据屏幕宽度大小、还是横竖屏呢。这些条件都是官方定的,非常多。但实际上,真正有用的就是 min-width和max-width,根据浏览器宽度来设定不同的样式。


这里会很容易混淆min-width和max-width的意义。min-width表示大于等于,max-width表示小于等于。

@media (max-width: 500px) {
    /** 窗口宽度小于等于500像素的样式 **/
}


@media (min-width: 800px) {
    /** 窗口宽度大于等于800像素的样式 **/
}


当有多个媒体特性时,用and连接,就可以形成一个区间范围

@media (min-width: 600px) and (max-width: 700px) {
    /** 窗口宽度在600-700像素的样式 **/
}


这就是他最基本的用法,凡是有两面性,下面来说说他的优缺点。

优点

(1)面对不同分辨率设备灵活性强

(2)能够快捷解决多设备显示适应问题

缺点

(1)兼容各种设备工作量大,效率低下

(2)代码累赘,会出现隐藏无用的元素,加载时间加长


案例

全局布局

下面这种响应式布局最为常见,通过媒体查询定义不同的样式,让其能够适应手机浏览器和桌面浏览器:


1、电脑端大屏幕下,网页元素全部展示

电脑端样式


2、手机端下,因为屏幕有限,只能让主体内容呈现出来,其余部分隐藏起来,并且让字体缩小。

手机端样式


栅格布局

一提起响应式,绝对离不开强大的栅格布局,根据浏览器的宽度,设置容器不同的列宽。


<div class="row">
  <div class="col-xs-12 col-sm-6 col-md-8"></div>
  <div class="col-xs-12 col-sm-6 col-md-8"></div>
</div>


只需要按照填写bootstrap参数,即可匹配不同的宽度


栅格布局的原理其实也是利用了媒体查询,这样你就可以自定义一份自己的栅格布局。

部分源代码


总结

1. 基本要求

前端界面显示的速度一般要求是:60fps

2. 根据要求 1s / 60=16.67ms 即:处理一个界面的时间,除了浏览器自己需要的时间,开发者能使用的时间大概10ms

10ms中处理的流程为:

javascript > style > layout > paint > composite

如果JS的操作影响到了界面样式的变化,则有上面的处理流程

如果style的操作影响到布局,则会进入layout,反之亦然;style改了transform属性,在blink和edge浏览器里面不需要layout和paint

3. 减少渲染堵塞

避免head标签JS堵塞

异步加载JS: HTML5 的script 属性 defer

JS写在body后面

Tips: 可能有时候JS库,还没加载完就要执行了,可能会报错

减少 head 中的 CSS 资源

CSS 会影响到 layout ,写在Body里面会界面闪烁,但写在Head里面如果太多会影响渲染

不要写太多base64,虽然很方便,但会改变文件大小

如果CSS文件没有达到三位数的大小,可以直接写到Html界面中,因为如果使用外链样式,则可能会花费更多时间,如DNS解析,建立链接,下载等

优化图片,使用响应式图片,图片的srcset 属性,会有兼容问题

<img srcset='photo_w350.jpg 1x photo_w640.jpg 2x' src='phtot_w350.jpg' alt=''>

使用picture按需加载,需要写在HTML中,如果使用JS来调用,则无效

<picture>

<source srcset='baner_w1000.jpg' media="(min-width:801px)"> # source 还有其它的优化属性,不过会有兼容问题: type='image/webp'

<source srcset='baner_w800.jpg' media="(max-width:800px)">

<img src='baner_w800.jpg' alt=''> # picture 必需有 img 标签,只有img标签才会触发onload事件; picture 与 source 都不触发 layout

</picture>

判断浏览器是否支持:

var supportSrcset='srcset' in document.createElement('img');

var surportPicture='HTMLPictureElement' in window;

延迟加载

<picture>

<source data-srcset="photo_w350.jpg 1x, photo_w640.jpg 2x">

<img data-src="photo_w350.jpg" src="about:blank" alt=""> # src 写为此值不会报错,也对浏览器友好

</picture>

监听Scroll事件

showImage(leftSpace=500){

var scrollTop=$window.scrollTop(), $containers=this.$imgContainers, scrollPosition=$window.scrollTop() + $window.height();

for(var i=0; i < $containers.length; i++){

//如果快要滑到图片的位置了

var $container=$containers.eq(i);

if($container.offset().top - scrollPosition < leftSpace) {

this.ensureImgSrc($container);

}

}

}

ensureImgSrc($container) {

var $source=$container.find("source");

if($source.length && !$source.attr("srcset")){

$source.attr("srcset", $source.data("srcset"));

}

var $img=$container.find("img:not(.loading)");

if($img.length && $img.attr("src").indexOf("//") < 0){

$img.attr("src", $img.data("src"));

this.shownCount++;

}

}

init(){

//初始化

var leftSpace=0;

this.showImage(leftSpace);

//滑动

$window.on("scroll", this, this.throttleShow);

}

ensureImgSrc($container){

//如果全部显示,off掉window.scroll

if(this.shownCount >=this.allCount){

$window.off("scroll", this.throttleShow);

}

}

指定图片尺寸,避免 reflow

4. 压缩与缓存

作用

第一个是把200变成304,避免资源重新传输,

第二个是让浏览器直接从缓存取,连http请求都不用了,这样对于第二次访问页面是极为有利的。

开启压缩 gzip

server {

gzip on;

gzip_types text/plain application/javascript application/x-javascript text/html text/css text/xml text/javascript

}

缓存 Cache-Control

location ~* \.(jpg|gif|png|webp) {

expires 30d;

}

location ~* \.(css|js) {

expires 1d;

}

此方法会在返回的请求响应头中添加 Cache-Control: max-age=604800 , 且 max-age 的优先级会大于 last-modified

开启 nginx last-modified 字段,在响应头中: last-modified 字段接收nginx的数据,在请求头中: If-Modified-Since 字段返回给nginx

这个办法得查手册

使用etag,在响应头中是: Etag 字段 ,在请求头中会记录在 If-None-Match 字段

server {

etag on;

}

5. 其它优化

DNS预读取

<link rel="dns-prefection" href="https://www.google.com"> # 在Head标签中添加相应的域名,由于它是并行的,不会堵塞页面渲染

HTML优化

删除注释、缩进,除了 pre 或 code 这样的标签不能删除,其它的都可以

代码优化

例如说html别嵌套太多层,否则加重页面layout的压力

CSS的选择器别写太复杂,不然匹配的计算量会比较大

JS的滥用闭包,闭包会加深作用域链,加长变量查找的时间

6. 利用HTML5或CSS3

代替图片 或 LocalStorage、 Offline Storage

创 前端二牛

虽然执行环境的类型总共只有两种——全局和局部(函数),但还是有办法来延长作用域链的,这么说是因为有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。在两种情况下会发生这种现象。具体来说,就是当执行流进入下列任何语句时,作用域链就会得到加长:

  1. try-catch语句的catch块。
  2. with语句。

这两个语句都会在作用域链的前端添加一个变量对象。对 with语句来说,会将指定的对象添加到作用域链中。对 catch语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。下面看一个例子:

  1. var
  2. mother
  3. =
  4. {
  5. name
  6. :
  7. 'Rose'
  8. ,
  9. age
  10. :
  11. 30
  12. }
  13. function
  14. father
  15. (){
  16. var
  17. fName
  18. =
  19. 'Jack'
  20. ;
  21. var
  22. name
  23. =
  24. '张三'
  25. ;
  26. function
  27. son
  28. (){
  29. var
  30. sName
  31. =
  32. 'son'
  33. ;
  34. with
  35. (
  36. mother
  37. ){
  38. var
  39. word
  40. =
  41. 'my name: '
  42. +
  43. sName
  44. +
  45. ', father name: '
  46. +
  47. fName
  48. +
  49. ', mother name: '
  50. +
  51. name
  52. +
  53. ", mother age: "
  54. +
  55. age
  56. ;
  57. }
  58. console
  59. .
  60. log
  61. (
  62. word
  63. );
  64. //my name: son, father name: Jack, mother name: Rose, mother age: 30
  65. }
  66. son
  67. ();
  68. }
  69. father
  70. ();

首先声明一个对象 mother,包含两个属性: name和 age,然后定义一个函数 father,里面声明两个变量: fName和 name,又声明一个函数 son, son中定义了一个变量 sName和一个 with语句块。我们来看打印的结果, mother name为对象 mother中的 Rose,而不是函数 father中的 张三,这就是 with语句在起作用。

在Chrome中调试可以发现,如下图:

代码执行到19行 with语句块中时,作用域链的前端增加了一个 WithBlock作用域,根据作用域链搜索机制,此时的 name应该是 Rose。

再看下图:

代码执行到22行, with语句块执行结束, with作用域从作用域链中移除, with语句块中声明的变量绑定在 with所在的函数中,所以 console.log(word)可以正常输出 word。