Web前端基础知识:CSS篇

301 阅读30分钟

先导

个人在学习过程中,涉及和遇见的一些基础知识,对其进行了简单归纳总结,浅尝辄止,略显杂而不精,做个人参考用

注:内容基本都是摘抄自博客、网络或MDN等

CSS

1、盒模型:box-sizing

CSS 中的 box-sizing属性定义了user agent 应该如何计算一个元素的总宽度和总高度。

content-box 是默认值。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。

border-box 告诉浏览器:你想要设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含它的borderpadding,内容区的实际宽度是width减去(border + padding)的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。


2、CSS定位

取值说明
static默认值,静态定位,表示没有定位,元素会按照正常的位置显示,此时 top、bottom、left 和 right 4 个定位属性也不会被应用。
relative相对定位,即相对于元素的正常位置进行定位,您可以通过 top、right、bottom、left 这 4 个属性来设置元素相对于正常位置的偏移量,在此过程中不会对其它元素造成影响。
absolute绝对定位,相对于第一个非 static 定位的父级元素进行定位,可以通过 top、right、bottom、left 这 4 个属性来设置元素相对于父级元素位置的偏移量。如果没有满足条件的父级元素,则会相对于浏览器窗口来进行定位。使用绝对定位的元素不会对其它元素造成影响。
fixed固定定位,相对于浏览器的创建进行定位,可以使用 top、right、bottom、left 这 4 个属性来定义元素相对于浏览器窗口的位置。使用固定定位的元素无论如何滚动浏览器窗口元素的位置都是固定不变的。
sticky粘性定位,它是 relative 和 fixed 的结合体,能够实线类似吸附的效果,当滚动页面时它的效果与 relative 相同,当要滚动到屏幕之外时则会自动变成 fixed 的效果。sticky元素效果完全受制于父级元素们

3、CSS浏览器兼容性

解决思路:浏览器CSS样式初始化、浏览器私有属性,CSS hack语法和自动化插件。

1). CSS初始化/css reset

解决浏览器默认样式不同导致的错乱问题,目的是将所有的浏览器的自带样式重置掉,这样更易于保持各浏览器渲染的一致性。

Normalize.cssnormalize 的理念则是尽量保留浏览器的默认样式,不进行太多的重置,而尽力让这些样式保持一致并尽可能与现代标准相符合。

2). 浏览器私有属性

-webkit--moz--ms-等前缀

  • -webkit- (谷歌,Safari,新版Opera浏览器,以及几乎所有iOS系统中的浏览器(包括 iOS 系统中的火狐浏览器);基本上所有基于WebKit 内核的浏览器)
  • -moz- (火狐浏览器)
  • -o- (旧版Opera浏览器)
  • -ms- (IE浏览器 和 Edge浏览器)

通过自动化插件来优化

3). CSS hack

针对不同的浏览器甚至不同版本编写特定的CSS样式,这一过程就叫做CSS hack!

  • 条件hack
<!--[if <keywords>? IE <version>?]>
// 代码块,可以是html,css,js
<![endif]-->
  • 属性hack 在CSS样式属性名前加上一些只有特定浏览器才能识别的hack前缀。

    selector{<hack>?property:value<hack>?;}

  • 选择符级hack

    针对一些页面表现不一致或者需要特殊对待的浏览器,在CSS选择器前加上一些只有某些特定浏览器才能识别的前缀进行hack

    <hack> selector{ sRules }

4). 浏览器前缀解决方案

Autoprefixer是一款自动管理浏览器前缀的插件,它可以解析CSS文件并且添加浏览器前缀到CSS内容里。

webpack环境下,可以使用 postcss-loader 自动添加私有前缀


4、link@import的区别?

  1. link 是 HTML 标签,除了加载 CSS 外,还可以定义 RSS 等其他事务;@import 属于 CSS 范畴,只能加载 CSS 。
  2. link 引用 CSS 时,在页面载入时同时加载; @import 需要页面网页完全载入以后加载。
  3. link 是 HTML 标签,无兼容问题;@import 是在 CSS2.1 提出的,低版本的浏览器不支持。
  4. link 支持使用 Javascript 控制 DOM 去改变样式;而 @import 不支持。

