盒子模型及块元素水平垂直定位和绝对元素的定位布局和弹性盒
盒子模型
组成:
- content(内容区)
- border(边框)
- padding(内边距)
- margin(外边距)
盒子大小
盒子的大小值得就是盒子在容器中实际所占据的高度和宽度(默认情况下我们通过css设置的width
和height
只是设置了content
(内容区)的高度和宽度,实际上盒子模型所占据的高度和宽度是按照下面来计算的)
实际的宽度:
实际宽度 = margin-left + border-left + padding-left + width(content-width) + padding-right + border-right + margin-right
实际的高度:
实际的高度 = margin-top + border-top + padding-top + height(content-height) + padding-bottom + border-bottom + margin-bottom
比如下面图片的实际宽度和实际高度是多少呢?
使用上述公式,就能算出示例中的高宽值
实际宽度 = 20+6+20+400+20+6+20 = 492
实际的高度 = 20+6+20+100+20+6+20 = 192
更改盒子模型的计算方式
一般情况下,css设置的width
,height
设置的都是content-width
,content-height
,但是我们也可以通过css,改变css里面的width,和height设置的是什么
box-sizing:content-box(默认情况)
- 一开始的css显示效果和代码,可以看到,Child container刚刚好等于父元素的宽度
- 也就是实际的宽度 = 父元素的宽度
1 | box-sizing: content-box; |
- 添加了
border为10px
,并且设置了padding:5px
- 可以看到内容超过了父元素,溢出了
- 实际的宽度 = 父元素的宽度 + border-left + border-right + padding-left + padding-right
1 | box-sizing: content-box; |
box-sizing:border-box
- 只将
box-sizing
修改为border-box
,效果就完全不同 - 实际的宽度 = 父元素的宽度
- 因为
box-sizing
设置的为border-box
所以css当中设置的width
属性包括了border
的宽度和padding
的宽度(注意,不包括margin
!)
1 | box-sizing: border-box; |
div(块元素)水平方向布局
- 看过上面,我们知道水平方向上的位置必须要满足
- margin-left + border-left + padding-lef + width + padding-right + border-right + margin-right = 父元素内容区的宽度
- 如果不满足上方等式,等式就会自动去调整
这七个值中有三个值可以设置为auto
1 | width |
- 调整的情况 (等式当中含有auto值和没有auto的情况)
width | margin-left | margin-right | 结果 |
---|---|---|---|
auto | / | auto | **宽度(width)自动调整为最大值,**选取的margin-right自动为0 |
auto | auto | / | **宽度(width)自动调整为最大值,**选取的margin-left自动为0 |
auto | auto | auto | **宽度(width)自动调整为最大值,**二个外边距自动设置为0 |
auto | / | / | **宽度(width)自动调整为最大值,**二个外边距自动设置为0 |
固定值 | auto | auto | 宽度(width)不变,margin-left和margin-right自动调整(也就是水平居中) |
固定值 | auto | / | 宽度(width)不变,自动调整margin-left的值 |
固定值 | / | auto | 宽度(width)不变,自动调整margin-right的值 |
固定值 | / | / | 宽度(width)不变,自动调整margin-right的值 |
总结:
三者当中含有auto值的情况
- 当
width为auto
的时候,总是保证width
为最大值而其他设置为auto的自动设置为0 - 当
width为固定值
的时候,自动调整已经设置为auto的值使其满足等式(margin-left + border-left + padding-lef + width + padding-right + border-right + margin-right = 父元素内容区的宽度)
- 当
三者当中没有auto的情况
- 当
width为固定值
发现其他值都没有写,没有一个auto,那么就自动调整margin-right
的值(见得最多的)
- 当
例如下方例子:
下方的例子说明auto的计算
注意,没有写代表没有,如果填写了0,或者auto,就代表在css里面设置了margin-left或者其他的为0或者auto!
margin-left | border-left | padding-left | width | padding-right | border-right | margin-right | 父元素宽度 | 结果 |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | auto | 0 | 0 | 0 | 800px | width当中的auto设置为800px |
auto | 0 | 0 | 500px | 0 | 0 | 0 | 800px | margin-left的auto被设置为300px |
0 | 0 | 0 | 400px | 0 | 0 | auto | 800px | margin-right的auto被设置为500px |
没有写 | 0 | 0 | 700px | 0 | 0 | 没有写 | 800px | margin-right的auto被设置为100px |
auto | 10 | 5 | 400px | 5 | 10 | auto | 700px | margin-left和margin-right的auto被设置为(700-(10+5+400+5+10))/2=135px |
- 所以为什么你经常看到设置了宽度后,在设置
margin:0 auto
就可以实现水平居中,就是利用上述原理- width固定,margin-left,margin-right为auto,那么浏览器会自动跳转auto的值,所以就实现了水平居中
div(块元素)垂直方向布局
块元素7个值没有auto的话就会自动调整margin-bottom
其他和水平基本一样的,也是下面三个值可以设置auto,这里就不多说了
1 | margin-top |
开启绝对定位元素的布局
先来大概了解下开启绝对定位后元素的参考父元素(也就是我们常说的包含块)
正常情况下,包含块就是最近的开启了相对定位的块元素(当然,如果都没有开启,则参考
html
)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<style>
.box1 {
width: 400px;
height: 400px;
background-color: red;
position: relative;
}
.box2 {
width: 200px;
height: 200px;
background-color: green;
}
.box3 {
width: 100px;
height: 100px;
background-color: blue;
position: absolute;
right: 0;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">
<div class="box3"></div>
</div>
</div>
</body>
开启决定定位后,开启绝对定位后的元素也是需要满足一定条件约束的
- 水平方向来说:(和平常没有开启定位的多了一个left,right)
left + margin-left + border-left + padding-left + width + padding-right + border-right + margin-right + right = 包含块的宽度
- 垂直方向来说:(和平常没有开启定位的多了一个top,bottom)
top + margin-top+ border-top+ padding-top+ height+ padding-bottom+ border-bottom+ margin-bottom+ bottom = 包含块的宽度
水平方向布局
可以调整为auto的
1 | margin-left |
需要满足
left + margin-left + border-left + padding-left + width + padding-right + border-right + margin-right + right = 包含块的宽度
如果9个值当中没有设置auto,则会自动调整right的值来满足(有点像未开启定位的块元素的水平布局一样,块元素其他7个值没有auto的话就会自动调整margin-right)
所以如果等式不满足的时候,就会自动调整left
和right
这两个值。
- 例子:下面的例子就会自动调整
right为-200px
,使得等式成立
1 | <style> |
浏览器查看box2的computed
当然,你如果皮,把box2的right改为0
1 | .box2{ |
那么效果依旧不会变化~不过浏览器查看box2的computed
的时候变成了这样子
- 需要注意的是: 要设置
left = 0; right = 0;
才能调整margin-left和margin-right
,否则会自动调整left和right的值(不管computed
有没有看到效果) 从而导致给margin-left、margin-right
设置值会失效
垂直方向布局
可以调整为auto的
1 | margin-top |
需要满足
top + margin-top+ border-top+ padding-top+ height + padding-bottom+ border-bottom+ margin-bottom+ bottom = 包含块的高度
如果9个值当中没有设置auto,则会自动调整bottom的值来满足(有点像块元素的垂直布局一样,块元素7个值没有auto的话就会自动调整margin-bottom)
所以如果等式不满足的时候,就会自动调整top
和bottom
这两个值。
常用的一些效果
- 开启定位后相对于包含块水平居中
1 | //设置代码 |
效果
浏览器computed效果
- 开启定位后相对于包含块垂直居中
1 | .box2{ |
效果
浏览器computed查看
- 开启定位后相对于包含块居中
1 | .box2 { |
效果
浏览器computed查看效果
弹性盒
基本概念
想看看也可以,这里说的简单的,也可以看看这位博主写的
设置
display:flex
开启弹性容器,将当前元素设置为块级的弹性容器display:inline-flex
开启弹性容器 设置为行内的弹性容器
基本概念
- 主轴
- 弹性元素的排列方向(默认水平方向为主轴)
- 侧轴
- 和主轴垂直的叫侧轴
- 主轴
- 特征
- 弹性容器的子元素是弹性元素
- 弹性元素可以同时是弹性容器
如下代码开启了弹性布局,div
即为弹性容器,div
下方的span
em
等即为弹性元素
1 | <body> |
设置主轴
顺带一提记忆方法: 你知道display:flex是开启定位,那么就联想记忆,就认为flex就代表水平,然后flex-direction就是告诉容器水平是哪一个方向的 (row代表行,行当然是水平的,column代表列,列肯定是垂直的) 感兴趣的可以看看MDN的主轴API
方向 flex-direction
flex-direction
:row(默认值)|row-reverse|column|column-reverse
flex-direction:row
设置弹性容器当中的弹性元素在水平方向排列,并且弹性元素是从左到右排序(同时设置主轴的方向为水平方向) (默认值)
flex-direction:row-reverse
设置弹性容器的弹性元素在水平方向排列并且是从右到左排列(同时设置主轴的方向为水平方向)
flex-direction:column
设置弹性容器的弹性元素在垂直方向,并且是从上到下依次排列(同时设置主轴的方向为垂直方向)
flex-direction:column-reverse
设置弹性容器的弹性元素在垂直方向,并且是从下到上排列(同时设置主轴的方向为垂直方向)
设置弹性元素在弹性容器上是否自动换行(重要) flex-wrap
flex-wrap
:nowrap(默认值不换行) | wrap(换行) | wrap-reverse
flex-wrap:nowrap
的情况
如果没有设置弹性元素:flex-shrink:0
的话,那么弹性元素如果超过了弹性容器的宽度,那么会自动跳转宽度使其等于弹性容器的宽度!
flex-wrap:wrap
换行
flex-wrap:wrap-reverse
主轴相反的方向进行换行 不太好描述,感觉像叠叠乐一样
对齐方式 justify-content
大家都知道word当中有什么左对齐,居中对其,右对齐,二端对其,css也有~
justify-content:
flex-start | flex-end | center | space-between | space-around设置如何顺着弹性容器主轴的方向分配弹性元素之间及其周围的空间(大白话就是主轴在哪里,我就按照你方向来分配其他没有被占据的空间)- 正确的理解应该是设置弹性元素在主轴上的对其方式
- justify-content说明文档
- 特别注意,这里的弹性元素会出现放不下被换行和垂直方向排布端正是因为设置了
flex-wrap: wrap;
及align-content: flex-start;
justify-content:flex-start
(可以说是默认值) 设置元素每一行在主轴开头(起始位置)开始排布
justify-content:flex-end
设置元素沿着主轴终点开始排列
justify-content:space-between
设置每一行的空白元素平均分配到元素中间
justify-content:space-around
设置每一行的空白元素分配到元素四周(注意:二个元素之间分配到的空白间距并不会取消,而是会叠加在一起)
设置侧轴
元素对其方式 align-items
align-items:
stretch(默认) |center| flex-start | flex-end | baseline
align-items:stretch
元素在侧轴上拉伸(如果没有设置height属性或者设置为auto就会拉伸) ,如果设置了width为固定值,那么这个效果就不会生效
align-items:center
设置侧轴元素居中排列
align-items:flex-start
元素向侧轴起点对齐(以每一行为参考,可以想象下每一行有自己的主轴侧轴)
align-items:flex-end
元素向侧轴终点对齐(以每一行为参考,可以想象下每一行有自己的主轴侧轴)
空隙排布 align-content
align-content:
flex-start | flex-end | space-between | space-around | center
图我就不自己截了,拿了其他的,原来作者找不到了..只找到一个转载的
align-content:flex-start
align-content:flex-end
align-content:space-between
align-content:space-around
align-content:center
一个小小的简写(一次性设置主轴方向和flex-wrap)
flex-flow
: flex-direction flex-wrap- 比如
flex-flow:row nowrap
- 比如
针对弹性元素的属性(注意区分弹性容器和弹性元素)
再次强调下,弹性容器是外壳,弹性元素是内部~
flex-grow:number
- 指定弹性元素的伸展系数,也就是当父元素(弹性容器)有空余的元素的时候如何分配(伸展)
- 比如 flex-grow : 1 ; flex-grow : 2; flex-grow : 3 ;
原来的空隙
设置 flex-grow : 1 ; flex-grow : 2; flex-grow : 3
; [这些数字就是所占据的比例,比如1,就占1/(1+2+3)=1/6 也就是六分之一]
flex-shrink:number
- 指定弹性元素的收缩系数,也就是如果当父元素(弹性容器)容纳不下子元素(弹性元素)的时候,如何减少
未设置flex-shrink,即为0
设置flex-shrink : 1 ; flex-shrink : 2 ; flex-shrink : 3 ;后的效果
flex-basis
flex-basis
具体长度|auto —-设置弹性元素在主轴上的基础长度- flex-basis:100px;
- 如果主轴为横向的,则此元素设置宽度
- 如果主轴是纵向的,则此元素设置高度