目录
一、CSS的position
static | 默认值。 没有定位,元素出现在正常的流中。 忽略 top, bottom, left, right, z-index 声明。 如果相邻的static元素都用margin设置了外边距,最终两个元素块会根据更大的外边距共享一块外边距。 |
relative | 生成相对定位的元素,相对于其正常位置进行定位。 可以使用lrtb和z-index进行偏移。 不会离开文档流。 |
absolute | 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。 脱离常规的文档流。 元素的位置通过 ltrb 属性进行偏移,z-index设置堆叠顺序。 如果找不到符合条件的父元素,会根据 标签进行定位。如果lrtb设置为auto,会回到常规文档流的位置(类似于relative),但和relative不同的是1. 不会撑开父元素的高度,可能发生高度坍塌;2. 和相邻元素的margin不会取最大值,而是两者的margin之和。 |
fixed | 生成绝对定位的元素,相对于浏览器窗口进行定位。 脱离常规的文档流。 元素的位置通过 ltrb 属性进行偏移,z-index设置堆叠顺序。 元素不会随着视窗滚动而跟着一期滚动,会固定在一个位置。 |
inherit | 规定应该从父元素继承 position 属性的值。 |
写个小demo试一下四种常用的定位:
- 三个蓝框采用relative相对定位,高度宽度固定,顺序排列。
- 第一个蓝框内的三个块级元素采用static定位,没有偏移。
- 第一个蓝框内的右侧两个块级元素采用绝对定位,相对于父元素相对定位的蓝框进行定位,不在正常的文档流中,上面的绝对定位元素设置z-index为-1,因此展示在static绝对定位框的下方。
- 右侧的红色框采用fixed绝对定位,相对于视图进行定位,即使向下滚动也不会随着父元素的蓝框向下移动。
- 第二个蓝框内的三个块级元素采用relative相对定位,可以通过设置lrtb进行偏移。
- 第三个蓝框内四个块级元素使用static和relative定位,每两个块级元素的margin取两者margin的最大值。
源代码贴一下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>position</title>
<style>
body {
margin: 0;
}
.block-static {
width: 200px;
height: 96px;
background-color: coral;
border: 2px solid black;
position: static;
}
.block-abs {
width: 200px;
height: 96px;
border: 2px solid blue;
background-color: greenyellow;
text-align: center;
position: absolute;
left: 150px;
bottom: 5px;
}
.block-fix {
width: 200px;
height: 100px;
border: 2px solid blue;
background-color: chocolate;
position: fixed;
top: 30px;
left: 600px;
}
.block-rea {
width: 200px;
height: 96px;
background-color: aquamarine;
border: 2px solid black;
position: relative;
left: 50px;
}
.father-block-rea {
width: 500px;
height: 300px;
border: 2px solid blue;
position: relative;
}
</style>
</head>
<body>
<div class="father-block-rea">
<div class="block-static">static默认定位:处于文档流中的正常位置,无法偏移</div>
<div class="block-static">static默认定位</div>
<div class="block-static">static默认定位</div>
<div class="block-fix">fix绝对定位:相对于浏览器窗口进行绝对定位</div>
<div class="block-abs" style="top: 50px; z-index: -1;">absolute绝对定位</div>
<div class="block-abs">absolute绝对定位:相对第一个非static的父元素绝对定位,脱离文档流</div>
</div>
<div class="father-block-rea">
<div class="block-rea">relative相对定位:相对于文档流中正常的位置进行定位</div>
<div class="block-rea">relative相对定位</div>
<div class="block-rea">relative相对定位</div>
</div>
<div class="father-block-rea" style="height: 500px">
<div class="block-static" style="margin: 10px">static默认定位</div>
<div class="block-static" style="margin: 20px">static默认定位</div>
<div class="block-rea" style="margin: 10px">relative相对定位</div>
<div class="block-rea" style="margin: 20px">relative相对定位</div>
</div>
<div class="father-block-rea">
</div>
</body>
</html>
二、 JavaScript闭包与作用域
1. js的作用域
js的作用域分为全局作用域、函数作用域和块级作用域(ES6新增)。
全局作用域:window。
块级作用域:“{}”包含的区域,定义在块级作用域内部的变量let和常量const只能在块级作用域内部使用,而使用var时不存在块级作用域的概念,会出现变量提升。
函数作用域:变量在声明它们的函数体内部以及函数体内部嵌套的其他函数体内具有定义。
2. 函数作用域和作用域链
作用域链:在一个函数体内嵌套了多层函数体,多层嵌套的函数体定义了同名的变量,但函数访问变量时,便会形成作用域链。当需要寻找某个变量的作用域链,则沿着变量被调用的位置向外寻找直到全局作用域,经过的每个函数作用域形成的链就是作用域链。
3. 箭头函数和普通函数的作用域
箭头函数:箭头函数无法形成函数作用域,因此箭头函数的函数作用域等于父级的函数作用域,this绑定的是父级的this。因此在寻找变量的作用域链时,应当跳过箭头函数。
4. this关键字
在函数中,this关键字指向的是当前函数的所有者对象,this在函数运行时才能确定其具体的指向。严格模式下没有调用方的函数的this不能指向window。
严格模式下的this:
var a = 20;
function fn( ) {
'use strict';
var a = 1;
var obj = {
a: 10,
c: this.a + 20
}
return obj.c;
}
console.log(fn());
console.log(window.fn())
严格模式下,this指向undefined,undefined.a报错。如果使用window调用,则能正确输出40。
5. var的变量提升
var的定义是在函数作用域内的,因此如果在if或while等内部定义的var实际是是在最近的函数作用域内部的。var的变量提升即变量可以在声明之前使用,值为undefined。
var bar = 1;
function test(){
console.log(bar); //undefined
var bar = 2;
console.log(bar); //2
}
test();
test内第一次输出bar时,由于var的变量提升,因此输出undefined;第二次bar已经赋值完成,输出2.
6. 未声明变量
js中直接初始化,没有使用var,let,const等关键字声明的变量,会按照作用域链向上寻找,对找到的变量进行赋值,如果一直到全局作用域都没找到,则在window初始化变量并赋值。
function func() {
a = 1;
var c = b = 2;
}
func();
console.log(a); //1
console.log(b); //2
console.log(window.c); //undefined
console.log(c); //Uncaught ReferenceError
a没有声明,形如“c = b = 2 ”这种连续赋值的定义表达式,后面的变量都未声明,都需要沿作用域链寻找赋值。
function fn() {
window.a = 20;
a = 30;
var a;
console.log(a); //30
console.log(this.a); //20
}
fn();
a没有声明,但下方有var a,因此a会变量提升,所以a=30赋值时修改的是下方函数内部的a变量,不会修改外层的window中a变量。
7. 一些相关的代码示例
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()()); // "The Window"
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); // "My Object"
第一个输出的object.getNameFunc()返回的是一个匿名函数,匿名函数执行的调用者是window,因此this指向的也是window,输出的是window的name。
第二个输出的匿名函数返回的是that.name,判断that的作用域链为:匿名函数-》getNameFunc -》window,因此在getNameFunc找到that,为getNameFunc函数的this,getNameFunc的调用者为object,因此this指向object,输出就位object的name。
inner = 'window'; function say() { console.log(inner); console.log(this.inner); } var obj1 = (function() { var inner = '1-1'; return { inner: '1-2', say: function() { console.log(inner); console.log(this.inner); } }; })(); say(); //window window obj1.say(); //1-1 1-2 obj1.say = say; obj1.say(); //window 1-2
三、flex布局
容器属性:
flex-direction: 主轴方向(横排列还是数排列)row横排列,row-reverse横排列倒序,column竖排列,column-reverse竖排列倒序。默认row横排列。
flex-wrap: 换行设置。nowrap不换行,wrap换行,wrap-reverse换行 行倒序排列。默认nowrap不换行。
flex-flow: 主轴方向+换行设置简写。默认row nowrap。
justify-content: 主轴对齐方式。flex-start向开始方向对齐;flex-end结束方向对齐;center居中对齐;space-between两端对齐,项目之间间隔相等,两侧无间隔;space-around:每个项目两侧有固定边距,所以两边有单倍边距,每两个项目中间是双倍边距。默认flex-start。
align-items: 交叉轴对齐方式。flex-start向交叉轴开始方向对齐;flex-end向交叉轴结束方向对齐;center居中对齐;baseline根据项目的第一行文字对齐;stretch如果项目未设置高度或设置为auto则项目充满整个交叉轴的高度。
align-content: 多根轴线的对齐方式,如果只有一根轴线,不起作用。flex-start向开始方向对齐;flex-end结束方向对齐;center居中对齐;space-between两端对齐,项目之间间隔相等,两侧无间隔;space-around:每个项目两侧有固定边距,所以两边有单倍边距,每两个项目中间是双倍边距。stretch:轴线占满整个交叉轴。
align-content会在换行设置为wrap或wrpa-reverse导致出现多根主轴时起作用,如果align-content未设置,默认为stretch,但会被align-items影响,因此如果设置为换行要设置好配置。
项目属性:
order: 自定义项目的顺序,不设置默认都为0,从0开始越小越排在前面。
flex-grow: 放大比例(主轴存在剩余空间时等比放大)
flex-shrink: 缩小比例(主轴不够用时,元素等比例缩小,数值越大缩小的越多,不同项目缩小的像素和设置的比例成正比,当项目内部有最小高度或宽度时,缩小到最小高度或宽度就不会再缩小)
flex-basis: 如果主轴有剩余空间,将根据这个属性来为项目分配多余的主轴空间。如果因为使用项目的flex-basis大小而导致主轴空间不够用,又会根据flex-shrink来等比例缩小项目。
flex: 三个有关缩小放大的属性的综合,默认为不放大,等比缩小:0 1 auto;有两个快捷键,分别是auto(1 1 auto) none(0 0 auto)
align-self: 设置单个项目自己的对齐方式,覆盖容器的align-items属性。默认为auto,表示继承父元素容器的align-items属性;flex-start向交叉轴开始方向对齐;flex-end向交叉轴结束方向对齐;center居中对齐;baseline根据项目的第一行文字对齐;stretch如果项目未设置高度或设置为auto则项目充满整个交叉轴的高度。
写一个小demo试一下:
附上源代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>flex</title>
</head>
<style>
.parent{
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
align-content: flex-start;
width:300px;
height:300px;
background: rgb(33, 46, 228);
}
.parent .child {
color: black;
width: 50px;
flex: auto;
}
</style>
<body>
<div class="parent">
<div class="child" style="order: 1; background-color: antiquewhite;">item1</div>
<div class="child" style="order: 2; background-color: aqua;">item2</div>
<div class="child" style="order: 4; background-color: chartreuse;">item3</div>
<div class="child" style="order: 3; background-color: coral;">item4</div>
</div>
</body>
</html>
四、Grid布局
Grid布局,是一种二维布局。
外层元素称为容器,内存中最顶层的子元素称为项目。
容器中分行和列,m行n列的容器,拥有m*n个单元格,m+1条水平网格线,n+1条垂直网格线。
容器的属性称为容器属性,项目的属性称为项目属性。
容器属性:
display: grid inline-grid
grid-template-columns:行分部
grid-template-rows:列分部
行列分部可以用 px 百分比 repeat()重复(auto-fill自动填充数量) fr比例 minmax()长度范围 auto自动填充 []来定义网格线名称
grid-template-areas:给网格线划分的每个区域起名字
grid-auto-flow:先行还是先列
justify-items:项目水平对齐
align-items:项目垂直对齐
justify-content:内容区域水平对齐
align-content:内容区域垂直对齐
grid-auto-columns:多余项目的宽
grid-auto-rows:多余项目的高
项目的属性:
grid-column-start:左边框
grid-column-end:右边框
grid-row-start:上边框
grid-row-end:下边框
justify-self:单个项目水平对齐
align-self:单个项目垂直对齐
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Grid</title>
</head>
<style>
span {
font-size: 2em;
}
#container{
display: grid;
width: 400px;
grid-template-columns: 100px auto 100px;
grid-template-rows: 50px 50px 50px 50px;
}
.item {
font-size: 2em;
text-align: center;
border: 1px solid #e5e4e9;
}
.item-1 {
background-color: #ef342a;
}
.item-2 {
background-color: #f68f26;
}
.item-3 {
background-color: #4ba946;
}
.item-4 {
background-color: #0376c2;
}
.item-5 {
background-color: #c077af;
}
.item-6 {
background-color: #f8d29d;
}
.item-7 {
background-color: #b5a87f;
}
.item-8 {
background-color: #d0e4a9;
}
.item-9 {
background-color: #4dc7ec;
}
</style>
<body>
<span>foo</span>
<div id="container">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
<div class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
<span>bar</span>
</body>
</html>