5、浏览器解析渲染机制

Chrome 渲染

  • 解析HTML,生成DOM树,解析CSS,生成CSSOM树, 渲染引擎开始解析html,并将标签转化为内容树中的dom节点

  • 将DOM树和CSSOM树结合,生成渲染树(Render Tree), 通过解析外部CSS文件及style标签中的样式信息。这些样式信息以及html中的可见性指令将被用来构建render树。Render树由一些包含有颜色和大小等属性的矩形组成,它们将被按照正确的顺序显示到屏幕上。

  • Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)

  • Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素

  • Display:将像素发送给GPU,展示在页面上

具体细节:

DOM和CSSOM的构建:字节数据==>字符串==>Token==>Node==>DOM/CSSOM

注意点:

  • 以上4个过程并不是以严格顺序执行的,所以内容有时会在样式还没有加载的时候展示出来。(导致FOCU或白屏问题)
  • 回流是位置和机会信息
  • 重绘是颜色、文本等显示样式
  • 回流一定会触发重绘

知识点:

  1. 一般情况下DOM树和css om树是并行的,但是可能由于引入JS,CSSOM也开始阻塞DOM的构建,只有CSSOM构建完毕后,DOM再恢复DOM构建。

  2. JS的加载、解析与执行会阻塞DOM的构建,也可能会导致CSSOM树取阻塞DOM树的构建

  • 因为JavaScript不只是可以改DOM,它还可以更改样式,也就是它可以更改CSSOM,不完整的CSSOM是无法使用的,但JavaScript中想访问CSSOM并更改它,那么在执行JavaScript时,必须要能拿到完整的CSSOM,导致阻塞)
  1. 相关问题


6、重排/回流(reflow)和重绘(repaint

简单地总结下两者的概念:

重排/回流:无论通过什么方式影响了元素的位置和几何信息(元素在视口内的位置和尺寸大小),浏览器需要重新计算元素在视口内的几何属性,这个过程叫做重排。简单的说就是重新生成布局,重新排列元素。

举例:

  • 页面初始渲染,这是开销最大的一次重排
  • 添加/删除可见的DOM元素
  • 改变元素位置
  • 改变元素尺寸,比如边距、填充、边框、宽度和高度等
  • 改变元素内容,比如文字数量,图片大小等
  • 改变元素字体大小
  • 改变浏览器窗口尺寸,比如resize事件发生时
  • 激活CSS伪类(例如::hover
  • 设置 style 属性的值,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow
  • 查询某些属性或调用某些计算方法:offsetWidthoffsetHeight

影响范围:

  • 全局范围:从根节点html开始对整个渲染树进行重新布局。
  • 局部范围:对渲染树的某部分或某一个渲染对象进行重新布局

重绘:当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。简单地说,重绘是填充像素的过程。它涉及绘出文本、颜色、图像、边框 和阴影,基本上包括元素的每个可视部分。在重绘阶段,系统会遍历渲染树,并调用渲染对象的 paint 方法,将渲染对象的内容显示在屏幕上。

页面初始渲染时:浏览器通过构造渲染树重排(回流) 阶段,可以知道哪些节点是可见的,以及可见节点的样式和具体的几何信息(元素在视口内的位置和尺寸大小),接下来就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘。

总结:重绘不一定导致重排,但重排一定会导致重绘。

如何减少重排和重绘?

最小化重绘和重排

  • 样式集中改变,使用添加新样式类名 .class 或 cssText 。
  • 批量操作 DOM,比如读取某元素 offsetWidth 属性存到一个临时变量,再去使用,而不是频繁使用这个计算属性;又比如利用 document.createDocumentFragment() 来添加要被添加的节点,处理完之后再插入到实际 DOM 中。
  • 使用 absolutefixed 使元素脱离文档流,这在制作复杂的动画时对性能的影响比较明显。
  • 开启 GPU 加速,利用 css 属性 transformwill-change 等,比如改变元素位置,我们使用 translate 会比使用绝对定位改变其 left 、top 等来的高效,因为它不会触发重排或重绘,transform 使浏览器为元素创建⼀个 GPU 图层,这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘。

7、BFC

1)BFCIFC

BFC 即块级格式上下文,

IFC(Inline Formatting Context)即行内格式化上下文。常规流(也称标准流、普通流)是一个文档在被显示时最常见的布局形态。

一个框在常规流中必须属于一个格式化上下文,可以把BFC想象成一个大箱子,箱子外边的元素将不与箱子内的元素产生作用。

2)BFC的理解和特性

