threejs解读 webGLRender

WebGLRender

概念

使用WebGL渲染场景

使用

1
WebGLRenderer( parameters : Object )
  • canvas - 绘制输出的canvas。这对应于下面的domElement属性。如果没有传值,则将创建新的canvas元素。

  • context - 可用于将渲染器添加到现有的RenderingContext。默认值为null

  • precision - 着色器精度。可以是“highp”,“mediump”或“lowp”。如果设备支持,则默认为“highp”
  • alpha 画布是否包含alpha(透明度)缓冲区。默认值为false
  • premultipliedAlpha 渲染器是否会假设颜色具有预乘alpha。默认为true
  • antialias 是否执行抗锯齿,默认值为false
  • stencil 绘图缓冲区是否具有至少8位的模板缓冲区。默认为true
  • preserveDrawingBuffer 在手动清除或覆盖之前是否保留缓冲区。默认值为false
  • powerPreference 向用户代理提供一个提示,指示适用于此WebGL上下文的GPU配置。可以是“high-performance”,“low-power”或“default”。默认为“default”
  • depth 绘图缓冲区是否具有至少16位的深度缓冲区。 默认为true
  • logarithmicDepthBuffer 是否使用对数深度缓冲区。 如果在单个场景中处理规模的巨大差异,则可能需要使用它。 默认值为false

属性

autoClear: Boolean

定义渲染器是否应在渲染帧之前自动清除其输出

autoClearColor: Boolean

如果autoClear为true,则定义渲染器是否应清除颜色缓冲区, 默认为true

autoClearDepth: Boolean

如果autoClear为true,则定义渲染器是否应清除深度缓冲区, 默认为true

autoClearStencil: Boolean

如果autoClear为true,则定义渲染器是否应清除模板缓冲区, 默认为true

capabilities: Object

包含当前RenderingContext功能详细信息d的对象
// TODO 对象属性待补充

clippingPlanes : Array

用户定义的在世界坐标系的裁剪平面对象。这些平面全局可用。空间中的点和该平面的点积为负将被裁剪掉。默认为 [].

context : WebGLRenderingContext

渲染器默认通过HTMLCanvasElement.getContext()方法其domElement获取RenderingContext上下文。
您可以手动创建它,但它必须与domElement对应才能渲染到屏幕

domElement:DOMElement

canvas元素。
这是由构造函数中的渲染器自动创建的(如果调用WebGLRenderer没有传入canvas); 你只需将它添加到你的页面就像这样:

1
document.body.appendChild(renderer.domElement);

extensions : Object

extensions.get方法的封装,用于检查是否支持各种WebGL扩展。

gammaFactor: Float

默认是

gammaInput:Boolean

如果设置,则所有纹理和颜色都是预乘伽马因子值。 默认值为false

gammaOutput:Boolean

如果设置,则所有纹理和颜色需要以预乘伽马输出。 默认值为false

info: Object

一个关于显卡内存和渲染过程统计信息的对象。便于调试和分析。该对象包含如下字段

  • memory:
    • geometries
    • textures
  • render:
    • calls
    • vertices
    • faces
    • points
  • programs

默认情况下,这些数据会在每次渲染调用时重置,但在使用一个或多个镜像时,最好使用自定义模式重置它们:

renderer.info.autoReset = false;
renderer.info.reset();

localClippingEnabled : Boolean

定义渲染器是否遵循对象级剪切平面。 默认值为false

maxMorphTargets : Integer

着色器中允许的最大变形目标数。标准材料仅允许8个变形目标。默认值为8

maxMorphNormals : Integer

着色器中允许的最大变形法线数。标准材料仅允许4个变形法线。默认值为4

physicallyCorrectLights : Boolean

是否使用物理上正确的照明模式。 默认值为false

properties : Object

由渲染器在内部使用,以跟踪各种子对象属性

renderLists : WebGLRenderLists

在内部用于处理场景对象渲染的排序

shadowMap : WebGLShadowMap
如果使用,它包含阴影贴图的引用

shadowMap.enabled : Boolean

如果为true,在场景中使用阴影贴图。 默认值为false

shadowMap.autoUpdate : Boolean

启用场景中阴影的自动更新。 默认为true
如果不需要动态光照/阴影,则可以在实例化渲染器时将其设置为false

shadowMap.needsUpdate : Boolean

设置为true时,场景中的阴影贴图将在下一个渲染调用中更新,默认值为false
如果禁用了阴影贴图的自动更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
```
则需要将其设置为true,然后进行渲染调用以更新场景中的阴影

### shadowMap.type : Integer
定义阴影贴图类型
选项有**THREE.BasicShadowMap**,**THREE.PCFShadowMap**(默认),**THREE.PCFSoftShadowMap**

### sortObjects : Boolean
定义渲染器是否应对对象进行排序。 默认为true
注意:排序用于尝试正确渲染具有一定透明度的对象。 根据定义,排序对象可能无法在所有情况下使用。 根据应用的需要,可能需要关闭排序并使用其他方法来处理透明度渲染,例如, 手动确定每个对象的渲染顺序

### state : Object
包含用于设置WebGLRenderer.context状态的各种属性的函数

### toneMapping: Constant
默认为**LinearToneMapping**

### toneMappingExposur: Number
色调映射的曝光级别。 默认值为1

### toneMappingWhitePoint : Number
色调映射白点。 默认值为1

## 方法
### allocTextureUnit : Integer
尝试分配纹理单元以供着色器使用。 如果尝试分配比GPU支持更多的纹理单元,则会发出警告。 这主要用于内部

### clear ( color : Boolean, depth : Boolean, stencil : Boolean ) : null

告诉渲染器清除其颜色,深度或模板绘制缓冲区。 此方法将颜色缓冲区初始化为当前的清除色。
参数默认为true

### clearColor ( ) : null
清除颜色缓冲区。 相当于调用```clear(true,false,false)

clearDepth(): null

清除深度缓冲区。相当于调用

1
2
3

