开头
这些题都是我们在面试中很常见到的题型,面试官也很喜欢问,反正不要畏惧不要慌,淦就完了,奥里给给!
HTML5新特性
-
拖拽释放(Drag and drop) API Drag API详情参考这里
-
语义化更好的内容标签
(header,nav,footer,aside,article,section) -
音频、视频API(audio,video)
-
画布(Canvas) API
-
地理(Geolocation) API
-
本地离线存储
localStorage长期存储数据,浏览器关闭后数据不丢失; -
sessionStorage的数据在浏览器关闭后自动删除 -
表单控件,
calendar、date、time、email、url、search -
新技术
webWorker、webSocket、Geolocation
为什么使用语义化标签?
- 去掉样式或者样式丢失时页面结构依然清晰分明
- 阅读器会根据标签的语义自动解析,呈现更容易阅读的内容形式(无障碍阅读)
- 搜索引擎优化
- 便于后期开发和维护
CSS选择器优先级
!important最高- 内联样式 1000
- ID选择器 0100
- 类选择器 / 属性选择器 /伪类选择器 0010
- 元素选择器 / 伪元素选择器 0001
- 关系选择器 / 通配符选择器 0000
常见行内元素、块级元素和行内块级元素
-
块级元素:总是独占一行,可以设置高度和宽度。没有设置宽度时为100%。常见的块级元素有:
h1-h6hr(水平分割线)、div、p(段落)、ul(无序列表)、ol(有序列表)、form(表单) -
行内元素:和其它元素在一行,不可以设置高度、宽度和内边距。 宽高就是内容的高度,依靠自身字体大小和图形支撑结构,不可以改变 。可以设置
padding和margin-left以及margin-right(top和bottom无法设置)。常见行内元素有:span、input、a、b/strong(加粗)、i/em(斜体)、del(删除线)、u(下划线) -
行内块级元素: 综合块级元素与行内元素的特性, 可以设置宽高(默认是内容宽高),也可以设置内外边距 。常见的有:
img、button、textarea、audio、video等
盒模型
盒模型就是我们可以把元素看成一个盒子,它包括外边距(margin)、边框(border)、内边距(padding)、实际内容(content)
其中盒模型又分为标准盒模型和IE盒模型(怪异盒模型),可以通过box-sizing来设置,它有两个属性可以分别设置这两种模型,content-box指定盒子模型为标准盒模型,border-box为IE盒子模型(怪异盒模型)。
我们再来说一下这两种模型的区别:
- 标准盒模型:设置元素的高度和宽度实际上就是设置内容(
content)的宽高,我们设置width和height其实就是设置content的宽高,padding和border的值其实是另外算的。 盒子总宽度=width+padding+border+margin - 怪异盒模型:设置元素的宽度和高度是同时设置
content、padding、border这三者的总和,盒子内边距加边框和内容就等于我们设置的宽高。 盒子总宽度=width(包含padding+border)+margin
下面放张图可以对比一下两种模型的区别:
BFC的理解
BFC 全称为块级格式化上下文 (Block Formatting Context) 。一个BFC盒子是独立布局的,盒子里面的子元素布局不会影响到外面的元素。在同一个 BFC 中的两个毗邻的块级盒在垂直方向(和布局方向有关系)的 margin 会发生折叠。
咋去触发BFC?
只要元素满足下面任一条件就能触发 BFC :
- body根元素
- 浮动元素(除none之外的属性)
- 绝对定位元素(
absolut、fixed) display为inline-block、table-cells、flexoverflow除了visible以外的值(hidden、auto、scroll)
BFC的作用是啥子?
-
利用BFC避免margin重叠。上面说到了,在同一个BFC盒子里的两个元素会发生上下边距重叠。想要避免外边距的重叠,可以将元素放在两个不同的 BFC 容器中。
-
利用BFC做自适应的两栏布局,其实最简单的方式就是用flex去触发BFC然后实现两栏布局,一样的道理,三栏布局也是可以的。
-
清除浮动,这是老生常谈的问题了,清除浮动的方法也有很多:
-
额外标签法(在最后一个浮动标签后,新加一个标签,给其设置
clear:both;)缺点是添加了无意义的标签,语义化太差,所以很少使用这个。 -
父级添加
overflow属性(父元素添加overflow:hidden;),缺点就是盒子里内容比较多的时候不会自动换行,溢出的内容会被隐藏掉 -
使用
after伪元素清除浮动 ,大概是介样子的,这种方式比较推荐使用,就是对低版本IE浏览器支持不太好(业界毒瘤,Vue3都放弃了,谁还管它).clearfix:after{ content: ""; display: block; height: 0; clear:both; visibility: hidden; } -
使用
before和after双伪元素清除浮动 ,这种方式也推荐使用。8过感觉现在大部分时候都用flex来布局了,大部分浏览器对flex也支持得很好了,实在要兼容一些低版本浏览器的时候才去用浮动布局。.clearfix:after, .clearfix:before{ content: ""; display: table; } .clearfix:after{ clear: both; }
-
关于Rem和em
-
Rem(font-size-of-the-root-element): rem是相对于
根元素<html>来设置字体大小的 ,看下下面的代码,我们改变根元素的font-size就可以对不同的移动设备进行字体大小的适配。//该模块实现移动端rem布局 function remSize() { let deviceWidth = document.documentElement.clientWidth || window.innerWidth //获取屏幕宽度 if (deviceWidth >= 750) { deviceWidth = 750 //pc端屏幕宽度如果大于750也直接设置成750 } if (deviceWidth <= 320) { deviceWidth = 320 //移动端屏幕宽度不能小于320 } //设计稿是750px //设置一半的宽度。就是375px //1rem = 100px的设计稿宽度 //一半宽度rem就是 3.75rem document.documentElement.style.fontSize = (deviceWidth / 7.5) + 'px' //设置默认字体大小 document.body.style.fontSize = 0.3 + 'rem' } remSize() window.onresize = function () { remSize() } -
em: em是相对其父元素来设置字体大小,如果对于浏览器来说 1em = 16px,浏览器默认字体大小为16px。这个单位会有一些问题,比如某元素可能继承其父元素的字体大小,而父元素又继承其父元素的字体大小
(套娃,套它🐒的)。 因此,以 em 为单位的元素字体大小可能会受到其任何父元素的字体大小影响。
让行内元素水平和垂直居中
给父元素设置text-align和line-height
div {
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
}
然后div里面的所有行内元素都可以水平垂直居中了
让块级元素垂直和水平居中
1.绝对定位+margin:auto
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.parent {
position: relative;
width: 300px;
height: 300px;
background-color: hotpink;
}
.child {
position: absolute;
width: 100px;
height: 100px;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: pink;
}
</style>
</head>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
</html>
2.绝对定位+transform
将上面css代码的child分别换成如下代码
.child {
position: absolute;
width: 100px;
height: 100px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: pink;
}
3.使用Flex布局
上面的css代码中的parent和child分别改成如下代码
.parent {
width: 300px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
background-color: hotpink;
}
.child {
width: 100px;
height: 100px;
background-color: pink;
}
4.使用grid布局
上面的css代码中的parent和child分别改成如下代码,该方法目前浏览器兼容性还不是特别好
.parent {
display: grid;
width: 300px;
height: 300px;
background-color: hotpink;
}
.child {
width: 100px;
height: 100px;
justify-self: center;
align-self: center;
background-color: pink;
}
上面几种就是比较常见的让元素水平和垂直居中方法了,他们的效果都是一样的,如下是效果图
两列布局
这种布局方式比较简单,但是面试也很常问。这里就说一下常见的几种方法吧,首先写好布局
<body>
<div class="content">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
</div>
</div>
</body>
然后我们可以用几种方式去设置,在此之前我们要先设置
* {
margin: 0;
padding: 0;
}
下面说的几种布局方式都是左侧固定,右侧自适应的
1.使用float+margin-left
.left{
background: pink;
width: 200px;
float: left;
}
.right{
background: hotpink;
margin-left: 210px;
}
2.双左浮动+calc
.left {
float: left;
width: 200px;
background-color: pink;
}
.right {
float: left;
margin-left: 10px;
width: calc(100% - 210px);
background-color: hotpink;
}
3.使用绝对定位
.content{
position: relative;
width: 100%;
height: 500px;
}
.left{
background: pink;
width: 200px;
position: absolute;
}
.right{
background: hotpink;
position: absolute;
left: 210px;
right: 0;
}
3.使用flex布局
.content{
width: 100%;
height: 500px;
display:flex;
}
.left{
background: pink;
width: 200px;
margin-right:10px;
}
.right{
background: hotpink;
flex:1;
}
4.float和BFC
设置右侧overflow:hidden触发BFC
.left {
float: left;
width: 200px;
background-color: pink;
}
.right {
margin-left: 210px;
overflow: hidden;
background-color: hotpink;
}
我们可以看到以上几种的表现方式都是这样子的
[提醒:使用浮动的方式记得要清除浮动],我们在上面已经说过几种清除浮动的方式咯
三列布局
圣杯布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.container {
padding: 0 100px;
}
.middle,
.left,
.right {
position: relative;
float: left;
}
.left {
width: 100px;
height: 100px;
background: red;
margin-left: -100%;
left: -100px;
}
.right {
width: 100px;
height: 100px;
background: green;
margin-left: -100px;
right: -100px;
}
.middle {
background: blue;
width: 100%;
height: 300px;
}
</style>
</head>
<body>
<div class="container">
<div class="middle"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
另外两种版本分别是使用绝对定位和flex布局,这两种版本更好理解。下面贴出代码
绝对定位版:
<style>
* {
margin: 0;
padding: 0;
}
.container {
position: relative;
}
.left,
.right {
top: 0;
}
.middle {
margin: 0 100px;
height: 300px;
background-color: hotpink;
}
.left {
position: absolute;
left: 0;
width: 100px;
height: 100px;
background-color: pink;
}
.right {
position: absolute;
right: 0;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
flex版本:
<style>
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
overflow: hidden;
}
.middle {
flex: 1;
height: 200px;
background-color: hotpink;
}
.left {
order: -1;
flex-basis: 100px;
height: 100px;
background-color: pink;
}
.right {
flex-basis: 100px;
height: 100px;
background-color: pink;
}
</style>
效果图都是像下面这样滴
双飞翼布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.container {
overflow: hidden;
}
.middle,
.left,
.right {
float: left;
height: 100px;
}
.left {
width: 100px;
background: pink;
margin-left: -100%;
}
.right {
width: 100px;
background: pink;
margin-left: -100px;
}
.middle {
width: 100%;
background: hotpink;
}
.inner {
margin: 0 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="middle">
<div class="inner"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
</head>
</body>
</html>
flex版本:
<style>
* {
padding: 0;
margin: 0;
}
.container {
display: flex;
}
.middle,
.left,
.right {
height: 100px;
}
.middle {
flex: 1;
background-color: hotpink;
}
.left {
order: -1;
flex-basis: 100px;
background-color: pink;
}
.right {
flex-basis: 100px;
background-color: pink;
}
</style>
两者区别
两者都是为了不让左右俩个东西遮住middle,经典圣杯布局通过父亲padding给左右俩腾位置从而不会遮住middle内容,而双飞翼是middle设置margin,限制内部内容区域,从而左右俩遮的地方不会影响到middle内容
对于三栏布局,最优解其实还是flex布局,当然用grid布局也行,只是兼容性没那么好,这两种方式都可以轻松实现多列布局,也可以控制顺序,middle依然可以先渲染,不管IE浏览器的话,最优解还是flex布局(业界毒瘤IE)
重绘和重排(回流)
-
重绘:给元素设置一些CSS样式,但不改变形状。比如说
visibility、color、background-color、outline这些之类的就会触发重绘,重绘不会重新布局。重绘不一定重排。 -
重排:元素发生形状的变化,位置的变化,渲染树需要重新计算就会触发重排。像设置
display:none;页面首次渲染、激活伪类元素如:hover、增删DOM元素、移动元素位置,改变窗口大小这些都会发生重排。重排必定重绘。
如何优化?
-
减少重绘和重排的发生次数:比如我们修改元素的样式,可以将多次修改合并成一次修改
const el = document.querySelector('.test') el.style.margin = '5px' el.style.paddingTop = '2px' el.style.paddingBottom = '5px'这里对DOM元素进行了多次的样式修改,每一次修改都会触发重排(现代浏览器已经做过优化,会合并成一次重排。但是旧的浏览器还是会触发多次)。所以我们就需要进行合并处理
const el = document.querySelector('.test') el.style.cssText += 'margin: 5px; padding-top: 2px; padding-bottom: 5px;'或者直接给el添加一个新的样式类
const el = document.querySelector('.test') el.className += ' test2' -
批量对DOM元素进行修改:
1.先让元素脱离文档流,然后
display:none隐藏元素,对DOM元素进行修改,然后display: block重新显示。这里隐藏和显示DOM元素会触发重排,但是对DOM元素修改的过程并不会,这样可以减少重排次数2.使用文档片段
document.createDocumentFragment()const ul = document.querySelector("ul") const fragment = document.createDocumentFragment() for (let i = 0; i < 20; i++) { let li = document.createElement("li") li.innerHTML = "index: " + i fragment.appendChild(li) } ul.appendChild(fragment); -
对于复杂动画,可以将其设置为绝对定位,脱离文档流,不然会引起它的父元素和后续元素进行频繁的重排
-
CSS优化:
1.避免使用table布局
2.避免设置内联样式
3.少用calc表达式,会频发触发重排
4.将动画设置到脱离文档流的元素上面
-
使用CSS3的硬件加速:可以触发硬件加速的属性有:
transform(过渡)、opacity(透明度)、filters(滤镜)、will-changewill-change属性参考
z-index什么时候会失效
- 父标签的position设置为relative
- 父标签的z-index设置得特别小的时候
- 问题标签没有设置position(除了static)以外的属性
- 问题标签设置了浮动
总结
大部分公司都是喜欢一开始先来问几道CSS的题,所以我们还是要注重这一块,这里的题都是常见题,有必要好好去掌握