W3C官方解释为:

BFC它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时,Block Formatting Context提供了一个环境,HTML在这个环境中按照一定的规则进行布局。

简单来说就是,BFC是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。那么怎么使用BFC呢,BFC可以看做是一个CSS元素属性

根据盒模型可知,每个元素都被定义为一个矩形盒子,然而盒子的布局会受到尺寸,定位,盒子的子元素或兄弟元素,视口的尺寸等因素决定,所以这里有一个浏览器计算的过程,计算的规则就是由一个叫做视觉格式化模型的东西所定义的,BFC 就是来自这个概念,它是 CSS 视觉渲染的一部分,用于决定块级盒的布局及浮动相互影响范围的一个区域

总结:具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。

特性:

  1. 块级元素会在垂直方向一个接一个的排列,和文档流的排列方式一致。
  2. 在 BFC 中上下相邻的两个容器的 margin  会重叠,创建新的 BFC 可以避免外边距重叠
  3. 计算 BFC 的高度时,需要计算浮动元素的高度
  4. BFC 区域不会与浮动的容器发生重叠。
  5. BFC 是独立的容器,容器内部元素不会影响外部元素。
  6. 每个元素的左 margin 值和容器的左 border 相接触。

利用这些特性,我们可以解决以下问题:

  • 利用 4  和 6 ,我们可以实现三栏(或两栏)自适应布局。
  • 利用 2 ,我们可以避免 margin  重叠问题。
  • 利用 3 ,我们可以避免高度塌陷。

创建 BFC 的方式:

  • 绝对定位元素(position 为 absolute 或 fixed )。
  • 行内块元素,即 display 为 inline-block 。
  • overflow 的值不为 visible 。
  • display: table-cell、display: flex

8、水平垂直居中实现

  1. 利用绝对定位,设置 left: 50% top: 50% 现将子元素左上角移到父元素中心位置,然后再通过 translate 来调整子元素的中心点到父元素的中心。该方法可以不定宽高。
.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
  1. 利用绝对定位,子元素所有方向都为 0 ,将 margin 设置为 auto ,由于宽高固定,对应方向实现平分,该方法必须盒子有宽高。
.father {
  position: relative;
}
.son {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0px;
  margin: auto;
  height: 100px;
  width: 100px;
}
  1. 利用绝对定位,设置 left: 50% top: 50% 现将子元素左上角移到父元素中心位置,然后再通过 margin-leftmargin-top 以子元素自己的一半宽高进行负值赋值。该方法必须定宽高。
.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 200px;
  height: 200px;
  margin-left: -100px;
  margin-top: -100px;
}
  1. 利用 flex ,最经典最方便的一种
.father {
  display: flex;
  justify-content: center;
  align-items: center;
}
  1. 利用display: griddisplay: table-cell
.container {
  display: grid;
  place-items: center;
  // place-content: center;
}

9、flex布局详解

属性总览