### clearStencil ( ) : null
清除模板缓冲区。相当于调用```clear(false,false,true)

compile ( scene : Scene, camera : Camera ) : null

使用相机编译场景中的所有材质。 这对于在第一次渲染之前预编译着色器很有用

copyFramebufferToTexture ( position : Vector2, texture : Texture, level : Number ) : null

将当前WebGLFramebuffer中的像素复制到2D纹理中

copyTextureToTexture ( position : Vector2, srcTexture : Texture, dstTexture : Texture, level : Number ) : null

将纹理的所有像素复制到从给定位置开始的现有纹理

dispose(): null

处理当前渲染上下文

extensions.get ( extensionName : String ) : Object

用于检查是否支持各种扩展,并返回一个对象,其中包含扩展的详细信息(如果可用)。 此方法可以检查以下扩展名:

- WEBGL_depth_texture
- EXT_texture_filter_anisotropic
- WEBGL_compressed_texture_s3tc
- WEBGL_compressed_texture_pvrtc
- WEBGL_compressed_texture_etc1

forceContextLoss ( ) : null

模拟WebGL上下文的丢失。 这需要支持WEBGL_lose_context扩展

getClearAlpha () : Float

返回具有当前clear alpha的float。 范围从0到1

getClearColor () : Color

返回具有当前清除色的THREE.Color实例

getContext () : WebGLRenderingContext

返回当前WebGL上下文

getContextAttributes () : WebGLContextAttributes

返回描述在创建WebGL上下文时设置的属性的对象

getRenderTarget () : RenderTarget

返回当前的RenderTarget(如果有)

getCurrentViewport () : RenderTarget

返回当前视口

getDrawingBufferSize () : Object

返回包含渲染器绘图缓冲区宽度和高度的对象,单位px

getPixelRatio () : number

返回当前设备像素比率

getSize () : Object

返回包含渲染器输出画布的宽度和高度的对象(单位px)

resetGLState ( ) : null

将GL状态重置为默认值。 如果WebGL上下文丢失,则在内部调用

readRenderTargetPixels ( renderTarget : WebGLRenderTarget, x : Float, y : Float, width : Float, height : Float, buffer ) : null

将renderTarget中的像素数据读入的缓冲区。这是WebGLRenderingContext.readPixels()的封装函数

render ( scene : Scene, camera : Camera, renderTarget : WebGLRenderTarget, forceClear : Boolean ) : null

使用相机渲染场景
渲染到renderTarget或canvas
如果forceClear为true,则即使autoClear属性为false,也会在渲染之前清除深度,模板和颜色缓冲区
即使将forceClear设置为true,也可以通过将autoClearColorautoClearStencilautoClearDepth属性设置为false来阻止清除某些缓冲区

renderBufferDirect ( camera : Camera, fog : Fog, geometry : Geometry, material : Material, object : Object3D, group : Object ) : null

使用相机和指定材质渲染缓冲几何集合

renderBufferImmediate ( object : Object3D, program : shaderprogram, shading : Material ) : null

object - Object3D实例
program - shaderProgram实例
着色 - Material实例

渲染立即缓冲区。 由renderImmediateObject调用

setAnimationLoop ( callback : Function ) : null

callback - 将在每个可用帧中调用该函数。 如果传递null,它将停止任何已经在进行的动画

可以用来代替requestAnimationFrame的内置函数。 对于WebVR项目,必须使用此功能

setClearAlpha ( alpha : Float ) : null

设置清除的alpha。 有效输入是介于0.0和1.0之间的浮点数

setClearColor ( color : Color, alpha : Float ) : null

设置清除色和不透明度

setPixelRatio ( value : number ) : null

设置设备像素比率。 这通常用于HiDPI设备,以防止画面模糊。

setRenderTarget ( renderTarget : WebGLRenderTarget ) : null

renderTarget - 需要激活的renderTarget(可选)

此方法设置活动的rendertarget。 如果省略该参数,则将画布设置为活动的rendertarget

setScissor ( x : Integer, y : Integer, width : Integer, height : Integer ) : null

将裁剪区域设置为(x,y)到(x + width,y + height)

setScissorTest ( boolean : Boolean ) : null

启用或禁用裁剪测试。 启用此选项后,只有定义的裁剪区域内的像素才会受到其他渲染器操作的影响

setSize ( width : Integer, height : Integer, updateStyle : Boolean ) : null

将输出画布的大小调整为(width,height),并考虑设备像素比率,将视口调整为从(0,0)开始适应该尺寸的大小。 将updateStyle设置为false可防止对输出画布进行任何样式更改

setTexture2D ( texture : Texture, slot : number ) : null

texture - 需要设置的纹理
slot - 指示纹理应使用哪个槽的数字

此方法将正确的纹理设置为WebGL着色器的正确插槽。 可以找到槽号作为采样器的均匀值

setTextureCube ( cubeTexture : CubeTexture, slot : Number ) : null

texture - 需要设置的cubeTexture。
slot - 指示纹理应使用哪个槽的数字。

此方法将正确的纹理设置为WebGL着色器的正确插槽, 可以找到槽号作为采样器的均匀值

setViewport ( x : Integer, y : Integer, width : Integer, height : Integer ) : null
将视口设置为从(x,y)到(x + width,y + height)

WebGLRenderTarget

概念

显卡为后台渲染场景的缓冲区,它用于不同的效果,例如在渲染图像显示在屏幕进行后期处理

使用

1
WebGLRenderTarget(width : Number, height : Number, options : Object)

width – renderTarget的宽度
height – renderTarget的高度
options是可选的对象,保存一个自动生成的目标纹理的纹理参数以及depthBuffer / stencilBuffer布尔值
wrapS - 默认为ClampToEdgeWrapping
wrapT - 默认为ClampToEdgeWrapping
magFilter - 默认为LinearFilter
minFilter - 默认为LinearFilter
format - 默认为RGBAFormat
type - 默认为UnsignedByteType
anisotropy - 默认值为1
encoding - 默认为LinearEncoding
depthBuffer - 默认为true。 如果您不需要,请将此设置为false
stencilBuffer - 默认为true。 如果您不需要,请将此设置为false

属性

width : number

渲染目标的宽度

height : number

渲染目标的高度

scissor : Vector4

渲染目标视口内的矩形区域。 区域外的部分将被裁剪

scissorTest : boolean

是否激活裁剪测试

viewport : Vector4

渲染目标的视口

texture

此纹理实例保存渲染的像素,将其用作输入以进行进一步处理

depthBuffer : boolean

渲染到深度缓冲区。 默认为true

stencilBuffer

渲染到深度缓冲区。 默认为true

depthTexture : DepthTexture

如果设置,则场景深度将呈现给此纹理。 默认值为null

方法

setSize ( width : Number, height : Number ) : null

设置渲染目标的尺寸

clone () : WebGLRenderTarget

创建渲染目标的克隆

copy ( source : WebGLRenderTarget ) : WebGLRenderTarget

采用source中渲染目标的设置到该渲染目标

dispose () : null

调用dispose事件

WebGLRenderTargetCube

概念

使用立方体相机(CubeCamera)对象来作为WebGL渲染器目标(WebGLRenderTarget)

使用

1
WebGLRenderTargetCube(width : Number, height : Number, options : Object)

width – renderTarget的宽度
height – renderTarget的高度
options是可选的对象,保存一个自动生成的目标纹理的纹理参数以及depthBuffer / stencilBuffer布尔值
wrapS - 默认为ClampToEdgeWrapping
wrapT - 默认为ClampToEdgeWrapping
magFilter - 默认为LinearFilter
minFilter - 默认为LinearFilter
format - 默认为RGBAFormat
type - 默认为UnsignedByteType
anisotropy - 默认值为1
encoding - 默认为LinearEncoding
depthBuffer - 默认为true。 如果您不需要,请将此设置为false
stencilBuffer - 默认为true。 如果您不需要,请将此设置为false

属性

activeCubeFace : integer

对应于立方体侧(PX 0,NX 1,PY 2,NY 3,PZ 4,NZ 5),由CubeCamera内部使用和设置

继承

继承自WebGLRenderTarget

方法

继承自WebGLRenderTarget

threejs 解读 scene

Scene

概念

scene用来创建场景

使用:

创建一个scene对象:

1
Scence()

属性

fog

fog实例,定义场景中的雾状背景。默认是null

overrideMaterial

如果不为null,它将使用其材质强制覆盖场景中所有对象。默认为null

autoUpdate

如果是ture,则每一帧自动检测矩阵更新.如果false,则需要手动维护矩阵更新。默认为true

background

如果不为null,则设置渲染场景时使用的背景,并始终先渲染。 可以设置为ColorTextureCubeTexture。 默认为null

方法

toJSON

以JSON格式返回场景数据

Fog

概念

此类包含定义线性雾的参数,即密度随着距离的增加呈线性增长

使用

创建Fog对象:

1
Fog( color : Integer, near : Float, far : Float )

color参数被传递给Color来设置颜色属性,color可以是一个十六进制整数或CSS样式的字符串

属性

name

对象的可选名称(不必是唯一的),默认值为空字符串

color

雾的颜色,例如:如果设置为黑色,远处的物体将被渲染为黑色

near

开始施雾的最小距离。距离当前相机小于near单位的对象,将不会受到雾的影响。默认为1

far

结束施雾的最大距离。距离当前相机大于far单位的对象,将不会受到雾的影响。默认为1000

方法

clone

返回具有与此雾有相同的参数的新雾实例

toJSON

以JSON格式返回线性雾数据

FogExp2

概念

此类包含定义指数雾的参数,即密度随着距离的增加呈指数增长

使用

创建FogExp2对象:

1
2
FogExp2( color : Integer, density : Float )
`

