引言 又是一年寒冬季,只身前往沿海工作,也是我第一次感受到沿海城市冬天的寒冷。刚过完金九银十,经过一场惨烈的江湖厮杀后,相信有很多小伙伴儿已经找到了自己心仪的工作,也有的正在找工作的途中。考虑到年后必定又是一场不可避免的厮杀,这里提前记录一下自己平时遇到和总结的一些知识点,自己巩固复习加强基础的同时也希望能在你的江湖路上对你有所帮助。笔者在入职最近这家公司之前也曾有过长达3个月的闭关修炼期,期间查阅资料无数,阅读过很多文章,但总结下来真正让你印象深刻的,不是那些前沿充满神秘感的新技术,也不是为了提升代码逼格的奇淫巧技,而是那些我们经常由于项目周期紧而容易忽略的基础知识。所谓万丈高楼平地起,只有你的地基打得足够牢固,你才有搭建万丈高楼的底气,你才能在你的前端人生路上越走越远。 这篇主要是先总结一下CSS相关的知识点,可能某些部分不会涉及到太多具体的细节,主要是对知识点做一下汇总,如果有兴趣或者有疑惑的话可以自行百度查阅下相关资料或者在下方评论区留言讨论,后续文章再继续总结JS和其他方面相关的知识点,如有不对的地方还请指出。 1. CSS盒模型 CSS盒模型就是在网页设计中经常用到的CSS技术所使用的一种思维模型。CSS 假定所有的HTML 文档元素都生成了一个描述该元素在HTML文档布局中所占空间的矩形元素框,可以形象地将其看作是一个盒子。CSS 围绕这些盒子产生了一种“盒子模型”概念,通过定义一系列与盒子相关的属性,可以极大地丰富和促进各个盒子乃至整个HTML文档的表现效果和布局结构。 CSS盒模型可以看成是由从内到外的四个部分构成,即内容区(content)、内边距(padding)、边框(border)和外边距(margin)。内容区是盒子模型的中心,呈现盒子的主要信息内容;内边距是内容区和边框之间的空间;边框是环绕内容区和内边距的边界;外边距位于盒子的最外围,是添加在边框外周围的空间。 根据计算宽高的区域我们可以将其分为IE盒模型和W3C标准盒模型,可以通过box-sizing来进行设置: content-box:W3C标准盒模型 border-box:IE盒模型 区别: W3C标准盒模型:width(宽度) = content(内容宽度) IE盒模型:width(宽度) = content(内容宽度) + padding(内边距) + border(边框) 2. BFC BFC即Block Fromatting Context(块级格式化上下文),它是页面中的一块独立的渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。具有BFC特性的元素可以看成是一个隔离的独立容器,让处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。 IE浏览器下为hasLayout,一般可以通过zoom:(除normal外任意值)来触发,hasLayout是IE浏览器渲染引擎的一个内部组成部分。在IE浏览器中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和和组织内容。为了调节这两个不同的概念,渲染引擎采用了hasLayout的属性,属性值可以为true或false。当一个元素的hasLayout属性为true时,我们就说这个元素有一个布局(Layout)。当拥有布局后,它会负责对自己和可能的子孙元素进行尺寸计算和定位,而不是依赖于祖先元素来完成这些工作。 2.1 触发条件 根元素() 浮动元素(元素的float不是none) 绝对定位元素(元素的position为absolute或fixed) 行内块元素(元素的display为inline-block) 表格单元格(元素的display为table-cell,HTML表格单元格默认为该值) 表格标题(元素的display为table-caption,HTML表格标题默认为该值) display值为flow-root的元素 overflow属性的值不为visible 弹性元素(display为flex或inline-flex元素的直接子元素) 网格元素(display为grid或者inline-grid元素的直接子元素) 2.2 布局规则 普通文档流布局规则: 浮动的元素是不会被父级计算高度的 非浮动元素会覆盖浮动元素的位置 margin会传递给父级 两个相邻元素上下margin会发生重叠 BFC布局规则: 浮动的元素会被父级计算高度(父级触发了BFC) 非浮动元素不会覆盖浮动元素的位置(非浮动元素触发了BFC) margin不会传递给父级(父级触发了BFC) 两个相邻元素上下margin不会发生重叠(给其中一个元素增加一个父级,并让它的父级触发BFC) 2.3 应用 防止margin重叠 清除内部浮动(原理是父级计算高度时,浮动的子元素也会参与计算) 自适应两栏布局 防止元素被浮动元素所覆盖 3. 层叠上下文 层叠上下文(stacking context),是HTML中一个三维的概念。在CSS2.1规范中,每个盒模型的位置都是三维的,分别是平面画布上的X轴,Y轴以及表示层叠的Z轴。一般情况下,元素在页面上沿X轴Y轴平铺,我们察觉不到它们在Z轴上的层叠关系。而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖。 如果一个元素含有层叠上下文,我们就可以理解为这个元素在Z轴上就"高人一等",最终表现就是它离屏幕观察者更近。 你可以把层叠上下文理解为该元素当了官,而其他非层叠上下文元素则可以理解为普通群众。凡是"当了官的元素"就比普通元素等级要高,也就是说元素在Z轴上更靠上,更靠近观察者。 3.1 触发条件 根层叠上下文() position属性为非static值并设置z-index为具体数值 CSS3中的属性也可以产生层叠上下文 flex transform opacity filter will-change -webkit-overflow-scrolling 3.2 层叠等级 层叠等级(stacking level),又叫"层叠级别"或者"层叠水平"。 在同一个层叠上下文中,它描述定义的是该层叠上下文中的层叠上下文元素在Z轴上的上下顺序 在其他普通元素中,它描述定义的是这些普通元素在Z轴上的上下顺序 注意: 普通元素的层叠等级优先由其所在的层叠上下文决定。 层叠等级的比较只有在当前层叠上下文元素中才有意义,不同层叠上下文中比较层叠等级是没有意义的。 根据以上的层叠等级图,我们在比较层叠等级时可以按照以下的思路来顺序比较: 首先判定两个要比较的元素是否处于同一个层叠上下文中 如果处于同一个层叠上下文中,则谁的层叠等级大,谁最靠上 如果处于不同的层叠上下文中,则先比较他们所处的层叠上下文的层叠等级 当两个元素层叠等级相同,层叠顺序相同时,在DOM结构中后面的元素层叠等级在前面元素之上 4. CSS3中新增的选择器以及属性 属性选择器: 属性选择器 含义描述 E[attr^="val"] 属性attr的值以"val"开头的元素 E[attr$="val"] 属性attr的值以"val"结尾的元素 E[attr*="val"] 属性attr的值包含"val"子字符串的元素 结构伪类选择器 选择器 含义描述 E:root 匹配元素所在文档的根元素,对于HTML文档,根元素始终是 E:nth-child(n) 匹配其父元素的第n个子元素,第一个编号为1 E:nth-last-child(n) 匹配其父元素的倒数第n个子元素,第一个编号为1 E:nth-of-type(n) 与:nth-child()作用类似,但是仅匹配使用同种标签的元素 E:nth-last-of-type(n) 与:nth-last-child() 作用类似,但是仅匹配使用同种标签的元素 E:last-child 匹配父元素的最后一个子元素,等同于:nth-last-child(1) E:first-of-type 匹配父元素下使用同种标签的第一个子元素,等同于:nth-of-type(1) E:last-of-type 匹配父元素下使用同种标签的最后一个子元素,等同于:nth-last-of-type(1) E:only-child 匹配父元素下仅有的一个子元素,等同于:first-child:last-child或 :nth-child(1):nth-last-child(1) E:only-of-type 匹配父元素下使用同种标签的唯一一个子元素,等同于:first-of-type:last-of-type或 :nth-of-type(1):nth-last-of-type(1) E:empty 匹配一个不包含任何子元素的元素,文本节点也被看作子元素 E:not(selector) 匹配不符合当前选择器的任何元素 CSS3新增属性 属性 含义描述 transition 过渡效果 transform 变换效果(移动(translate)、缩放(scale)、旋转(rotate)、倾斜(skew)) transform-origin 设置旋转元素的基点位置 animation 动画效果 border-color 为边框设置多种颜色 border-radius 圆角边框 box-shadow 边框阴影 border-image 边框图片 background-size 规定背景图片的尺寸 background-origin 规定背景图片的定位区域 background-clip 规定背景图片从什么位置开始裁切 text-shadow 文本阴影 text-overflow 文本截断 word-wrap 对长单词进行拆分,并换行到下一行 opacity 不透明度 box-sizing 控制盒模型的组成模式 rgba 基于r,g,b三个颜色通道来设置颜色值,通过a来设置透明度 5. CSS3中transition和animation的属性 1) transition(过渡动画) 用法:transition: property duration timing-function delay | 属性 | 含义描述 | | ---- | ---- | | transition-property | 指定哪个CSS属性需要应用到transition效果 | | transition-duration | 指定transition效果的持续时间 | | transition-timing-function | 指定transition效果的速度曲线 | | transition-delay | 指定transition效果的延迟时间 | 2) animation(关键帧动画) 用法:animation: name duration timing-function delay iteration-count direction fill-mode play-state | 属性 | 含义描述 | | ---- | ---- | | animation-name | 指定要绑定到选择器的关键帧的名称 | | animation-duration | 指定动画的持续时间 | | animation-timing-function | 指定动画的速度曲线 | | animation-delay | 指定动画的延迟时间 | | animation-iteration-count | 指定动画的播放次数 | | animation-direction | 指定是否应该轮流反向播放动画 | | animation-fill-mode | 规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式 | | animation-play-state | 指定动画是否正在运行或已暂停 | 6. 清除浮动的方式以及各自的优缺点 额外标签法(在最后一个浮动元素的后面新加一个标签如
,并在其CSS样式中设置clear: both;) 优点:简单,通俗易懂,写少量代码,兼容性好 缺点:额外增加无语义html元素,代码语义化差,后期维护成本大 给父级设置高度 优点:简单,写少量代码,容易掌握 缺点:不够灵活,只适用于高度固定的布局 触发父级BFC(如给父元素设置overflow:hidden,特别注意的是:在IE6中还需要触发hasLayout,例如给父元素设置zoom:1。原理是触发父级BFC后,父元素在计算高度时,浮动的子元素也会参与计算) 优点:简单,代码简洁 缺点:设置overflow:hidden容易造成不会自动换行导致超出的尺寸被隐藏掉,无法显示要溢出的元素 使用after伪元素,常见的写法如下: .clearfix::after { content: "."; display: block; height: 0; line-height: 0; clear: both; visibility:hidden; font-size: 0; } .clearfix { // 注意此处是为了兼容IE6和IE7浏览器,即触发hasLayout zoom: 1; } 优点:符合闭合浮动思想,结构语义化正确 缺点:代码量多,因为IE6-7下不支持after伪元素,需要额外写zoom:1来触发hasLayout 7. 居中布局的方式 水平居中: 若是行内元素,则直接给其父元素设置text-align: center即可 若是块级元素,则直接给该元素设置margin: 0 auto即可 若子元素包含浮动元素,则给父元素设置width:fit-content并且配合margin .parent { width: -webkit-fit-content; width: -moz-fit-content; width: fit-content; margin: 0 auto; } 使用flex布局的方式,可以轻松实现水平居中,即使子元素中存在浮动元素也同样适用 // flex 2012年版本写法 .parent { display: flex; flex-direction: row; justify-content: center; } // flex 2009年版本写法 .parent { display: box; box-orient: horizontal; box-pack: center; } 使用绝对定位的方式,再配合CSS3新增的transform属性 .child { position: absolute; left: 50%; transform: translate(-50%, 0); } 使用绝对定位的方式,再配合负值的margin-left(此方法需要固定宽度) .child { position: absolute; left: 50%; width: 200px; // 假定宽度为200px margin-left: -100px; // 负值的绝对值为宽度的一半 } 使用绝对定位的方式,再配合left:0;right:0;margin:0 auto;(此方法需要固定宽度) .child { position: absolute; left: 0; right: 0; margin: 0 auto; width: 200px; // 假定宽度为200px } 垂直居中: 若元素是单行文本,则直接给该元素设置line-height等于其父元素的高度 若元素是行内块级元素,可以配合使用display:inline-block;vertical-align:middle和一个伪元素来让内容块居中 .parent::after, .child { display: inline-block; vertical-align: middle; } .parent::after { content: ""; height: 100%; } 使用vertical-align属性并且配合使用display:table和display:table-cell来让内容块居中 .parent { display: table; } .child { display: table-cell; vertical-align: middle; } 使用flex布局的方式,可以轻松实现垂直居中,即使子元素中存在浮动元素也同样适用 // flex 2012年版本写法 .parent { display: flex; align-items: center; } // flex 2009年版本写法 .parent { display: box; box-orient: vertical; box-pack: center; } 使用绝对定位的方式,再配合CSS3新增的transform属性 .child { position: absolute; top: 50%; transform: translate(0, -50%); } 使用绝对定位的方式,再配合负值的margin-top(此方法需要固定高度) .child { position: absolute; top: 50%; height: 200px; // 假定高度为200px margin-top: -100px; // 负值的绝对值为高度的一半 } 使用绝对定位的方式,再配合top:0;bottom:0;margin:auto 0;(此方法需要固定高度) .child { position: absolute; top: 0; bottom: 0; margin: auto 0; height: 200px; // 假定高度为200px } 水平垂直居中: 使用flex布局的方式同样可以轻松实现水平垂直居中 // flex 2012年版本写法 .parent { display: flex; justify-content: center; align-items: center; } // flex 2009年版本写法 .parent { display: box; box-pack: center; box-align: center; } 使用绝对定位的方式,再配合CSS3新增的transform属性 .child { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } 使用绝对定位的方式,再配合使用负值的margin-top和负值的margin-left(此方法需要同时固定宽度和高度) .child { position: absolute; left: 50%; top: 50%; margin-top: -50px; // 负值的绝对值为高度的一半 margin-left: -100px; // 负值的绝对值为宽度的一半 width: 200px; // 假定宽度为200px height: 100px; // 假定高度为100px } 8. CSS的优先级和权重 选择器(优先级从高到低) 示例 特殊性值 !important(重要性标识) div { color: #fff !important; } 无,但为了方便记忆,可将其表示为1,0,0,0,0 行内样式
1,0,0,0 id选择器 #id 0,1,0,0 类,伪类和属性选择器 .content, :first-child, [type="text"] 0,0,1,0 标签和伪元素选择器 h1, ::after 0,0,0,1 通配符、子选择器、相邻选择器 *, div > p, p + p 0,0,0,0 继承 span { color: inherit; } 无 浏览器默认值 浏览器开发者工具右侧的Styles面板中会显示user agent stylesheet字样 无 9. 移动端1px物理像素边框 我们知道,在移动端存在物理像素(physical pixel)和设备独立像素(density-independent pixel)的概念。物理像素也称为设备像素,它是显示设备中一个最微小的物理部件,每个像素可以根据操作系统设置自己的颜色和亮度。设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如CSS像素),然后由相关系统转换为物理像素。根据物理像素和设备独立像素也衍生出了设备像素比(device pixel ratio)的概念,简称为dpr,其定义了物理像素和设备独立像素的对应关系,其计算公式为设备像素比 = 物理像素 / 设备独立像素。因为视网膜(Retina)屏幕的出现,使得一个物理像素并不能和一个设备独立像素完全对等,如下图所示: 在上图中,在普通屏幕下1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素却对应4个物理像素,即在Retina屏幕下会有不同的dpr值。为了追求在移动端网页中更好的显示质量,因此我们需要做各种各样的适配处理,最经典的莫过于1px物理像素边框问题,我们需要根据移动端不同的dpr值来对边框进行处理。在JavaScript中,可以通过window.devicePixelRatio来获取当前设备的dpr,在CSS中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和-webkit-max-device-pixel-ratio来进行媒体查询,从而针对不同的设备,来做一些样式适配。这里对于1px像素的边框问题,给出一种最常见的写法: .border-1px { position: relative; } .border-1px::after { content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background-color: #000; -webkit-transform: scaleY(.5); transform: scaleY(.5); } @media only screen and (-webkit-min-device-pixel-ratio: 2.0), (min-device-pixel-ratio: 2.0) { .border-1px::after { -webkit-transform: scaleY(.5); transform: scaleY(.5); } } @media only screen and (-webkit-min-device-pixel-ratio: 3.0), (min-device-pixel-ratio: 3.0) { .border-1px::after { -webkit-transform: scaleY(.33); transform: scaleY(.33); } } 10. 实现三栏布局的方式有哪些 三栏布局,顾名思义就是分为左中右三个模块进行布局,并且左右两边固定,中间模块根据浏览器的窗口变化进行自适应,效果图如下: 这里给出四种实现三栏布局的方式: 使用绝对定位的方式 .container { position: relative; height: 200px; line-height: 200px; text-align: center; font-size: 20px; color: #fff; } .left { position: absolute; left: 0; top: 0; width: 150px; background: red; } .main { margin-left: 160px; margin-right: 110px; background: green; } .right { position: absolute; right: 0; top: 0; width: 100px; background: blue; }
优点:方便快捷,简单实用,不容易出现问题,而且还可以将
元素放到最前面,使得主要内容被优先加载。 缺点:元素脱离了文档流,可能会造成元素的重叠。 使用flex布局的方式 .container { display: flex; height: 200px; line-height: 200px; text-align: center; font-size: 20px; color: #fff; } .left { width: 150px; background: red; } .main { margin: 0 10px; flex: 1; background: green; } .right { width: 100px; background: blue; }
优点:简单实用,是现在比较流行的方案,特别是在移动端,大多数布局都采用的这种方式,是目前比较完美的一个。 缺点:需要考虑到浏览器的兼容性,根据不同的浏览器厂商需要添加相应的前缀。 双飞翼布局 .content { float: left; width: 100%; } .main, .left, .right { height: 200px; line-height: 200px; text-align: center; font-size: 20px; color: #fff; } .main { margin-left: 160px; margin-right: 110px; background: green; } .left { float: left; margin-left: -100%; width: 150px; background: red; } .right { float: right; margin-left: -100px; width: 100px; background: blue; }
优点:比较经典的一种方式,通用性强,没有兼容性问题,而且支持主要内容优先加载。 缺点:元素脱离了文档流,要注意清除浮动,防止高度塌陷,同时额外增加了一层DOM结构,即增加了渲染树生成的计算量。 圣杯布局 .container { margin-left: 160px; margin-right: 110px; } .left, .main, .right { height: 200px; line-height: 200px; text-align: center; font-size: 20px; color: #fff; } .main { float: left; width: 100%; background: green; } .left { position: relative; left: -160px; margin-left: -100%; float: left; width: 150px; background: red; } .right { position: relative; right: -110px; margin-left: -100px; float: left; width: 100px; background: blue; }
优点:相比于双飞翼布局,结构更加简单,没有多余的DOM结构层,同样支持主要内容优先加载。 缺点:元素同样脱离了文档流,要注意清除浮动,防止高度塌陷。 11. 实现等高布局的方式有哪些 等高布局,顾名思义就是在同一个父容器中,子元素高度相等的布局。从等高布局的实现方式来说,可以分为两种,分别是伪等高和真等高。伪等高是指子元素的高度差依然存在,只是视觉上给人的感觉就是等高,真等高是指子元素的高度真实相等。效果图如下: 这里给出五种实现等高布局的方式: 伪等高: 使用padding-bottom和负的margin-bottom来实现 .container { position: relative; overflow: hidden; } .left, .main, .right { padding-bottom: 100%; margin-bottom: -100%; float: left; color: #fff; } .left { width: 20%; background: red; } .main { width: 60%; background: green; } .right { width: 20%; background: blue; }