属性描述
display指定 HTML 元素的盒子类型
flex-direction指定弹性盒子中子元素的排列方式
flex-wrap设置当弹性盒子的子元素超出父容器时是否换行
flex-flowflex-direction 和 flex-wrap 两个属性的简写
justify-content设置弹性盒子中元素在主轴(横轴)方向上的对齐方式
align-items设置弹性盒子中元素在侧轴(纵轴)方向上的对齐方式
align-content修改 flex-wrap 属性的行为,类似 align-items,但不是设置子元素对齐,而是设置行对齐
order设置弹性盒子中子元素的排列顺序
align-self在弹性盒子的子元素上使用,用来覆盖容器的 align-items 属性
flex设置弹性盒子中子元素如何分配空间
flex-grow设置弹性盒子的扩展比率
flex-shrink设置弹性盒子的收缩比率
flex-basis设置弹性盒子伸缩基准值

1)容器属性

  1. flex-direction: 决定主轴的方向(即项目的排列方向)
描述
row默认值,主轴沿水平方向从左到右
row-reverse主轴沿水平方向从右到左
column主轴沿垂直方向从上到下
column-reverse主轴沿垂直方向从下到上
initial将此属性设置为属性的默认值
inherit从父元素继承此属性的值
  1. flex-wrap: 设置当弹性盒子的子元素(项目)超出父容器时是否换行
描述
nowrap默认值,表示项目不会换行
wrap表示项目会在需要时换行
wrap-reverse表示项目会在需要时换行,但会以相反的顺序
initial将此属性设置为属性的默认值
inherit从父元素继承属性的值
  1. flex-flowflex-directionflex-wrap 两个属性的简写

flex-flow: flex-direction flex-wrap;

  1. justify-content:设置弹性盒子中元素在主轴(横轴)方向上的对齐方式
描述
flex-start默认值,左对齐
flex-end右对齐
center居中
space-between两端对齐,项目之间的间隔是相等的
space-around每个项目两侧的间隔相等
initial将此属性设置为属性的默认值
inherit从父元素继承属性的值
  1. align-items: 设置弹性盒子中元素在侧轴(纵轴)方向上的对齐方式
描述
stretch默认值,项目将被拉伸以适合容器
center项目位于容器的中央
flex-start项目位于容器的顶部
flex-end项目位于容器的底部
baseline项目与容器的基线对齐
initial将此属性设置为属性的默认值
inherit从父元素继承属性的值
  1. align-content:justify-content 属性类似,可以在弹性盒子的侧轴还有多余空间时调整容器内项目的对齐方式
描述
stretch默认值,将项目拉伸以占据剩余空间
center项目在容器内居中排布
flex-start项目在容器的顶部排列
flex-end项目在容器的底部排列
space-between多行项目均匀分布在容器中,其中第一行分布在容器的顶部,最后一行分布在容器的底部
space-around多行项目均匀分布在容器中,并且每行的间距(包括离容器边缘的间距)都相等
initial将此属性设置为属性的默认值
inherit从父元素继承该属性的值

2)项目属性

(1)order

order 属性用来设置项目在容器中出现的顺序,您可以通过具体的数值来定义项目在容器中的位置

order: number; number 就是项目在容器中的位置,默认值为 0。

(2)align-self

align-self 属性允许您为某个项目设置不同于其它项目的对齐方式,该属性可以覆盖 align-items 属性的值

描述
auto默认值,表示元素将继承其父容器的 align-items 属性值,如果没有父容器,则为“stretch”
stretch项目将被拉伸以适合容器
center项目位于容器的中央
flex-start项目位于容器的顶部
flex-end项目位于容器的底部
baseline项目与容器的基线对齐
initial将此属性设置为属性的默认值
inherit从父元素继承属性的值

(3)flex

flex 属性是 flex-grow、flex-shrink 和 flex-basis 三个属性的简写,语法格式如下:

flex: flex-grow flex-shrink flex-basis;

参数说明如下:

  • flex-grow:(必填参数)一个数字,用来设置项目相对于其他项目的增长量,默认值为 0;
  • flex-shrink:(选填参数)一个数字,用来设置项目相对于其他项目的收缩量,默认值为 1;
  • flex-basis:(选填参数)项目的长度,合法值为 auto(默认值,表示自动)、inherit(表示从父元素继承该属性的值) 或者以具体的值加 "%"、"px"、"em" 等单位的形式。