color参数被传递给Color来设置颜色属性,color可以是一个十六进制整数或CSS样式的字符串

属性

name

对象的可选名称(不必是唯一的),默认值为空字符串

color

雾的颜色,例如:如果设置为黑色,远处的物体将被渲染为黑色

density

定义雾密度增加的速度,默认0.00025

方法

clone

返回具有与此雾有相同的参数的新雾实例

toJSON

以JSON格式返回线性雾数据

javascript & ECMAScript & es

JavaScript & ECMAScript & ES2015… & ES6…

JavaScript

JavaScript一种动态类型、弱类型、基于原型的客户端脚本语言,用来给HTML网页增加动态功能

JavaScript由三部分组成

  1. ECMAScript
  2. DOM
  3. BOM

ECMAScript

一个由 ECMA International 进行标准化,TC39 委员会进行监督的语言。通常用于指代标准本身

ECMA
Ecma国际(Ecma International)是一家国际性会员制度的信息和电信标准组织。1994年之前,名为欧洲计算机制造商协会(European Computer Manufacturers Association)。因为计算机的国际化,组织的标准牵涉到很多其他国家,因此组织决定改名表明其国际性。现名称已不属于首字母缩略字。

Ecma国际是一家和企业密切相连的组织,所以 Ecma国际制定的规范都是由各类企业来做主要的制定和推广

TC39
在ECMA国际,每个标准都会有一个 TC 来负责,而一个 TC 中可能会有不同的 TG 来负责不同的工作。而负责 ECMA262,也就是我们所说的 ECMAScript 的就是 TC39(以前叫 TC39-TG1)。
TC(Technical Committees)
TG(Task Groups)

要讲清ECMAScript,回顾历史。
1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。
该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。

ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现

ECMAScript 作为一门脚本程序设计语言标准,并不只有 javascript 这一种实现,它也有很多的方言实现。比如有下面这些语言:

JavaScript

Ejscript

JScript .NET

ActionScript

DMDScript

CriScript

InScript

ES2015…

ES2015
ECMAScript 2015
ECMAScript 的第六版修订,于 2015 年完成标准化。这个标准被部分实现于大部分现代浏览器。

ECMAScript 2016
第七版 ECMAScript 修订,只加了Array.prototype.includes、Exponentiation Operator(求冥运算)

ECMAScript 2017
第八版 ECMAScript 修订
新增
Object.values/Object.entries
字符串填充 padStart()和padEnd()
Object.getOwnPropertyDescriptor
尾随逗号
异步函数async
共享内存和原子操作

ECMAScript 2018
异步迭代
Promise.finally()
Rest/Spread 属性: ES2018为对象解构提供了和数组一样的Rest参数()和展开操作符
正则表达式命名捕获组(Regular Expression Named Capture Groups)
正则表达式反向断言(lookbehind)
正则表达式dotAll模式
正则表达式 Unicode 转义
非转义序列的模板字符串

ECMAScript Proposals
被考虑加入未来版本 ECMAScript标准的特性与语法提案,他们需要经历五个阶段:

stage 名称 描述
Stage 0 strawman(稻草人) 任何人都可以提交pull request到GitHub - tc39/ecma262: Status, process, and documents for ECMA262
Stage 1 Proposal(提议) TC39制定成员作为 champion,TC39审阅通过,有实现的 Demo 或者 Polyfill初步描写标准的语义语法算法复杂度解决的问题等
Stage 2 Draft(草案) 有两个或两个以上的实现(包括babel这类的转译实现)使用正式的语言描述该语法,api等
Stage 3 Candidate(候选) 至少2个实现,可以为实验性实现,ECMAScript spec editor 通过审核,TC39 review 通过,文本编写完成
Stage 4 Finished (完成) 编写 test 262 测试用例,通过两个实现该特性的内核测试,ECMAScript spec editor 通过审核,开发者表示支持和认可

对于有些人来说,前端的更新总是很突兀,很让人迷茫。

但是其实不是的。变化总是一点一点发生的。

GitHub - tc39/proposals: Tracking ECMAScript Proposals

我们可以在 TC39 的 Github 仓库中找到完成了,废弃的,以及正在进行中的提案。

多去关注这些东西,对于很多新事物的到来,我们也就不会有多惊讶了。

其他ECMA标准
和 ECMAScript 有关的标准有 ECMA262,ECMA290,ECMA327,ECMA357,ECMA402,ECMA404,ECMA414等等。

其中290,327,357等等没有推广开来,被废弃。

ECMA 262 是语言规范本身。

ECMA 402 则是制定一些基于 ECMAScript 5 或者之后版本的一些国际化 API 标准。

ECMA 404 是 JSON 规范。

ECMA 414 则规定了哪些规范是和 ECMAScript 有关的。目前内部就包含了 262,402和404。

ES6…

ES ECMAScript
ES6 ECMAScript 2015
ES7 ECMAScript 2016
ES8 ECMAScript 2017
ES9 ECMAScript 2018

ES1:1997 年 6 月  ——  
ES2:1998 年 6 月  ——
ES3:1999 年 12月  ——  
ES4: 2007 年 10月 未通过 ——
ES5: 2009年12月 ——
ES5.1 2011年6月 ——

ES4&ES3.1
在制定ES4的时候,是分成了两个工作组同时工作的。

一边是以 Adobe, Mozilla, Opera 和 Google为主的 ECMAScript 4 工作组。

一边是以 Microsoft 和 Yahoo 为主的 ECMAScript 3.1 工作组。

ECMAScript 4 的很多主张比较激进,改动较大。而 ECMAScript 3.1 则主张小幅更新

