盒子模型
标准盒模型、IE盒模型的区别
- 在 标准盒子模型中,盒子的width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。
- IE盒子模型中,盒子的width 和 height 指的是内容区域+border+padding的宽度和高度。
通过设置可以改变这两种盒子模式
// 标准盒模型
box-sizing: content-box;
// IE盒模型
box-sizing: border-box;
计算出box盒子的offsetWidth的值
offsetWidth = content + border + padding
<style>
.box{
width:100px;
height:100px;
border:1px;
padding:10px;
margin:10px;
}
</style>
<div class="box">
</div>
计算offsetWidth为100+20+2 = 122;
如果要让offsetWidth的值为100,怎么解决?
<style>
.box{
width:100px;
height:100px;
border:1px;
padding:10px;
margin:10px;
+ border-sizing:border-box;
}
</style>
<div class="box">
</div>
设置border-sizing:border-box;
盒子(BFC)边距重叠解决方案
BFC(Block Formatting Context):块级格式化上下文。解决边距重叠的问题。是一块独立的渲染区域,内部内容和外部互不影响
如何触发BFC
- 根元素
- float属性不为none
- position为absolute或fixed
- display为inline-block, table-cell, table-caption, flex, inline-flex
-
自适应两栏布局
<style>
body {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
会产生main左边和aside左边重叠,让main的宽度变化,解决办法,给main块设置为BFC
.main{
overflow:hidden;
}
清除内部浮动
<style>
.par {
border: 5px solid #fcc;
width: 300px;
}
.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
内部child的浮动会让par块的高度失效,高度塌陷。解决办法是将par元素设置为BFC
.par{
overflow:hidden;
}
防止margin重叠
<style>
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<p>Hehe</p>
</body>
两个p之间的距离为100px,发生了margin重叠。
解决办法:.wrap {
overflow: hidden;
}
js获取dom高度
clientHeight: height + padding
- offsetHeight: height + padding + border
- scrollHeight: clientHeight + scrollTop,但是scrollHeight会包含隐藏内容的高度。
- innerHeight: 浏览器window可视内容的高度
- outerHeight: 浏览器整个高度window,包括书签等
clientHeight
offsetHeight
scrollHeight: 元素内容的总高度,包含了隐藏内容的高度。
magin负值
- margin-top和margin-left设置负值,元素会向上或向左移动
- margin-right设置负值,右侧元素会左移,自身不受影响
- margin-bottom设置负值,下方元素会上移,自身不受影响
浮动float
圣杯布局
通过给父容器设置padding移动两侧的内容
```css<body>
<div id="header">#header</div>
<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>
<div id="footer" class="clearfix">#footer</div>
</body>
header,
footer {
background: rgba(29, 27, 27, 0.726); text-align: center; height: 60px; line-height: 60px; } / 设置两侧padding值 /container{
padding: 0 200px; } .column { height: 200px; float: left; position: relative; }
left {
width: 200px;
background-color: aqua;
margin-left: -100%;
right: 200px;
}
right {
width: 200px;
background-color: wheat;
margin-left: -200px;
left: 200px;
}
center {
width: 100%;
background-color: tomato;
} .clearfix{ clear: both; }
<a name="1Yy2v"></a>
### 双飞翼布局
通过margin设置两侧的内容位置<br />双飞翼是在center元素内部又**设置了一层inner-center的**元素并设置它的左右margin,而非圣杯布局的padding,来排除两边元素的覆盖
```html
<body>
<div class="col" id="center">
<div id="inner-center">center</div>
</div>
<div id="left" class="col">left left left</div>
<div id="right" class="col">right right right</div>
</body>
body{
min-width: 500px;
}
.col{
float: left;
}
#center{
width: 100%;
height: 200px;
background: #ccc;
}
#inner-center{
margin:0 190px;
}
#left{
width: 190px;
height: 200px;
background-color: #00f;
margin-left: -100%;
}
#right{
width: 190px;
height: 200px;
background-color: #f0f;
margin-left: -190px;
}
清除浮动clearfix
.clearfix:after{
content:'';
display:table;
clear:both;
}
定位position
absolute和relative依据什么定位
- relative依据自身定位
- absolute依据最近一层的定位元素定位(absolute、fixed、relative)
居中对齐的方式
水平居中
- inline元素:text-align:center;
- block元素:margin:auto;
absolute:left:50%+ margin-left:负值
垂直居中
inline元素:line-height的高度等于height的值
- absolute: top:50%+ margin-top:负值
- absolute: transform(-50%, -50%)
- absolute: (top/left/right/bottom)=0 + magin:auto
多行文字垂直居中
<div class="box">
<span>执行async函数,返回的是Promise对象执行async函数,返回的是Promise对象执行async函数,返回的是Promise对象</span>
</div>
line-height与vertical-align
.box{
width: 200px;
height: 200px;
border: 1px solid #ccc;
line-height: 200px;
text-align: center;
}
.box span{
line-height: 22px;
display: inline-block;
vertical-align: middle;
}
transform: translateY
.box{
width: 200px;
height: 200px;
border: 1px solid #ccc;
line-height: 200px;
text-align: center;
}
.box span{
line-height: 22px;
display: inline-block;
position: relative;
top:50%;
transform: translateY(-50%);
}
display:flex;
.box{
width: 200px;
height: 200px;
border: 1px solid #ccc;
text-align: center;
display: flex;
align-items: center;
}
响应式布局
各种单位
- px:绝对长度单位
- em:相对长度单位,相对于父元素
-
vh和vw视口的尺寸1%
window.screen.height:屏幕大小的高度
- window.innerHeigth:网页视口的高度
- document.body.height:DOM结构body的高度
window.screen.height = 667
window.innerHeight = 553 (网页视口高度,去除掉浏览器的头和尾)
media-query媒体查询
移动端使用js设置html的font-size
// 计算移动端rem
;(function (doc, win, undefined) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in win? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (clientWidth === undefined) return;
docEl.style.fontSize = 10 * (clientWidth / 750) + 'px';
};
if (doc.addEventListener === undefined) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window);
flex弹性布局
https://juejin.cn/post/6938292463605907492
flex布局要设置父/子盒子。
父级盒子设置
如果要设置flex布局,首先要把父级盒子设置为display:flex;这样位于该盒子下的元素才能应用弹性flex布局。
属性包含:
- flex-direction:用来定义item子元素排列方向
- flex-wrap:定义item排列时,是否换行
- flex-flow:是flex-direction和flex-wrap的缩写,默认为row nowrap
- justify-content:定义item在主轴上的对齐方式
flex-start
(默认值):左对齐flex-end
:右对齐center
: 居中space-between
:两端对齐,项目之间的间隔都相等。space-around
:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
- align-items:定义item在交叉轴上对齐方式
flex-start
:交叉轴的起点对齐。flex-end
:交叉轴的终点对齐。center
:交叉轴的中点对齐。baseline
: 项目的第一行文字的基线对齐。stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content:定义多个轴线的对齐方式,item要换行。如果是单个轴线,该属性不起作用。
order:定义排列的顺序,越小越靠前。默认为0
- flex-grow:定义item的放大比例。默认为0,表示默认不放大。
- flex-shrink:定义item的缩小比例,默认1,表示剩余空间不足时,该项目将缩小
- flex-basis:定义item在分配剩余空间之前,item占主轴空间大小。默认值auto,表示原来的大小(width/height),如果该项目未指定大小,则大小有内容决定。
auto
表示项目的本来大小,当设置为auto
时会根据主轴方向检索该flex-item
的**width**
或**height**
值作为**flex-basis**
的值。如果width
或height
值为auto
,则flex-basis
设置为content
,也就是基于 flex 的元素的内容自动调整大小。0
相当于指定了宽度或高度(宽度或高度由主轴方向决定)为 0。
- flex:是flex-grow,flex-shrink,flex-basis的组合形式。默认inital为0 1 auto,只会缩小不会放大。设置auto时为1 1 auto,可以自动放大缩小。
- align-self:允许单个项目可与其他item有不同的对齐方式。默认为auto,表示继承了父级的align-items。
- auto
- flex-start
- flex-end
- center
- baseline
- stretch
flex简写的三个属性【应用在子级】
flex-grow/flex-shrink/flex-basis三个属性的作用:定义了父级不同宽度下,子元素是如何布局空间的。
1. flex-basis:basis<主要,基础>
当子元素设置了width或者height,遇到basis后,要以basis为主。basis的权重级别最高。
2.flex-grow:扩展,放大
当父元素的宽度大于所有子元素宽度和,并且父元素宽度有剩余,可以定于子元素伸长,放大。
3.flex-shrink:缩小,收缩
当父元素的宽度小于所有子元素宽度和,并且大于父元素。那么可以设置子元素进行缩小。
Flex项目中使用 flex 属性可以根据Flex容器的可用空间对自身做伸缩计算,其包含三个子属性: flex-basis 、 flex-shrink 和 flex-grow 。这几个属性都有其初始值:
- flex-grow 的初始值为 0
- flex-shrink 的初始值为 1
- flex-basis 的初始值为 auto
即 flex 的三个子属性: flex-grow (扩展比率)、 flex-shrink (收缩比率)和 flex-basis (伸缩基准)。这三个属性可以控制Flex项目,具体的表现如下:
- flex-grow :设置Flex项目的扩展比率,让Flex项目得到(扩展)多少Flex容器剩余空间(Positive Free Space),即Flex项目可能会变大
- flex-shrink :设置Flex项目收缩比率,让Flex项目减去Flex容器不足的空间(Negative Free Space),即Flex项目可能会变小
- flex-basis :Flex项目未扩展或收缩之前,它的大小,即指定了Flex项目在主轴方向的初始大小
flex 属性可以指定 1个值(单值语法) 、 2个值(双值语法) 或 3个值(三值语法) 。
单值语法:值必须为以下其中之一:
- 一个无单位的数(
),比如 flex: 1 ,这个时候它会被当作 的值 - 一个有效的宽度( width )值,比如 flex: 30vw ,这个时候它会被当作
的值 - 关键词 none 、 auto 或 initial (即初始值)
双值语法:第一个值必须为一个无单位数值,并且它会被当作
- 一个无单位的数(
),它会被当作 的值 - 一个有效的宽度( width )值,它会被当作
的值
三值语法:
- 第一个值必须是一个无单位数(
),并且它会被当作 的值 - 第二个值必须是一个无单位数(
),并且它会被当作 的值 - 第三个值必须为一个有效的宽度( width )值,并且它会被当作
的值
flex 属性的取值可以是:
- auto :Flex项目会根据自身的 width 和 height 来确定尺寸,但Flex项目根据Flex容器剩余空间进行伸缩。其相当于 flex: 1 1 auto
- initial :Flex项目会根据自身的 width 和 height 来设置尺寸。它会缩短自身以适应Flex容器,但不会伸长并吸收Flex容器中的额外剩余空间来适应Flex容器。其相当于 flex: 0 1 auto
- none :Flex项目会根据自身的 width 和 height 来设置尺寸。它是完全非弹性的(既不会缩短,也不会伸长来适应Flex容器)。其相当于 flex: 0 0 auto
:定义Flex项目的 flex-grow 属性,取值为 :定义Flex项目的 flex-shrink 属性,取值为 :定义Flex项目的 flex-basis 属性。若值为0 ,则必须加上单位,以免被视作伸缩性
多层滚动条问题
业务开发中,由于列表元素很多,往往会出现滚动条。
box高度固定,a区域的高度值不定,b区域的高度要子适应填满box剩余的高度,并且只有b可以显示滚动条,box不可以显示滚动条。
此时非常适合使用弹性盒子布局。让b区域自动适应剩余高度值。
注意⚠️区别flex: 1 1 auto和flex: 1 1 0; 上文flex-basis详解。
给b设置flex: 1 1 auto时,表示高度值会依赖b区域内容的实际高度。
给b设置flex: 1 1 0时,表示高度值会自动适应box剩余的高度。
示例:https://codepen.io/shenshuai/pen/VwmgEJj
实现骰子的五点布局
<div class="box">
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
</div>
</div>
/* 重要内容
实现步骤:
1:让三个column竖向排列
2:让column的内容是flex布局,并且默认的横向排列,内部的原点为两端分布
3:让第二个column原点居中对齐
*/
.box{
display: flex;
flex-direction: column;
}
.box .column {
display: flex;
justify-content: space-between;
}
.box .column:nth-of-type(2) {
justify-content: center;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.box {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}