示例:

flex:1 = flex: 1 1 0%;:在父元素尺寸不足的时候,会优先最小化内容尺寸。

flex:auto = flex: 1 1 auto;:在父元素尺寸不足的时候,会优先最大化内容尺寸。


10、CSS布局相关

1)基础概念

1. 物理像素(physical pixel)

物理像素又被称为设备像素,它是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。正是这些设备像素的微小距离欺骗了我们肉眼看到的图像效果。

2. 设备独立像素(density-independent pixel)

设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素) ,然后由相关系统转换为物理像素。

3. CSS像素

CSS像素是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。一般情况之下,CSS像素称为与设备无关的像素(device-independent pixel),简称DIPs。

4. 屏幕密度

屏幕密度是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算(PPI)。

5. 设备像素比(DPR)

设备像素比简称为dpr,其定义了物理像素和设备独立像素的对应关系。它的值可以按下面的公式计算得到:

设备像素比 = 物理像素 / 设备独立像素

在Javascript中,可以通过 window.devicePixelRatio 获取到当前设备的dpr。

在css中,可以通过 -webkit-device-pixel-ratio-webkit-min-device-pixel-ratio-webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配。

或者使用 resolution | min-resolution | max-resolution 这些比较新的标准方式

6. 位图像素

一个位图像素是栅格图像(如:png, jpg, gif等)最小的数据单元。每一个位图像素都包含着一些自身的显示信息(如:显示位置,颜色值,透明度等)。

理论上,1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示

7. 缩放比 scale

缩放比:scale = 1/dpr

8. 视窗 viewport

简单的理解,viewport是严格等于浏览器的窗口。

  • 桌面浏览器中,viewport就是浏览器窗口的宽度高度。但在移动端设备上就有点复杂。
  • 移动端的viewport太窄,为了能更好为CSS布局服务,所以提供了两个viewport:
    • 虚拟的visualviewport
    • 布局的layoutviewport

9. 视窗单位

  • vw: 1vw 等于视窗宽度的1%
  • vh: 1vh 等于视窗高度的1%
  • vmin: 选取 vw 和 vh 中最小的那个
  • vmax: 选取 vw 和 vh 中最大的那个

2)PC端

经典布局:

参考链接:各种常见布局实现

1)两栏布局

  1. 利用浮动,左边元素宽度固定 ,设置向左浮动。将右边元素的 margin-left 设为固定宽度 。注意,因为右边元素的 width 默认为 auto ,所以会自动撑满父元素。
  2. 同样利用浮动,左边元素宽度固定 ,设置向左浮动。右侧元素设置 overflow: hidden; 这样右边就触发了 BFC ,BFC 的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠。
  3. 利用 flex 布局,左边元素固定宽度,右边的元素设置 flex: 1
  4. 利用绝对定位,父级元素设为相对定位。左边元素 absolute 定位,宽度固定。右边元素的 margin-left 的值设为左边元素的宽度值。(子绝父相)
  5. 利用绝对定位,父级元素设为相对定位。左边元素宽度固定,右边元素 absolute 定位, left 为宽度大小,其余方向定位为 0 。

总结:浮动、子绝父相、flex

2)三分栏布局

  • 三栏布局,中间一栏最先加载和渲染(内容最重要,这就是为什么还需要了解这种布局的原因)。
  • 两侧内容固定,中间内容随着宽度自适应。
  • 一般用于 PC 网页。

技术总结:

  • float 布局。
  • 两侧使用 margin 负值,以便和中间内容横向重叠。
  • 防止中间内容被两侧覆盖,圣杯布局用 padding ,双飞翼布局用 margin。

关键点

margin 负值:

为了方便理解负值margin,我们引入参考线的定义,参考线就是就是margin移动的基准点,而margin的值就是移动的数值。