最终经过 TC39 的会议,决定将一部分不那么激进的改动保留发布为 ECMAScript 3.1,然后将一部分比较激进的部分放置到 ES.NEXT 中,命名为 Harmony(和谐),留待以后再进行商榷。接下来,ECMAScript 3.1 变成了 ECMAScript 5,而 ES.NEXT 中的那些特性,则有着相当一部分被ECMAScript 6,也就是 ECMAScript 2015 所吸收了。所以说虽然 ECMAScript 4 被废弃了,但是它终究还是通过另一种方式活了下来。

head-meta

使用 HTML5 doctype,不区分大小写

<!DOCTYPE html> 

单一的 zh 和 zh-CN 均属于废弃用法。
问题主要在于,zh 现在不是语言code了,而是macrolang,能作为语言code的是cmn(国语)、yue(粤语)、wuu(吴语)等。
通常建议写成 zh-cmn 而不是光写 cmn,主要是考虑兼容性(至少可匹配 zh),有不少软件和框架还没有据此更新。zh-CN 的问题还在于,其实多数情况下标记的是简体中文,但是不恰当的使用了地区
所以其实应该使用 zh-Hans / zh-Hant 来表示简体和繁体。

<html lang="zh-cmn-Hans">

声明文档使用的字符编码

<meta charset='utf-8'>

优先使用 IE 最新版本和 Chrome

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>

页面描述

<meta name="description" content="不超过150个字符"/>

页面关键词

<meta name="keywords" content=""/>

网页作者

<meta name="author" content="name, email@gmail.com"/>

搜索引擎抓取

<meta name="robots" content="index,follow"/>

为移动设备添加 viewport

<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">

width=device-width 会导致 iPhone 5 添加到主屏后以 WebApp 全屏模式打开页面时出现黑边 http://bigc.at/ios-webapp-viewport-meta.orz

iOS 设备 begin
添加到主屏后的标题(iOS 6 新增)

<meta name="apple-mobile-web-app-title" content="标题">

是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏

<meta name="apple-mobile-web-app-capable" content="yes"/>

添加智能 App 广告条 Smart App Banner(iOS 6+ Safari)

<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">

设置苹果工具栏颜色

忽略页面中的数字识别为电话,忽略email识别

<meta name="format-detection" content="telphone=no, email=no"/>

启用360浏览器的极速模式(webkit)

避免IE使用兼容模式

<meta http-equiv="X-UA-Compatible" content="IE=edge">

不让百度转码

<meta http-equiv="Cache-Control" content="no-siteapp" />

针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓

<meta name="HandheldFriendly" content="true">

微软的老式浏览器

<meta name="MobileOptimized" content="320">

uc强制竖屏

<meta name="screen-orientation" content="portrait">

QQ强制竖屏

<meta name="x5-orientation" content="portrait">

UC强制全屏

<meta name="full-screen" content="yes">

QQ强制全屏

<meta name="x5-fullscreen" content="true">

UC应用模式

<meta name="browsermode" content="application">

QQ应用模式

<meta name="x5-page-mode" content="app">

windows phone 点击无高光

<meta name="msapplication-tap-highlight" content="no">

iOS 图标 begin
iPhone 和 iTouch,默认 57x57 像素,必须有

<link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png"/>

Retina iPhone 和 Retina iTouch,114x114 像素,可以没有,但推荐有

<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/apple-touch-icon-114x114-precomposed.png"/>

Retina iPad,144x144 像素,可以没有,但推荐有

<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144x144-precomposed.png"/>

iOS 图标

iOS 启动画面 begin
iPad 竖屏 768 x 1004(标准分辨率)

<link rel="apple-touch-startup-image" sizes="768x1004" href="/splash-screen-768x1004.png"/>

iPad 竖屏 1536x2008(Retina)

<link rel="apple-touch-startup-image" sizes="1536x2008" href="/splash-screen-1536x2008.png"/>

iPad 横屏 1024x748(标准分辨率)

<link rel="apple-touch-startup-image" sizes="1024x748" href="/Default-Portrait-1024x748.png"/>

iPad 横屏 2048x1496(Retina)

<link rel="apple-touch-startup-image" sizes="2048x1496" href="/splash-screen-2048x1496.png"/>

iPhone/iPod Touch 竖屏 320x480 (标准分辨率)

<link rel="apple-touch-startup-image" href="/splash-screen-320x480.png"/>

iPhone/iPod Touch 竖屏 640x960 (Retina)

<link rel="apple-touch-startup-image" sizes="640x960" href="/splash-screen-640x960.png"/>

iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina)

<link rel="apple-touch-startup-image" sizes="640x1136" href="/splash-screen-640x1136.png"/>

Windows 8 磁贴颜色

<meta name="msapplication-TileColor" content="#000"/>

Windows 8 磁贴图标

<meta name="msapplication-TileImage" content="icon.png"/>

添加 RSS 订阅

添加 favicon icon

sns 社交标签 begin
参考微博API

<meta property="og:type" content="类型" />
<meta property="og:url" content="URL地址" />
<meta property="og:title" content="标题" />
<meta property="og:image" content="图片" />
<meta property="og:description" content="描述" />

sns 社交标签 end

<title>标题</title>

css 杂记(持续补充)

margin

  • 作用
    • 让块元素水平居中
    • 让元素之间留有间距
    • 处理特殊的first,last
    • 布局
  • 要点
    • margin折叠
    • margin百分比
    • margin的auto值
    • margin和相对偏移的异同
    • IE6浮动双margin Bug
    • IE6浮动相邻元素3px Bug

auto

一般auto计算值取决于可用空间

百分比

默认在writing-mode:horizontal-tb和direction:ltr,百分比参照父级的宽度

margin折叠

  • 垂直边毗邻
    • 元素的上外边距和其属于常流中的第一个孩子的上外边距
    • 元素的下外边距和其属于常流中的下一个兄弟的上外边距
    • 属于常流中的最后一个孩子的下外边距和其父亲的下外边距
    • 元素的上下外边距,如果该元素没有建立新的块级格式上下文,且min-height的计算值为0或auto,且没有属于常流中的孩子

IE6浮动双倍margin bug

  • 解决方案
    1. _margin-left:*/2
    2. _display:inline

z-index

  • 元素的层叠级别为整型,描述在相同层叠上下文中元素在z轴上的呈现顺序
  • 同一层叠上下文中,层叠级别大的显示在上,相同层叠级别时,遵循后来居上的原则
  • 不同层叠的上下文中,元素呈现顺序以父级层叠上下文的层叠级别来决定呈现的先后顺序,与自身的层叠级别无关
  • 当定位元素没有显式定义z-index值时,不会创建新的局部层叠上下文
  • 子元素有可能和祖先的兄弟会长祖先兄弟的子元素处在同一个层叠上下文中
  • 当opacity值小于1时,该元素会创建新的局部层叠上下文,
  • 当opacity值小于1时,该元素拥有层叠级别相当于z-index:0或auto,但不能定义z-index,除非本身是定位元素

freemark

FreeMarker

summary

