1. 单位值
模拟移动端的mata
为什么会有媒体查询?
- 移动设备的快速普及完全颠覆了Web设计领域。
- 用户不再仅在传统桌面系统上查看Web内容,他们越来越多地使用具有各种尺寸的智能电话、平板电脑和其他设备。
- Web设计人员的挑战是确保他们的网站不仅在大屏幕上看起来不错,在小型的电话以及介于它们之间的各种设备上看起来也不错
- 什么是媒体查询
- 媒体查询是向不同设备提供不同样式的一种方式,它为每种类型的用户提供了最佳的体验。
- css2: media typemedia type(媒体类型)是css 2中的一个非常有用的属性,通过media type我们可以对不同的设备指定特定的样式,从而实现更丰富的界面。
- css3: media querymedia query是CSS3对media type的增强,事实上我们可以将media query看成是media type+css属性(媒体特性Media features)判断。
-
2.1 link标签引入媒体查询
- html标签引入css样式文件,添加属性media=’screen and (max-width: 800px)’
- max-width:800px,表示最大屏幕尺寸为800像素时,css样式文件才会生效
- 屏幕大于800px没有样式
- 屏幕小于800px,添加css样式
- 表示最小屏幕尺寸为801像素时,css样式才会生效
- 媒体类型(Media Type):
媒体特性
-
2.3 css3新增的@media
- css样式文件中直接写入媒体查询
- @media screen and (min-width: 801px) {
div {
width: 100px;
height: 100px;
background-color: green;
}
}- 表示媒体查询 彩色电脑屏幕 and (最大尺寸)
- 当屏幕尺寸最小值为 801 的时候div变为green
2.4 逻辑操作符
- and 与
- 合并多个媒体属性或合并媒体属性与媒体类型, 一个基本的媒体查询,即一个媒体属性与默认指定的screen媒体类型。
-
- 当屏幕最小为801px 和 最大为1000px的时候颜色变为green
- 当屏幕最大为800px的时候颜色变为oreange
- 当屏幕最小为1000px的时候颜色变为red
逗号 , 或
- 没有or关键词可用于指定备用的媒体功能。
- 相反,可以将备用功能以逗号分割列表的形式列出
- @media screen and (min-width: 801px), (max-width: 1000px)
- 当屏幕最小801px或最大为100px时颜色变为green
not 非
-
- 要指定否定条件,可以在媒体声明中添加关键字not,不能在单个条件前使用not。
- 该关键字必须位于声明的开头,而且它会否定整个声明。
- 所以,上面的示例会应用于除才色屏幕外的所有设备
only 向早期浏览器隐藏媒体查询
- 媒体查询规范还提供了关键字only,它用于向早期浏览器隐藏媒体查询。
- 类似于not,该关键字必须位于声明的开头。
- 早期浏览器应该将以下语句media=”screen and (min-width: 401px) and (max-width: 600px)” 解释为media=”screen”: 换句话说,它应该将样式规则应用于所有屏幕设备,即使它不知道媒体查询的含义。
- 无法识别媒体查询的浏览器要求获得逗号分割的媒体类型列表,规范要求,它们应该在第一个不是连字符的非数字字母字符之前截断每个值。
- 所以,早期浏览器应该将上面的示例解释为:media=”only” 因为没有only这样的媒体类型,所以样式表被忽略。
易混淆的宽度
- 练习 当图片最大摆放五列,根据屏幕缩小变换列
-
3. 物理像素和设备独立像素
- html标签引入css样式文件,添加属性media=’screen and (max-width: 800px)’
一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。
- 设备独立像素(也叫目睹无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(css像素),然后由相关系统转换为物理像素
- 设备像素比(device pixel ratio)设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到 设备像素比 = 物理像素 / 设备独立像素 js中可以通过 window.devicePixelRatio
- css像素在PC端显示器需要用(1*1)个栅格点表示
- 在iPhone6中则需要4(2*2)个
- 也就是在不同的屏幕上(普通屏幕 vs retina屏幕),css像素所呈现的大小(物理尺寸)是一致的,不同的是一个css像素所对象的物理像素个数是不一致 在普通的屏幕下,1个css像素对应的1个物理像素 为1:1 。
在retina屏幕下,1个css像素对应4个物理像素 1:4
1个位图像素是栅格图像(如:png,jpg,gif等)最小的数据单元。
处理HTML 生成DOM树
- 浏览器把获取到的html代码解析成1个Dom树,html中的每个tag都是Dom树中的1个节点,根节点就是我们常用的document对象( tag),当然这里包含用js动态创建的dom节点
- 处理CSS 生成CSSDOM树
- 浏览器把所有样式(主要包括css和浏览器的默认样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式,生成CSSDOM树
- 将两树合并成render树
- DOM tree和CSSDOM tree 合并成 render tree,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还有无样式head节点),因为这些节点不会用于呈现,而且不会影响呈现的
- 对render树进行布局计算
- render tree构建完毕之后根据样式计算布局,布局阶段的输出结果称为 “盒模型”(box model)。盒模型精确表达了窗口中每个元素的位置和大小,而且所有的相对的度量单位都被转化成了屏幕上的绝对像素位置 (根据css2的标准,render tree中的每个节点都称为box(Box dimensions——盒子模型),box所有属性:width,height,margin,padding,left,top,border等。)
- 将render树中的每一个节点绘制到屏幕上
- 将这些信息渲染为屏幕上每个真实的像素点了。这个阶段称为“绘制”,或者“栅格化”(rasterizing)
- 注意 visibility:hidden隐藏的元素还是会包含到render tree中的,因为visibility:hidden 会影响布局(layout),会占有
-
4.1 重绘、重排
- 我们计算它们在当前设备中准确的位置和尺寸。这正是布局阶段要做的的工作,该阶段在英语中也被称为“回流”(reflow),当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。也会回流(其实我觉得叫重新布局更简单明了些)。
- 当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。所以重排也一定重绘了,但重绘不一定重排。
- 每个页面至少需要一次回流,就是在页面第一次加载的时候。
- 重绘(repaints)
- 当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
- 重绘,重排会影响性能
- 蓝色:
- 网络通信和HTML解析
- 黄色:
- JavaScript执行
- 紫色:
- 样式计算和布局,即重排
- 绿色:
- 重绘
-
4.2 触发重排的方法
以下这些属性和方法需要返回最新的布局信息,重新计算渲染树,就会造成回流,触发重排以返回正确的值。建议将他们合并到一起操作,可以减少回流的次数。
- 这些属性包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight;scrollTop、scrollLeft、scrollWidth、scrollHeight;clientTop、clientLeft、clientWidth、clientHeight;getComputedStyle() 、currentStyle()。
- 提高网页性能,就是要降低”重排”和”重绘”的频率和成本,尽量少触发重新渲染。
- DOM变动和样式变动,都会触发重新渲染。但是,浏览器已经很智能了,会尽量把所有的变动集中在一起,排成一个队列,然后一次性执行,尽量避免多次重新渲染.
- div.style.color = ‘red’; div.style.background=‘yellow’;
- div.style.left = ’10px’; div.style.width = ’20px’;
但是浏览器只会触发一次重排和重绘。
一般来说,样式的写操作之后,如果有上面那些属性的读操作,都会引发浏览器立即重排,这种重排,不会形成之前队列优化
- Bad:
- div.style.left = div.offsetLeft + ‘px’; div.style.top = div.offsetTop + ‘px’;
- 重排重绘两次
- Good:
- var left = div.offsetLeft + ‘px’; var top = div.offsetTop + ‘px’;
- div.style.left = left; div.style.top = top;
- 放到队列一次执行重排重绘一次
- 理论上的解决优化办法:
默认继承父级的font-size
针对html根标签的字体大小,不会继承父级的
- 1 * font-size = 1rem
- 通常直接修改html标签的字体大小,用来配合rem
- html字体大小如果为10,那么1rem就等于10px