margin的参考线有两类:

一类是top、left,它们以外元素作为参考线,

另一类是right、bottom,它们以自身作为参考线。

1.margin-left,margin-right为负值

  • 元素本身没有宽度,会增加元素宽度
  • 元素本身有宽度,会产生位移

2.margin-top为负值,不管是否设置高度,都不会增加高度,而是会产生向上的位移

3.margin-bottom为负值的时候不会位移,而是会减少自身供css读取的高度.

3)移动端

参考链接:REM布局与vw布局

1. viewport适配

根据设计稿标准(750px 宽度)开发页面,写完后页面及元素自动缩小,适配 375 宽度的屏幕

<!-- 在 head 里设置如下代码:  initial-scale = 屏幕的宽度 / 设计稿的宽度 -->
<meta name="viewport" content="width=750,initial-scale=0.5">

<!--  为了适配其他屏幕,需要动态的设置 initial-scale 的值 -->
<head>
  <script>
    const WIDTH = 750
    const mobileAdapter = () => {
      let scale = screen.width / WIDTH
      let content = `width=${WIDTH}, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}`
      let meta = document.querySelector('meta[name=viewport]')
      if (!meta) {
        meta = document.createElement('meta')
        meta.setAttribute('name', 'viewport')
        document.head.appendChild(meta)
      }
      meta.setAttribute('content',content)
    }
    mobileAdapter()
    window.onorientationchange = mobileAdapter //屏幕翻转时再次执行
  </script>
</head>

2. REM布局

rem布局的核心是设置好根html元素的font-size

1px在高清屏幕中的显示问题:

在REM布局中普遍采用的是viewport scale 视窗缩放的方式,就是直接将meta标签中的scale进行更改

根据不同屏幕宽度,设置 html 的 font-size

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
  <script>
    const WIDTH = 750 //设计稿尺寸
    const setView = () => {
      document.documentElement.style.fontSize = (100 * screen.width / WIDTH) + 'px'
    }
    window.onorientationchange = setView
    setView()
  </script>
</head>

另一种实现参考:

rem(倍数) = width / (html的font-size)

计算并设置html根元素的fontSize的大小,并监听resize事件更新fontSize的大小 rem只是等比缩放,只解决了响应式布局的准则 的部分问题 ,还需要配合媒体查询

// 原始配置
function setRem () {
  let doc = document.documentElement
  let width = doc.getBoundingClientRect().width
  let rem = width / 75
  doc.style.fontSize = rem + 'px'
}
// 监听窗口变化
addEventListener("resize", setRem)

3. VW布局

REM布局中用到了JS来动态设置htmlfont-size,可能造成页面的抖动。

在REM布局中处理1px问题是用了视窗缩放的方案,在VW布局中就不用了,转而使用容器缩放(transform)的方案

调用方式形如:height: px2vw(300);

同样,需要写个转换方法

/* 移动端页面设计稿宽度 */
$design-width: 750;
/* 移动端页面设计稿dpr基准值 */
$design-dpr: 2;

/*
    vw与px对应关系,100vw为视窗宽度,$vw即为$px对应占多宽

        $px                    $vw
    -------------    ===    ------------
    $design-width              100vw
*/

/* 单位px转化为vw */
@function px2vw($px) {
    @return ($px / $design-width) * 100vw;
}

/* 单位vw转化为px,可用于根据vw单位快速计算原px */
@function vw2px($vw) {
    @return #{($vw / 100) * $design-width}px;
}

11、浮动

1)引起的问题

(1)父元素的高度无法被撑开,影响与父元素同级的元素

(2)与浮动元素同级的非浮动元素会跟随其后

(3)若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构

2)如何清除

(1)、父级div定义 height

原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。

优点:简单、代码少、容易掌握

缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

建议:不推荐使用,只建议高度固定的布局时使用

(2)、结尾处加空div标签 clear:both

原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度