基于模板的,用来生成输出文本的通用工具
适用于MVC模式,分离思想
并非web的应用框架,只是框架中的一个组件,其引擎本身并不知道http协议或者servlet

freemark 模板

  • ${...} interpolations 插值
  • <#> </#> tags 标签 (<@> </@> 自定义标签)
  • <#-- --> comments 注释
  • <table></tabel> directives 指令

指令

if指令

条件
<#if boolean><#else></#if>

list指令

循环
<#list Array as array></#list>

include指令

插入其他文件到当前模板
<#include ""/>

处理不存在的变量

变量不存在时使用default代替

${...}!"default"

使用??和if指令,变量不存在忽略代码段

<#if argument??></if>

argument1.argument2.argument3!0
若argument1或argument2不存在,则模板处理会以“未定义变量”错误停止
通过(argument1.argument2.argument3)!0 方式防止这种错误

用户自定义指令

如果能够实现,用自定义指令而不用函数/方法。
输出(返回值)的是标记(HTML,XML 等)。
主要原因是函数的返回结果可以自动进行 XML 转义
(这是因为${…}的特性),
而用户自定义指令的输出则不是
(这是
因为<@…>的特性所致,它的输出假定为是标记,因此就不再转义)。

转义

特殊字符 原生字符 ${r"${foo}"}

浏览器渲染

从浏览器角度谈渲染

  • 之前更多的优化是从页面资源的数量,传输是否采用了压缩,JS、cSS,是否进行了精简,缓存有没有合理的使用
  • 这次从另一个角度谈页面的渲染,浏览器是如何工作的,要把页面渲染出来,浏览器需要做什么,哪些过程比较耗时
  • 浏览器工作原理浏览器工作原理
    • 加载HTML
    • 解析HTML,生成DOM
    • 加载CSS,JS
    • 解析CSS,生成CSSOM
    • JS引擎执行JS
    • 合并DOM和CSSOM,生成Render Tree
    • 根据Render Tree 进行布局
    • 绘制每个层中的元素
    • 合并图层
  • 方案:加快完成DOM+CSSOM-Layout-Paint-Composite的整个过程
    • 分割css
      对不同的浏览终端,同一终端的不同模式,提供不同的规则(通俗讲屏幕大小和宽高比)把媒体查询放在link上,根据终端情况加载不同的css文件
  • css规则的优先级
    css权重计算的无形增加
    css选择器解析从右往左还是从左往右??
    过多的嵌套规则,会导致复杂的,无必要的深层次规则(SASS,LESS开发过程中尤为明显)
    css规则越复杂,构建Render Tree时,浏览器花费的时间越长
  • 使用GPU加速
    很多的动画定时的执行,会导致浏览器的重新布局

          @keyframes my {
         20% {
          top: 10px;
          }
    
      50% {
          top: 120px;
      }
    
      80% {
          top: 10px;
      }
    } 
    

    这些执行可以放到GPU加速执行

     @keyframes my {
      20% {
          transform: translateY(10px);
      }
    
      50% {
          transform: translateY(120px);
      }
    
      80% {
          transform: translateY(10px);
      }
    }
    
jQuery 不能避免 layout thrashing (有人喜欢将其翻译为“布局颠簸”,会导致多余relayout/reflow),因为它的代码不仅仅用于动画,它还用于很多其他场景。 

jQuery的内存消耗较大,经常会触发垃圾回收。而垃圾回收触发时很容易让动画卡住。

jQuery使用了setInterval而不是 reqeustAnimationFrame(RAF),因为 RAF 会在窗口失去焦点时停止触发,这会导致jQuery的bu    
**setTimeOut和FAF(单人淋浴间和大澡堂)**    

var startingTop = 0;
        setInterval(function() {
            element.style.top = (startingTop += 1/60);
        }, 16);


        function tick () {
            element.style.top = (startingTop += 1/60);
        }
        window.requestAnimationFrame(tick);


requestAnimationFrame
setTimeout间隔设置过小,显示器16.7ms刷新间隔之前发生了其他绘制请求(setTimeout),导致所有第三帧丢失,继而导致动画断续显示(堵车的感觉),这就是过度绘制带来的问题。不仅如此,这种计时器频率的降低也会对电池使用寿命造成负面影响,并会降低其他应用的性能。

而requestAnimationFrame就是为了这个而出现的。所做的事情很简单,跟着浏览器的绘制走,如果浏览设备绘制间隔是16.7ms,那我就这个间隔绘制;如果浏览设备绘制间隔是10ms, 我就10ms绘制。这样就不会存在过度绘制的问题,动画不会掉帧

优势:向下兼容 、相比于css3动画应用更广、动画效果更多

CSS transition 的动画逻辑是由浏览器来执行,所以它的性能能够比 jQuery 动画好。它的优势体现在:

通过优化 DOM 操作,避免内存消耗来减少卡顿
使用与 RAF 类似的机制
强制使用硬件加速 (通过 GPU 来提高动画性能)

  • 异步JavaScript
    js执行会阻塞DOM构建的过程,Js中可能存在dom操作 async异步

    js可能会不断的重新布局,重新绘制

    1.访问元素的某些属性  
    2.通过JavaScript修改元素的CSS属性  
    3.在onScroll中做耗时的任务  
    4.在其他Event Handler中做耗时的任务  
    5.图片的预处理  
    6.过多的动画  
    7.过多的数据处理  
    

    元素的一些属性和方法,当被访问或调用的时候,会触发浏览器的布局和绘制,布局基本上会影响页面的大部分元素,导致耗时长

    为了避免之前提到的布局颠簸,我们需要批量访问和更新DOM。

        var currentTop,
        currentLeft;
    /* 有 layout thrashing. */
    currentTop = element.style.top; /* 访问 */
    element.style.top = currentTop + 1; /* 更新 */
    
    currentLeft = element.style.left; /* 访问 */
    element.style.left = currentLeft + 1; /* 更新 */
    
    /* 没有 layout thrashing. */
    currentTop = element.style.top; /* 访问 */
    currentLeft = element.style.left; /* 访问 */
    
    element.style.top = currentTop + 1; /* 更新 */
    element.style.left = currentLeft + 1; /* 更新 */
    

    计算offset 时,浏览器需要重新计算(重新布局),然后才能返回最新的值

           for(var i = 0; i < list.length; i++) {
      list[i].style.width = parent.offsetWidth + 'px';
    }   
    
