盒子模型的宽度计算
- offsetWidth = width + boder + padding,无外边距
box-sizing: border-box; 即所设置的盒子 width = offsetWidth
1 2 3 4 5 6 7 8 9 10 11 12 13
| // div1的 offsetWidth 是多少? 122px // 如果设置了 box-sizing: border-box; 则 offsetWidth = 100px(其中宽度78px)
<style> #div1 { width: 100px; padding: 10px; border: 1px solid #ccc; margin: 20px; } </style>
<div id="div1"></div>
|
margin 纵向重叠
- 相邻元素的
margin-top 和 margin-bottom 会发生重叠
- 空白内容的
<p></p>也会重叠
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| // AAA和BBB之间的距离是多少? 15px
<style> p { font-size: 16px; line-height: 1; margin-top: 10px; margin-bottom: 15px; } </style>
<p>AAA</p> <P></P> <P></P> <P></P> <P>BBB</P>
|
margin 负值
元素设置了浮动
- 如果设置的 margin 的方向与浮动的方向相同,那么,元素会往对应的方向移动对应的距离
- 如果设置 margin 的方向与浮动的方向相反,则元素本身不动,元素之前或者之后的元素会向该元素的方向移动相应的距离
元素没有设置浮动,且没有设置定位或者 position 为 static
- margin-top 和 margin-left 负值,元素向设置的方向移动相应的距离
- margin-right 和 margin-bottom 负值,元素本身不移动,元素后面的其他元素会往该元素的方向移动相应的距离,并且会覆盖在该元素上面
元素没有设置浮动,且 position 为 relative
- margin-top 和 margin-left 负值,元素向设置的方向移动相应的距离
- margin-right 和 margin-bottom 负值,元素本身不移动,元素后面的其他元素会往该元素的方向移动相应的距离,该元素会覆盖在后面的元素上面
元素没有设置浮动,且 position 为 absolute
- margin-top 和 margin-left 负值,元素向设置的方向移动相应的距离
- margin-right 和 margin-bottom 负值,元素本身不移动,对后面的元素没有影响
BFC 理解和应用
什么是 BFC
- Block formatting cotext,块级格式化上下文
- 一块独立渲染区域,内部元素的渲染不会影响边界以外的元素
BFC 的布局规则
- 内部的 Box 会在垂直方向,一个接一个地放置
- Box 垂直方向的距离由 margin 决定,属于同一个BFC的两个相邻 Box 的 margin 会发生重叠
- 每个盒子(块盒与行盒)的 margin box 的左边,与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此
- BFC的区域不会与 float box 重叠
- 计算 BFC 的高度时,浮动元素也参与计算
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此
如何创建 BFC
- float 不是 none
- overflow 不是 visible
- position 是 absolute、fixed
- display 是 inline-block、flex
BFC 常见应用
- 清除浮动(为浮动元素的父元素设置 overflow: hidden,以解决高度坍塌)
- 避免 margin 重叠(在重叠元素的外层增加父元素 div,并设置 overflow: hidden)
- 自适应两栏布局(左栏固定宽度并左浮动,右栏不设置宽度且设置 overflow: hidden)
float 布局
圣杯布局和双飞翼布局的目的
- 三栏布局,中间一栏最先加载和渲染(内容最重要)
- 两侧内容固定,中间内容随着宽度自适应
- 一般用于 PC 网页
如何实现圣杯布局和双飞翼布局
- 使用 float 布局
- 两侧使用 margin 负值,以便和中间内容横向重叠
- 防止中间内容被两侧覆盖,圣杯布局用 padding,双飞翼布局用 margin
圣杯布局的实现
- header、footer 宽度 100% 撑满
- center、left、right 都设置左浮动,left、right 设为相对定位
- center 放在最前面,宽度 100% 撑满,left 和 right 分别定宽 200px 和 150px
- 给外层的 container 设置
padding-left: 200px; padding-right: 150px;,给 left 和 right 空出位置
- 设置 left 的
margin-left: -100%;,让 left 回到上一行
- 设置 left 的
left: -200px; 把 left 拉回最左侧
- 设置 right 的
margin-right: -150px; 把 right 拉回上一行最右侧
1 2 3 4 5 6 7 8 9
| <header>header</header> <main> <div id="container"> <div id="center" class="column">center</div> <div id="left" class="column">left</div> <div id="right" class="column">right</div> </div> </main> <footer>footer</footer>
|
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
| #header, #footer { background-color: #ccc; } #container { overflow: hidden; padding-left: 200px; padding-right: 150px; } #container .column { float: left; position: relative; } #center { width: 100%; background-color: darkseagreen; } #left { left: -200px; width: 200px; margin-left: -100%; background-color: cadetblue; } #right { width: 150px; margin-right: -150px; background-color: palevioletred; }
|
双飞翼布局的实现
- header、footer 宽度 100% 撑满
- left、center、right 都设置左浮动
- center 放在最前面,宽度 100% 撑满,left 和 right 分别定宽 200px 和 150px
- 设置负边距,left 设置
margin-left: -100%;,right 设置margin-left: -150px;
- 设置 center-wrap 的 margin 值为左右两个侧栏留出空间,margin 值大小为 left 和 right 宽度
1 2 3 4 5 6 7 8 9 10 11
| <header>header</header> <main> <div id="container"> <div id="center" class="column"> <div class="center-wrap">center</div> </div> <div id="left" class="column">left</div> <div id="right" class="column">right</div> </div> </main> <footer>footer</footer>
|
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
| header, footer { background-color: #ccc; } #container { overflow: hidden; } #container .column { float: left; } #center { width: 100%; background-color: darkseagreen; } .center-wrap { margin: 0 150px 0 200px; } #left { width: 200px; margin-left: -100%; background-color: palevioletred; } #right { width: 150px; margin-left: -150px; background-color: burlywood; }
|
注意!圣杯布局和双飞翼布局的优缺点:
|
优点 |
缺点 |
| 圣杯布局 |
结构简单,无多余 DOM 层 |
中间部分宽度小于左侧时布局混乱 |
| 双飞翼布局 |
支持各种宽高变化,通用性强 |
多余 DOM 层,增加渲染树生成的计算量 |
手写 clearfix
1 2 3 4 5 6 7 8
| .clearfix:after { content: ''; display: block; clear: both; } .clearfix { *zoom: 1; }
|
1 2 3 4 5
| <div class="clearfix"> <div style="float: left">center</div> <div style="float: left">left</div> <div style="float: left">right</div> </div>
|
flex 布局
1 2 3
| .container { display: flex(块元素)| inline-flex(行内元素); }
|
注意!当设置 flex 布局之后,子元素的 float、clear、vertical-align 的属性将会失效
- flex-direction: 主轴的方向(即项目的排列方向)
1 2 3 4 5 6 7
| .container { flex-direction: row(默认值,主轴为水平方向,起点在左端) | row-reverse(主轴为水平方向,起点在右端) | column(主轴为垂直方向,起点在上沿) | column-reverse(主轴为垂直方向,起点在下沿); }
|
- justify-content:项目在主轴的对齐方式
1 2 3 4 5 6 7 8
| .container { justify-content: flex-start(默认值,左对齐) | flex-end(右对齐) | center(居中对齐) | space-between(两端对齐,项目之间的间隔相等,即剩余空间等分成间隔) | space-around(每个项目两侧的间隔相等,项目之间的间隔比项目与边缘的间隔大一倍); }
|
1 2 3 4 5 6 7 8
| .container { align-items: stretch(默认值,如果项目未设置高度或者设为 auto,将占满整个容器的高度) | flex-start(交叉轴的起点对齐) | flex-end(交叉轴的终点对齐) | center(交叉轴的中点对齐) | baseline(项目的第一行文字的基线,即文字的底部对齐); }
|
1 2 3 4 5 6
| .container { flex-wrap: nowrap(默认值,当主轴尺寸固定且空间不足时,项目尺寸会随之调整而并不会挤到下一行) | wrap(换行,项目主轴总尺寸超出容器时换行,第一行在上方) | wrap-reverse(换行,第一行在下方); }
|
- align-content:定义多根轴线的对齐方式,如果项目只有一根轴线,那么该属性将不起作用。即当 flex-wrap 设置为 wrap 的时候,容器可能会出现多条轴线,需要设置多条轴线之间的对齐方式
1 2 3 4 5 6 7 8 9
| .container { align-content: stretch(默认值,多条轴线平分容器的交叉轴方向上的空间) | flex-start(轴线全部在交叉轴的起点对齐) | flex-end(轴线全部在交叉轴的终点对齐) | center(轴线全部在交叉轴的中点对齐) | space-between(轴线两端对齐) | space-around(每个轴线两侧的间隔相等); }
|
- align-self:允许单个项目有与其他项目不一样的对齐方式,与 align-items 属性类似
1 2 3 4 5 6 7 8 9
| .item { align-self: auto(默认值,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch) | flex-start(交叉轴的起点对齐) | flex-end(交叉轴的终点对齐) | center(交叉轴的中点对齐) | baseline(项目的第一行文字的基线,即文字的底部对齐) | stretch(如果项目未设置高度或者设为 auto,将占满整个容器的高度); }
|
flex 实现三栏布局
- container 中的 left、center、right 依次排布即可
- 给 container 设置弹性布局
display: flex;
- left 和 right 区域定宽,center 设置
flex: 1; 即可
flex 实现一个三点的骰子
1 2 3 4 5
| <div class="container"> <span class="items"></span> <span class="items"></span> <span class="items"></span> </div>
|
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
| .container { display: flex; justify-content: space-between; width: 150px; height: 150px; border: 5px solid #ccc; padding: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; } .items { display: inline-block; width: 40px; height: 40px; background-color: #cd1426; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; } .items:nth-child(2) { align-self: center; } .items:nth-child(3) { align-self: flex-end; }
|

flex 实现一个五点的骰子
1 2 3 4 5 6 7 8 9 10 11 12 13
| <div class="container"> <div class="items-wrap"> <span class="items"></span> <span class="items"></span> </div> <div class="items-wrap"> <span class="items"></span> </div> <div class="items-wrap"> <span class="items"></span> <span class="items"></span> </div> </div>
|
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
| .container { display: flex; flex-direction: column; justify-content: space-between; width: 150px; height: 150px; border: 5px solid #ccc; padding: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; } .items-wrap { display: flex; justify-content: space-between; } .items-wrap:nth-child(2) { justify-content: center; } .items { display: inline-block; width: 40px; height: 40px; background-color: #cd1426; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; }
|