优点:简单、代码少、浏览器支持好、不容易出现怪问题

缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好

建议:不推荐使用,但此方法是以前主要使用的一种清除浮动方法

(3)、父级div定义 伪类:after 和 zoom

原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题

优点:浏览器支持好、不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)

缺点:代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持。

建议:推荐使用,建议定义公共类,以减少CSS代码。

// 父元素中加一个类名为clearfix 

.clearfix:after{
  content:".";  /*尽量不要为空,一般写一个点*/
  height:0;     /*盒子高度为0,看不见*/
  display:block;    /*插入伪元素是行内元素,要转化为块级元素*/
  visibility:hidden;      /*content有内容,将元素隐藏*/
  clear:both;  
}

.clearfix {
  *zoom: 1;   /*  *只有IE6,7识别 */
}

(4)、父级div定义 overflow:hidden

原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度

优点:简单、代码少、浏览器支持好

缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。

建议:只推荐没有使用position或对overflow:hidden理解比较深的朋友使用。

(5)、父级div定义 overflow:auto

原理:必须定义width或zoom:1,同时不能定义height,使用overflow:auto时,浏览器会自动检查浮动区域的高度

优点:简单、代码少、浏览器支持好

缺点:内部宽高超过父级div时,会出现滚动条。

建议:不推荐使用,如果你需要出现滚动条或者确保你的代码不会出现滚动条就使用吧。


12、伪类和伪元素

1)伪类

伪类是选择器的一种,它用于选择处于特定状态的元素,只有处于DOM树无法描述的状态下才能为元素添加样式

伪类就是开头为冒号的关键字::pseudo-class-name

2)伪元素

伪元素创建一些不在文档树中的元素,并为其添加样式,类似于增添一个新的DOM节点到DOM树中,而不是改变元素的状态。在DOM中不可见

以双冒号开头:::pseudo-element-name


13、css百分比参照问题

  • 参照父元素宽度的元素:padding / margin / width / text-indent
  • 参照父元素高度的元素:height
  • 参照父元素属性:font-size / line-height
  • 特殊:相对定位的时候,top(bottom) / left(right)参照的是父元素的内容区域的高度与宽度,而绝对定位的时候参照的是最近的定位元素包含padding的高度与宽度

14、CSS sprites与base64编码

1)CSS Sprites

CSS Sprites(雪碧图)其实就是将一个页面涉及到的所有零星图片都包含到一张大图中去。

再利用CSS的background-imagebackground-repeatbackground-position的组合进行背景定位,通过background-position可以用数字精确的定位出背景图片的位置。

适用范围:

  1. 需要通过降低http请求数完成网页加速。
  2. 网页中含有大量小图标。或者,某些图标通用性很强。
  3. 网页中有需要预载的图片。主要是aa:hover背景图这种关系的。如果aa:hover的背景图分别加载,那么,就会出现用户鼠标移到某个按钮上,按钮的背景突然消失再出来,产生“闪烁”,如果按钮文字色与大背景相同或相近,就可能让人产生按钮“消失”了的错觉。

2)base64编码

如果图片足够小且因为用处的特殊性无法被制作成雪碧图(CssSprites),在整个网站的复用性很高且基本不会被更新。那么可以使用base64编码传输图片

但是! 使用 Base64 不代表性能优化,使用 Base64 的好处是能够减少一个图片的 HTTP 请求,然而,与之同时付出的代价则是 CSS 文件体积的增大。

即缺点:base64编码的缺点在于其体积比原图片更大

3)对比

使用CssSprites合并为一张大图:

  • 页面具有多种风格,需要换肤功能,可使用CssSprites
  • 网站已经趋于完美,不会再三天两头的改动(例如button大小、颜色等)
  • 使用时无需重复图形内容
  • 没有 Base64 编码成本,降低图片更新的维护难度。(但注意 Sprites 同时修改 css 和图片某些时候可能造成负担)
  • 不会增加 CSS 文件体积