var parentWidth = parent.offsetWidth;
for(var i = 0; i < list.length; i++) {
  list[i].style.width = parentWidth + 'px';
}
  • css样式修改
  • 修改布局相关属性,会触发Layout-Paint-Composite
  • 修改绘制相关属性,会触发Paint-Composite
  • 其他属性,某些特别属性可在不同层中单独绘制,在合并图层,就是直接Composite (transform,opacity)

    在绑定 scroll 、resize 这类事件时,当它发生时,它被触发的频次非常高,如果事件中涉及到大量的位置计算、DOM 操作、元素重绘等工作且这些工作无法在下一个 scroll 事件触发前完成,就会造成浏览器掉帧。加之用户鼠标滚动往往是连续的,就会持续触发 scroll 事件导致掉帧扩大、浏览器 CPU 使用率增加、用户体验受到影响。

    类比电梯

    // 防抖动函数
    

    function debounce(func, wait, immediate) {

    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
    

    };

    var myEfficientFn = debounce(function() {

    // 滚动中的真正的操作
    

    }, 250);

    // 绑定监听

    window.addEventListener(‘resize’, myEfficientFn);

       // 简单的节流函数
    function throttle(func, wait, mustRun) {
        var timeout,
            startTime = new Date();
    
        return function() {
            var context = this,
                args = arguments,
                curTime = new Date();
    
            clearTimeout(timeout);
            // 如果达到了规定的触发时间间隔,触发 handler
            if(curTime - startTime >= mustRun){
                func.apply(context,args);
                startTime = curTime;
            // 没达到触发间隔,重新设定定时器
            }else{
                timeout = setTimeout(func, wait);
            }
        };
    

    };
    // 实际想绑定在 scroll 事件上的 handler
    function realFunc(){

    console.log("Success");
    

    }
    // 采用了节流函数
    window.addEventListener(‘scroll’,throttle(realFunc,500,1000));

pointer-events: none 可用来提高滚动时的帧频。的确,当滚动时,鼠标悬停在某些元素上,则触发其上的 hover 效果,然而这些影响通常不被用户注意,并多半导致滚动出现问题。

will-change 为 web 开发者提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器可以在元素属性真正发生变化之前提前做好对应的优化准备工作。 这种优化可以将一部分复杂的计算工作提前准备好,使页面的反应更为快速灵敏。

类比萨里机长

值得注意的是,用好这个属性并不是很容易:

不要将 will-change 应用到太多元素上:浏览器已经尽力尝试去优化一切可以优化的东西了。有一些更强力的优化,如果与 will-change 结合在一起的话,有可能会消耗很多机器资源,如果过度使用的话,可能导致页面响应缓慢或者消耗非常多的资源。

不要过早应用 will-change 优化:如果你的页面在性能方面没什么问题,则不要添加 will-change 属性来榨取一丁点的速度。 will-change 的设计初衷是作为最后的优化手段,用来尝试解决现有的性能问题。它不应该被用来预防性能问题。过度使用 will-change 会导致大量的内存占用,并会导致更复杂的渲染过程,因为浏览器会试图准备可能存在的变化过程。这会导致更严重的性能问题。

给它足够的工作时间:这个属性是用来让页面开发者告知浏览器哪些属性可能会变化的。然后浏览器可以选择在变化发生前提前去做一些优化工作。所以给浏览器一点时间去真正做这些优化工作是非常重要的。使用时需要尝试去找到一些方法提前一定时间获知元素可能发生的变化,然后为它加上 will-change 属性。

Unable to preventDefault inside passive event listener due to target being treated as passive

window.addEventListener(“touchstart”, func, {passive: true} );

window, document , body

浏览器与内核

Trident

IE内核
IE9 开始用 Chakra,这两个版本区别很大,Chakra 无论是速度和标准化方面都很出色

国内很多的双核浏览器的其中一核便是 Trident

Window10 发布后,IE 将其内置浏览器命名为 Edge,Edge 最显著的特点就是新内核 EdgeHTML

Gecko

Firefox 内核

Webkit

safari
早期chrome

chrome
chromium fork 自开源引擎 webkit

Presto

早期oprea

关于移动端

移动端的浏览器内核主要说的是系统内置浏览器的内核。

目前移动设备浏览器上常用的内核有 Webkit,Blink,Trident,Gecko 等,其中 iPhone 和 iPad 等苹果 iOS 平台主要是 WebKit,Android 4.4 之前的 Android 系统浏览器内核是 WebKit,Android4.4 系统浏览器切换到了Chromium,内核是 Webkit 的分支 Blink,Windows Phone 8 系统浏览器内核是 Trident。

跨域

什么是跨域

协议,域名,端口任何一项不同都会引起跨域问题
注意: 下面讨论的解决方案都是针对于域名引起的跨域的,协议和端口的跨域前端无能为力

跨域解决方案

1.document.domain + iframe

只有主域相同才能使用

//parent.domain.com/a.html
document.doman = 'domain.com'
var ifr = document.createElement('iframe')
ifr.src = 'child.domain.com/b.html'
ifr.display = none;
document.body.appendChild(ifr);
ifr.onload = function () {
    var doc = ifr.contentDocument || ifr.contentWindow.document
    //doc 
     ifr.onload = null;
}

//child.domain.com/b.html
document.domain = 'domain.com'

2.动态创建script

function loadScript(url, func) {
  var head = document.head || document.getElementByTagName('head')[0];
  var script = document.createElement('script');
  script.src = url;

  script.onload = script.onreadystatechange = function(){
    if(!this.readyState || this.readyState=='loaded' || this.readyState=='complete'){
      func();
      script.onload = script.onreadystatechange = null;
    }
  };

  head.insertBefore(script, null);
}
window.baidu = {
  sug: function(data){
    console.log(data);
  }
}
loadScript('http://suggestion.baidu.com/su?wd=w',function(){console.log('loaded')});    

3.loaction.hash+ iframe

    //a.com/a.html
function startRequest(){
    var ifr = document.createElement('iframe');
    ifr.style.display = 'none';
    ifr.src = 'http://b.com/b.html#paramdo';
        document.body.appendChild(ifr);
}

function checkHash() {
    try {
        var data = location.hash ? location.hash.substring(1) : '';
        if (console.log) {
            console.log('Now the data is '+data);
        }
    } catch(e) {};
}
setInterval(checkHash, 2000);


//b.com/b.html
//模拟一个简单的参数处理操作
switch(location.hash){
case ‘#paramdo’:
callBack();
break;
case ‘#paramset’:
//do something……
break;
}

function callBack(){
    try {
        parent.location.hash = 'somedata';
    } catch (e) {
        // ie、chrome的安全机制无法修改parent.location.hash,
        // 所以要利用一个中间的cnblogs域下的代理iframe
        var ifrproxy = document.createElement('iframe');
        ifrproxy.style.display = 'none';
        ifrproxy.src = 'http://a.com/c.html#somedata';    // 注意该文件在"a.com"域下
        document.body.appendChild(ifrproxy);
    }
}    


//http://a.com/c.html
parent.parent.location.hash = self.location.hash.substring(1);

4.window.name + iframe

window.name :name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)

    //a.com/a/html
            function proxy(url,func) {
    var isFirst = true;
    var ifr = document.createElement('iframe');
    loadFunc = function() {
        console.log(1,isFirst)
        if(isFirst) {
            ifr.src = 'a.com/cs1.html';
            isFirst = false;
        } else {
            console.log('name',ifr.contentWindow.name)
            func(ifr.contentWindow.name);
            document.body.removeChild(ifr);
            ifr.src = null;
            ifr = '';
        }

    }
     ifr.src = url;
    ifr.style.display = 'none';
    if(ifr.attachEvent){ ifr.attachEvent('onload', loadFunc);
}else {ifr.onload = loadFunc;}
     document.body.appendChild(ifr);
}

 proxy('http://www.baidu.com/', function(data){
      console.log('data',data);
    });

