css
盒模型宽度的计算
知识点
以下属性值不包括margin
,因为它不是元素的一部分
offsetWidth/offsetHeight
:元素的完整大小(包括边框)
clientWidth/clientHeight
:包括元素的内容宽度和padding
,但不包括滚动条宽度
scrollWidth/scrollHeight
就像 clientWidth/clientHeight
,但它们还包括滚动隐藏的部分(内容区域的完整内部高度/宽度)
<div id="div1">this is div1</div>
#div1 {
width: 100px;
padding: 10px;
border: 1px solid red;
margin: 10px;
}
- 请问
div1
的offsetWidth
是多大?
122px
- 如果要让
offsetWidth
的值等于 100px
,怎么做?
给div1
添加box-sizing:border-box
,让div1
变成怪异盒模型。此时盒子的 width
=盒子内容的宽度+左右padding
+左右 border
=offsetWidth
=100
margin 纵向重叠问题
知识点
<p>aaa</p>
<p></p>
<p></p>
<p></p>
<p>bbb</p>
p {
font-size: 16px;
line-height: 16px;
margin-top: 10px;
margin-bottom: 15px;
}
aaa
和 bbb
之间的距离?
- 相邻元素的
margin-top
和margin-bottom
会发生重叠 - 空白内容的
p
也会重叠 - 所以答案为 15
px
margin 负值问题
top
,left
为负值,元素向上、向左移动right
负值 右侧元素左移,自身不受影响bottom
负值,下方元素上移,自身不受影响
BFC 理解与应用
- 块级格式化上下文
- 一块独立渲染区域,内部元素的渲染不会影响边界以外的元素
- 形成
BFC
的条件是?
float
的值不是none
positon
的值是absloute
或者fixed
display
的值是inline-block
,flex
,或者inline-flex
overflow
的值不是visible
- 应用
- 清除浮动
BFC
可以取消盒子margin
塌陷BFC
可以阻止元素被浮动元素覆盖
了解
float 布局:实现圣杯和双飞翼布局- 三栏布局,中间一栏最先加载和渲染(内容最重要)
- 两侧内容固定,中间内容随着宽度自适应
- 一般用于
PC
网页
技术总结
- 使用
float
布局 - 两侧使用
margin
负值,以便和中间内容横向重叠 - 防止中间内容被两侧覆盖,一个用
padding
一个用margin
圣杯布局
关于页面的最小宽度
min-width 就是页面的最小宽度:要想保证该布局效果正常显示,由于两侧都具有固定的宽度,所以需要给定页面一个最小的宽度,但这并不只是简单的 200+150=350px。回想之前 left 使用了 position: relative,所以就意味着在 center 开始的区域,还存在着一个 left 的宽度(" 老家留坑")。所以页面的最小宽度应该设置为 200+150+200=550px
<main>
<div class="center column">这是中间部分</div>
<div class="left column">这是左侧部分</div>
<aside class="right column">这是右侧部分</aside>
</main>
body {
min-width: 550px;
}
* {
margin: 0;
padding: 0;
}
.column {
text-align: center;
float: left;
}
.center {
width: 100%;
background-color: yellow;
}
.left {
position: relative;
width: 200px;
background-color: #ff1f1f;
/* 父元素main宽度的100% */
margin-left: -100%;
right: 200px;
}
.right {
width: 150px;
background-color: blueviolet;
margin-right: -150px;
}
main {
overflow: hidden;
padding-left: 200px;
padding-right: 150px;
}
双飞翼布局
关于页面的最小宽度
由于双飞翼布局没有用到 position:relative 进行定位,所以最小页面宽度应该为 200+150=350px。但是当页面宽度缩小到 350px 附近时,会挤占中间栏的宽度,使得其内容被右侧栏覆盖,因此在设置最小页面宽度时,应该适当增加一些宽度以供中间栏使用
<main class="col">
<div class="main-wrap">这是中间部分</div>
</main>
<div class="left col">这是左侧部分</div>
<div class="right col">这是左侧部分</div>
* {
margin: 0;
padding: 0;
}
body {
min-width: 550px;
}
.col {
float: left;
}
main {
width: 100%;
}
.main-wrap {
margin: 0 150px 0 200px;
background-color: aqua;
}
.left {
background-color: red;
width: 200px;
margin-left: -100%;
}
.right {
width: 150px;
background-color: green;
margin-left: -150px;
}
了解
float 布局:手写 clearfix.clearfix:after {
content: '';
display: block;
clear: both;
}
flex 布局:用 flex 写一个三栏布局
* {
padding: 0;
margin: 0;
}
.left {
width: 200px;
background-color: red;
}
.right {
width: 150px;
background-color: aquamarine;
}
.center {
flex: 1;
background-color: blue;
}
main {
display: flex;
height: 100vh;
}
.column {
text-align: center;
}
<main>
<div class="left column">这是左侧部分</div>
<div class="center column">这是中间部分</div>
<aside class="right column">这是右侧部分</aside>
</main>
flex 布局:实现一个三点骰子
.box {
width: 200px;
height: 200px;
border-radius: 20px;
border: 2px solid #000;
display: flex;
padding: 20px;
box-sizing: border-box;
justify-content: space-between;
}
.item {
width: 50px;
height: 50px;
background-color: #000;
border-radius: 50%;
}
.item:nth-child(2) {
align-self: center;
}
.item:nth-child(3) {
align-self: flex-end;
}
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
absloute 和 relative 分别依据什么定位?
absloute
: 依据最近一层的定位元素(absloute
,relative
,fixed
=>body
)定位relative
: 依据自身定位
居中有哪些实现方式
水平居中
inline
元素:text-align:center
block
元素:margin:auto
(margin:auto
会使元素水平居中的原因是因为浏览器在计算块级元素的水平margin
时,如果设置了左右margin
都为auto
,浏览器会将左右margin
均分到元素两侧,从而实现水平居中的效果,在垂直方向上,块级元素不会自动扩充,它的外部尺寸没有自动充满父元素,也没有剩余空间可说。所以margin:auto不能实现垂直居中)absolute
元素:left:50%
+margin-left:-宽度的一半
垂直居中
inline
元素:line-height
的值等于height
absolute
元素:top:50%
+left:50%
+margin-top:-高度的一半
+margin-left:-宽度的一半
(元素尺寸已知)absolute
元素:top:50%
+left:50%
+transform: translate(-50%, -50%)
(元素尺寸未知)absolute
元素:top:0,left:0,bottom:0,right:0
+margin:auto
(需设置元素宽高)flex
元素:align-items:center
+justify-content:center
line-height 如何继承
body {
font-size: 20px;
line-height: 200%;
}
p {
font-size: 16px;
}
/* p的行高为? */
- 写具体数值,如
30px
,则继承该值(比较好理解) - 写比例,如
1.5
,则继承该比例(比较好理解) =>20*1.5=24px - 写百分比,如
200%
,则继承计算出来的值(考点)=>20*200%=40px
待思考
说一下响应式布局rem
rem
是一个长度单位,
px
,绝对长度单位,最常用em
,相对长度单位,相对于父元素,不常用rem
,相对长度单位,相对根元素
/* 1rem等于html元素上字体设置的大小 */
html {
font-size: 100px;
}
div {
font-size: 0.16rem;
}
media-query
,根据不同的屏幕宽度设置根元素font-size
,使用rem
作为长度单位,案例:网易新闻 H5 过时
用 css 画个三角形
<div id="box"></div>
#box {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid #64b687;
}
css 中常见的可继承和不可继承的属性有哪些
不可继承:
分类 | 属性 |
---|---|
display | - |
文本系列属性 | vertical-align,text-decoration,text-shadow,white-space |
盒模型属性 | width,height,margin,padding,border |
背景属性 | - |
定位属性 | float,clear,position,top,right,bottom,left,min-width,min-height,max-width,max-height,overflow,z-index |
可继承:
分类 | 属性 |
---|---|
字体系列属性 | font-family,font-weight,font-size,font-style |
文本系列属性 | text-indent,text-align,line-height,word-spacing,letter-spacing,text-transform,color |
元素可见性 | visibility |
光标属性 | cursor |
display:none 和 visibility:hidden 的区别
这两个属性都是让元素隐藏,不可见。
区别:
- DN 会让元素完全从渲染树中消失,渲染时不会占据任何空间
- VH 不会让元素从渲染树中消失,渲染的元素还会占据相应的空间,只是内容不可见
- DN 是非继承属性,子孙节点会随着父节点从渲染树消失,通过修改子孙节点的属性也无法显示;VH 是继承属性,子孙节点消失是由于继承了 hidden,通过设置 VV 可以让子孙节点显示
- 修改常规文档流中的 display 通常会造成文档的回流,但是修改 visibility 只会造成元素的重绘
margin 和 padding 的使用场景
- 需要在 border 外侧添加空白,且空白处不需要背景色时,使用 margin
- 需要再 border 内测添加空白,且空白处需要背景色时,使用 padding
隐藏元素的方法有哪些
- display:none:渲染树不会包含该渲染对象,因此该元素不会在页面中占据位置,也不会响应绑定的事件
- visibility:hidden:元素在页面中仍占据空间,但是不会响应绑定的监听事件
- opacity:0:将元素的透明度设置为 0,以此来实现元素的隐藏。元素在页面中仍然占据空间,并且能响应元素绑定的监听事件
- transform:scale(0,0):将元素缩放为 0,来实现元素的隐藏。这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件
link 和 @import 的区别
- link 是 html 标签,除了加载 css,还支持订阅 rss 等其他事务;@import 属于 css 范畴,只能加载 css
- link 引用 css 时,在页面载入时同时加载;@import 需要页面网页完全载入以后加载
- link 支持使用 javascript 控制 DOM 去改变样式,而@import 不支持
transition 和 animation 的区别
transition 是过渡属性,强调过渡,它的实现需要触发一个事件(点击、鼠标移上去,焦点)才执行动画,可以设置一个开始关键帧,一个结束关键帧
animation 是动画属性,强调动画,它的实现不需要触发事件,可以设置多个关键帧,每个关键帧都可以设置不同的属性值
z-index 属性在什么情况下会失效
- 父元素 positon 为 relative 时,子元素的 z-index 失效,解决:父元素 positon 改为 absloute 或 static
- 元素没有设置 positon 属性为非 static 属性。解决:设置该元素的 positon 属性为 relative,absloute 或是 fixed 中的一种
- 元素在设置 z-index 的同时还设置了 float 浮动,float 去掉,改为 display:inline-block
伪元素和伪类的区别和作用
伪元素:在内容元素的前后插入额外的元素和样式,但是这些元素实际上不在文档中生成。他们只在外部显示可见,但不会在文档的源代码中找到他们,因此称为“伪”元素
伪类:将特殊的效果添加到特定选择器上,这个选择器匹配处于确定状态的元素,比如说鼠标悬停在元素上时,或者元素获得焦点时,不会产生新的元素
对 requestAnimationFrame 的理解
requestAnimationFrame 是浏览器提供的一个 API,用来在浏览器重绘之前执行动画,它会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,避免了因为 DOM 操作频繁引起的性能问题
为什么有时候用 translate 来改变位置而不是定位
操作定位属性(top、bottom)会改变节点位置从而引发回流,使用translate
代替,只会引发图层重绘,还会间接启动 GPU 加速
常用的选择器有哪些,优先级怎么样
- 通配符选择器(
*
):0,0,0,0 - 标签选择器(
div
):0,0,0,1 - 类选择器(
.class
):0,0,1,0 - ID 选择器(
#id
):0,1,0,0 - 属性选择器(
[attr]
):0,0,1,0 - 伪类选择器(
:hover
):0,0,1,0 - 伪元素选择器(
::before
):0,0,0,1 - 交集选择器(
div.class
):0,0,1,1 - 并集选择器(
ul,ol
):0,0,0,2 - 后代选择器(
div p
):0,0,0,2 - 子选择器(
div>p
):0,0,0,2 - 相邻兄弟选择器(
div+p
):0,0,0,2 - 通用兄弟选择器(
div~p
):0,0,0,2
css 通过 css 选择器的权重占比,来计算 css 选择规则的总权值,从而确定 CSS 声明的优先级次序 css 选择规则的权值不同时,权值高的优先 css 选择规则的权值相同时,后定义的规则优先 css 属性后面加 !important 时,无条件绝对优先
谈谈你对 CSS 盒模型的认识
标准盒子模型,即 box-sizing content-box,浏览器默认模型,我们所写的 width 和 height 并不是最终盒子的宽高,而是 content 的,盒子的宽高由我们的 content+padding+border 来组成的,但是这样在做项目时可能会遇到小问题,假如我想构建一个 100x100 的盒子大小,但是我发现我写的是 width 和 height 是 100,于是我需要加上 padding 及 border,但是加上去之后,盒子也会相应变大,这就造成改动麻烦。
后面 css3 中提供了 IE 盒子模型,能够直接控制盒子的大小。于是项目中大多数用上了 IE 盒子模型,以及我看过 bootstrap 以及 element-ui 源码中大部分也是用的 IE 盒子模型