使用base64直接把图片编码成字符串写入CSS文件:

  • 无额外请求
  • 对于极小或者极简单图片
  • 可像单独图片一样使用,比如背景图片重复使用等
  • 没有跨域问题,无需考虑缓存、文件头或者cookies问题

15、CSS 隐藏页面元素

  1. display: none
  2. opacity: 0:仍在文档流中,当作用于其上的事件(如点击)仍有效
  3. visibility: hidden:透明度为 0,仍在文档流中,但作用于其上的事件(如点击)无效
  4. content-visibility:移出文档流,但是再次显示时消耗性能低
  5. 绝对定位于当前页面的不可见位置
  6. font-size: 0;
  7. HTML5的hidden属性:<p hidden>test</p>
  8. z-index

16、CSS选择器

参考Wschool:css选择器

  • 后代选择器:element element

  • 子代选择器:element > element

  • 相邻兄弟选择器:element + element

  • 通用兄弟选择器:element1 ~ element2

  • 序选择器:nth-child: 选取父元素的第 N 个子元素,与类型无关。

    n是从0开始的,但nth-child()是从1开始计数的:nth-child(1)是第一个子元素,没有nth-child(0).

  • :nth-last-child(n):同上,最后一个子元素开始计数。

  • :nth-of-type(n):匹配属于父元素的特定类型的第 N 个子元素的每个元素.


17、CSS选择器解析顺序

从上到下,从右到左

因为从左到右,首先浏览器会遍历你最左边的选择器,可能是div,可能是span,我需要在整个页面去把匹配成功的dom找出来,可以说是海底捞针,但是从右到左不一样了,它通过具体的遍历条件去寻找一个最匹配的值,查找之后在向上查询,是否符合自己的选择器规则,才最后匹配成功;

前者会浪费大量的遍历时间,造成大量错误的匹配结果


18、属性继承

可以继承的属性很少,只有

  1. 颜色:color
  2. 文字: fontfont-familyfont-sizefont-style
  3. 字体间距:text-indent
  4. 行高:line-height
  5. 对齐方式:text-align
  6. 列表的样式:list-style、list-style-type
  7. 元素可见性:visibility
  8. 光标属性:cursor

所有元素可以继承的

  • 元素可见性:visibility
  • 光标属性:cursor

line-height 继承

  • 父元素的 line-height 写了具体数值,比如 30px,则子元素 line-height 继承该值。
  • 父元素的 line-height 写了比例,比如 1.52,则子元素 line-height 也是继承该比例。
  • 父元素的 line-height 写了百分比,比如 200%,则子元素 line-height 继承的是父元素 font-size * 200%计算出来的值。

19、关于border

了解本质: 元素的border是由三角形组合而成

div {
    width: 0;
    height: 0;
    border: 40px solid;
    border-color: orange blue red green;
}

所以可以通过border去实现三角形、扇形


20、padding的百分比

padding百分比特点:

padding的百分比是相对于父元素宽度,如果父元素有宽度,相对于父元素宽度,如果没有,找其父辈元素的宽度,均没设宽度时,相对于屏幕的宽度。


21、margin负值

参考链接:margin负值

  1. 当元素的margin-top或者margin-left为负数时,“当前元素”会被拉向指定方向。

即:当前元素向上或向左覆盖

  1. 当元素的margin-bottom或者margin-right为负数时,“后续元素”会被拉向指定方向。

即:当前元素的后继元素会覆盖当前元素

运用场景

比较常用的技巧有:

  • 图片与文字对齐
  • 自适应两列布局
  • 元素垂直居中
  • tab选项卡

22、min-width/max-width/width的包含(优先级)关系

min-width会继承父元素的width,而min-height不会。

优先级:min-width>width和max-width

三个属性都设置时:Math.max(min-width, Math.min(width, max-width))


23、transition 如何检测动画结束

JS监听动画结束

transitionEnd事件

transitionEnd事件会在CSS transition动画结束后触发。

animationend事件