5. postMessage

a.com/index.html中的代码:
<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
    window.onload = function() {
    var ifr = document.getElementById('ifr');
       var targetOrigin = 'http://b.com';
     // 若写成'http://b.com/c/proxy.html'效果一样
      // 若写成'http://c.com'就不会执行postMessage了
       ifr.contentWindow.postMessage('I was there!', targetOrigin);
};
</script>

//b.com/index.html
window.addEventListener('message', function(event){
        // 通过origin属性判断消息来源地址
        if (event.origin == 'http://a.com') {
            alert(event.data);    // 弹出"I was there!"
            alert(event.source);  
            // 对a.com、index.html中window对象的引用
            // 但由于同源策略,这里event.source不可以访问window对象
        }
    }, false);

6.CORS

7.JSONP

    function handleResponse(response){
    console.log('The responsed data is: '+response.data);
}
var script = document.createElement('script');
script.src = 'http://www.baidu.com/json/?callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);
/*handleResonse({"data": "zhe"})*/
//原理如下:
//当我们通过script标签请求时
//后台就会根据相应的参数(json,handleResponse)
//来生成相应的json数据(handleResponse({"data": "zhe"}))
//最后这个返回的json数据(代码)就会被放在当前js文件中被执行
//至此跨域通信完成

8.web socket

flex & grid 布局

Flex

背景

布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

flex布局

  • 容器的声明
    Flex是Flexible Box的缩写,意为”弹性布局”
    任何容器,我们均可以将它指定为flex布局,行内元素也可以使用Flex布局,Webkit内核的浏览器,必须加上-webkit前缀
    设为Flex布局以后,子元素的float、clear和vertical-align属性将失效
  .box{
    display:flex;
    }


  .box{  
  display:inline-flex;
  }

  .box{
  display:-webkit-flex;
  display:flex;
}

概念


采用flex布局的元素,称为flex容器(flex container)。它的所有子元素自动成为容器成员,称为flex项目(flex item)
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。 项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size

容器的属性

  1. flex-direction
    该属性决定主轴的方向

         .box {
      flex-direction: row | row-reverse | column | column-reverse;
    }
    

  2. flex-wrap
    如果一条轴线排不下,如何换行

    .box{
         flex-wrap: nowrap | wrap | wrap-reverse;
       }
    

    nowrap为默认值,代表不换行。
    wrap代表换行,但默认为第一行在上方。
    wrap-reverse代表换行,但默认为第一行在下方。

  3. flex-flow
    flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
 .box {
  flex-flow: <flex-direction> || <flex-wrap>;
}
  1. justify-content
    justify-content属性定义了项目在主轴上的对齐方式。

       .box {
      justify-content: flex-start | flex-end | center | space-between | space-around;
    }
    

    flex-start为默认值,代表项目在主轴上向起始方向对齐
    flex-end代表项目在主轴上向结束方向对齐
    center代表项目在主轴上居中对齐
    space-between代表项目在主轴上两端对齐,但第一个项目在主轴的起始位置,最后一个项目在主轴的结束位置
    space-around代表项目在主轴上等分间距,但第一个项目与最后一个项目距离主轴的两端保持一定的距离,这个距离为项目之间间距的1/2

  2. align-items
    align-items属性定义项目在交叉轴上如何对齐。

    .box {
      align-items: flex-start | flex-end | center | baseline | stretch;
    }
    


    flex-start代表项目在交叉轴上向起始方向对齐。
    flex-end代表项目在交叉轴上向结束方向对齐。
    center代表项目在交叉轴上居中对齐。
    baseline代表项目在交叉轴上向项目的第一行文字的基线对齐。
    stretch代表项目在交叉轴上拉伸对齐。

  3. align-content
    align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

    .box {
      align-content: flex-start | flex-end | center | space-between | space-around | stretch;
    }
    

    flex-start:与交叉轴的起点对齐。
    flex-end:与交叉轴的终点对齐。
    center:与交叉轴的中点对齐。
    space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
    space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
    stretch(默认值):轴线占满整个交叉轴。

项目的属性

  1. order
    order属性定义项目的排列顺序,数值越小,排列越靠前,默认为0

      .item {
      order: <integer>;
    }
    

2.flex-grow
flex-grow定义了项目的放大比例。如果所有伸缩项目的flex-grow设置了1,那么每个伸缩项目将设置为一个大小相等的剩余空间。如果你给其中一个伸缩项目设置了flex-grow值为2,那么这个伸缩项目所占的剩余空间是其他伸缩项目所占剩余空间的两倍。

ps:负值对该属性无效。

.item {
    flex-grow: <number>; /* default 0 */
}

  1. flex-shrink
    类似于flex-grow,flex-shrink定义了项目的缩小比例。其默认值为1

如果所有项目的flex-shrink都为1,当空间不足时,都将等比例缩小

如果所有项目都为1,但其中一个项目的flex-shrink为0,即代表空间不足时,该项目缩小0倍,即为不缩小

ps:负值对该属性不起作用。

  1. flex-basis
    flex-basis定义了在分配多余空间之前,项目占据的主轴空间。览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

      .item {
        flex-basis: <length> | auto; /* default auto */
    }
    

利用flex-basis,我们可以很容易实现页面布局中的常见问题:两栏/三栏布局

    <div class="box">
    <div class="left">left</div>
    <div class="main">main</div>
</div>


        .box {
    display: flex;
    height: 200px;
        }
        .left {
            background-color: yellow;
            flex-basis: 200px;
    /* flex-basis定义该项目在分配主轴空间之前提前获得200px的空间 */
            flex-grow: 0;
            /* flex-grow定义该项目不分配剩余空间 */
        }
        .main {
            background-color: green;
            flex-grow: 1;
            /* flex-grow定义main占满剩余空间 */
        }

5.flex
flex是flex-grow、flex-shrink和flex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
    flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
  1. align-self
    align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

Grid

概念

grid 布局。是一个基于网格的二维布局系统。grid是第一个专门为了解决那些我们一直使用 hack 手段而导致的页面布局问题而创建的CSS模块。
一个grid容器的内容:

  • 可以将应用程序分割成不同的空间
  • 可以定义子项的大小、位置以及层级。
  • 与表格类似的是:可以让Web设计师根据元素按列或行对齐排列。
  • 可以定位自己的位置,这样他们可以重叠和类似元素定位。
  • 可以通过结合CSS的媒体查询属性,根据不同的设备和可用空间调整元素的显示风格与定位,而不需要去改变文档结构的本质内容

浏览器支持

采用grid布局的元素,称为grid容器(grid container)。它的所有子元素自动成为容器成员,称为grid项目(grid item)。

分隔的线组成了网格的结构。它们可以是垂直的(“列网格线”)或者水平的(“行网格线”),也可以在行或列的任一边。下面的例子中黄色的线是一个列网格线的例子。
网格线
每条网格线具有默认的编号,从左到右和从上到下分别为1,2,3……

网格单元
网格单元是指两根毗邻的行网格线和列网格线中间的位置,它是一个单独的网格“单元”,如图所示,网格单元是指第 1 和 2 根行网格线和第 2 和 3 根列网格线中间的位置。

网格轨迹
网格轨迹是指两根毗邻线中间的位置,可以认为是网格的行或者列

网格区域
网格区域是指 4 根网格线包围的空间,一个网格空间可能由任意数量的网格单元构成

容器的属性

  1. disaplay
    display属性定义了一个网格容器,容器是展现为行内或块状由所给定的值而决定,此时,他的所有子元素进入grid文档流,称为grid项目

    .box {
        display: grid | inline-grid | subgrid;
    }
    

    grid定义了一个网格容器,它以块级元素的形式显示
    inline-grid定义了一个网格容器,它以内联元素的形式显示
    subgrid定义了一个网格容器,这个网格容器是其父级网格容器的一个子项。它的行和列的大小从父级网格容器中获取

  2. grid-template-columns | grid-template-rows
    grid-template-rows和grid-template-columns定义了一个网格的列数、行数以及网格的大小。

    .box {
            grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
            grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
        }
    

    定义网格单元的宽高,其单位可以是一个长度(如px、em、rem、vw、vh)或百分比,也可以是网格中自由空间的份数(单位为fr)
    定义网格线的名称,它不是必须值。可以一个你选择的任意名字,当没有显示设定时,它的名字以数字表示。

    .box {
        grid-template-columns: 40px 50px auto 50px 40px;
        grid-template-rows: 25% 100px auto;
    }
    

    .box {
        grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
        grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
    }
    

一根网格线可以有多个名字,例如在下面的例子中第二根线有两个名字:row1-end 和 row2-start,命名方式以空格来作为间隔。

.box{
    grid-template-rows:[row1-start] 25% [row1-end row-start] 25% [row-end];
    }

定义了容器的重复部分,你可以使用CSS的repeat()方法来生成多个相同值:

.box {
    grid-template-columns: repeat(3, 20px [col-start]) 5%;
}

.box {
    grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}

fr是一个特殊的单位,它可以类似于设定flex-grow时,给网格容器中的自由空间设置为一个份数,举个例子,下面的例子将把网格容器的每个子项设置为三分之一

.box {
    grid-template-columns: 1fr 1fr 1fr;
}

也是类似于flex-grow,自由空间是在固定子项确定后开始计算的(这里就如同flex-basis提前给予宽高那样),在下面的例子中自由空间是fr单位的总和但不包括50px:
.box {
grid-template-columns: 1fr 50px 1fr 1fr;
}

  1. grid-template-areas
    grid-template-areas可以配合gird-area定义一个显示的网格区域。
    grid-template-areas定义网格区域,然后使用grid-area调用声明好的网格区域名称来放置对应的网格项目

     <section class="grid">
        <div class="title">title</div>
        <div class="nav">nav</div>
        <div class="main">main</div>
        <div class="aside">aside</div>
        <div class="footer">footer</div>
    </section>  
    .grid {
            display: grid;
            grid-template-columns: 100px 100px 100px 100px 100px;
            grid-template-rows: 100px 100px 100px 100px;
            grid-template-areas: 'title title title title aside'
                                  'nav main main main aside'
                                  'nav main main main aside'
                                  'footer footer footer footer footer';
            font-size: 30px;
            text-align: center;
        }
        .title {
            grid-area: title;
            background-color: blue;
        }
        .nav {
            grid-area: nav;
            background-color: yellow;
        }
        .main {
            grid-area: main;
            background-color: gray;
        }
        .aside {
            grid-area: aside;
            background-color: green;
        }
        .footer {
            grid-area: footer;
            background-color: pink;
        }
    

  2. grid-column-gap|grid-row-gap
    grid-column-gap和grid-row-gap定义了网格之间的间距

       .box {
        grid-template-columns: 100px 50px 100px;
        grid-template-rows: 80px auto 80px;
        grid-column-gap: 10px;
        grid-row-gap: 15px;
    }
    

5.justify-items
justify-items定义了网格子项的内容和列轴对齐方式,即水平方向上的对齐方式

.box {
    justify-items: start | end | center | stretch;
}

start代表内容和网格区域的左边对齐
end代表内容和网格区域的右边对齐
center代表内容和网格区域的中间对齐
stretch为默认值,代表填充整个网格区域的宽度

  1. align-items
    类似于justify-items,align-items定义了网格子项的内容和行轴对齐方式,即垂直方向上的对齐方式。

     .box {
        align-items: start | end | center | stretch;
    }
    

start代表内容和网格区域的上边对齐
end代表内容和网格区域的下边对齐
center代表内容和网格区域的中间对齐
stretch为默认值,代表填充整个网格区域的高度

  1. justity-content|align-content
    justify-content属性定义了网格和网格容器列轴对齐方式

      .box {
        justify-content|align-content: start | end | center | stretch | space-around | space-between | space-evenly;
    }
    

    start代表网格在网格容器(左|上)边对齐
    end代表网格在网格容器(右|下)边对齐
    center代表网格在网格容器中间对齐
    stretch改变网格子项的容量让其填充整个网格容器宽度
    space-around代表在每个网格子项中间放置均等的空间,在始末两端只有一半大小
    space-between代表在每个网格子项中间放置均等的空间,在始末两端没有空间
    space-evenly代表在每个网格子项中间放置均等的空间,包括始末两端

  2. grid-auto-columns|grid-auto-rows
    grid-auto-columns与grid-auto-rows可以指定隐式网格。

       <div class="grid">
        <div class="box1">box1</div>
        <div class="box2">box2</div>
        <div class="box3">box3</div>
        <div class="box4">box4</div>
    </div>
          .grid {
            display: grid;
            grid-template-columns: 200px;
            grid-template-rows: 200px;
            text-align: center;
            font-size: 30px;
        }
        .box1 {
            background-color: pink;
            grid-column: 1;
            grid-row: 1;
        }
        .box2 {
            background-color: yellow;
            grid-column: 2;
            grid-row: 1;
        }
        .box3 {
            background-color: gray;
            grid-column: 1;
            grid-column: 2;
        }
        .box4 {
            background-color: blue;
            grid-column: 2;
            grid-row: 2;
        }
    


通过grid-auto-columns与grid-auto-rows属性,创建一个隐式的2×2的网格

grid-auto-columns: 300px;
grid-auto-rows: 300px;

  1. grid-auto-flow
    grid布局自身具有的自动布局算法会将网格子项自动放置起来,而grid-auto-flow属性控制自动布局算法如何工作

    .box {
     grid-auto-flow: row | column | row dense | column dense
    

    }

row为默认值,代表自动布局算法在每一行中依次填充,只有必要时才会添加新行。
column代表自动布局算法在每一列中依次填充,只有必要时才会添加新行。
dense代表告诉自动布局算法如果更小的子项出现时尝试在网格中填补漏洞。
10 grid
grid为以下属性的合并写法:grid-template-rows,grid-template-columns,grid-template-areas,grid-auto-rows,grid-auto-columns,grid-auto-flow。它也可以设置grid-column-gap和grid-row-gap。

.box {
    grid: none | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]];
}