• [前端基础] CSS3 篇


    CSS3 使用了层叠样式表技术,可以对网页布局、字体、颜色、背景灯效果做出控制。CSS3 作为 CSS 的进阶版,拆分和增加了盒子模型、列表模块、语言模块 、背景边框 、文字特效 、多栏布局等等。CSS3 的改变有很多,增加了文字特效,丰富了下划线样式,加入了圈重点的功能。在边框方面,有了更多的灵活性,可以更加轻松地操控渐变效果和动态效果等等。在文字效果方面,特意增加了投影。CSS3在兼容上做了很大的功夫,并且网络浏览器也还将继续支持 CSS2,因此原来的代码不需要做太多的改变,只会变得更加地轻松。

    CSS3 中新增了一些特性例如:

    • 新增各种 CSS 选择器 (:not(.input):所有 class 不是“input”的节点)
    • 圆角 (border-radius:8px)
    • 多列布局 (multi-columnlayout)
    • 阴影和反射 (Shadow\Reflect)
    • 文字特效 (text-shadow)
    • 文字渲染 (Text-decoration)
    • 线性渐变 (gradient)
    • 旋转 (transform)
    • 缩放,定位,倾斜,动画,多背景

    关于 CSS 布局,参见 https://zhuanlan.zhihu.com/p/29070363https://juejin.cn/post/7073811972361289736

    1、CSS 盒模型

    盒模型用于装填内容:分为内容(content)、填充(padding)、边界(margin)、边框(border)四个部分。

    div {
    	box-sizing: border-box/padding-box/content-box;
    }
    
    • 1
    • 2
    • 3

    W3C 标准盒模型:
    在这里插入图片描述
    IE 盒模型:
    在这里插入图片描述
    区别:这两种盒子模型最主要的区别就是 width 的包含范围,在标准的盒子模型中,width 指 content 部分的宽度,在 IE 盒子模型中,width 表示 content+padding+border 这三个部分的宽度,故这使得在计算整个盒子的宽度时存在着差异。

    在 ie8+ 浏览器中使用哪个盒模型可以由 box-sizing(CSS 新增的属性)控制,默认值为 content-box。如果在 ie6,7,8 中 DOCTYPE 缺失会将盒子模型解释为 IE 盒子模型。若在页面中声明了 DOCTYPE 类型,所有的浏览器都会把盒模型解释为 W3C 盒模型。

    • box-sizing:content-box; 表示标准的盒子模型
    • box-sizing:border-box; 表示的是 IE 盒子模型
    • box-sizing:padding-box; 这个属性值的宽度包含了左右 padding+width

    内联盒模型基本概念

    1. 内容区域(contentarea)。内容区域指一种围绕文字看不见的盒子,其大小仅受字符本身特性控制,本质上是一个字符盒子
      (characterbox);但是有些元素,如图片这样的替换元素,其内容显然不是文字,不存在字符盒子之类的,因此,对于这些元素,内容区域可以看成元素自身。
    2. 内联盒子(inlinebox)。“内联盒子”不会让内容成块显示,而是排成一行,这里的“内联盒子”实际指的就是元素的“外在盒子”,用来决定元素是内联还是块级。该盒子又可以细分为“内联盒子”和“匿名内联盒子”两类。
    3. 行框盒子(linebox),每一行就是一个“行框盒子”(实线框标注),每个“行框盒子”又是由一个一个“内联盒子”组成的。
    4. 包含块(containingbox),由一行一行的“行框盒子”组成。

    幽灵空白节点
    “幽灵空白节点”是内联盒模型中非常重要的一个概念,具体指的是:在 HTML5 文档声明中,内联元素的所有解析和渲染表现就如同
    每个行框盒子的前面有一个“空白节点”一样。这个“空白节点”永远透明,不占据任何宽度,看不见也无法通过脚本获取,就好像幽灵
    一样,但又确确实实地存在,表现如同文本节点一样,因此,我称之为“幽灵空白节点”。

    2、link 与 import

    • link 属于 html 标签,而 @import 是 css 提供的
    • 页面被加载时,link 会同时被加载,而 @import 引用的 css 会等到页面加载结束后加载
    • link 是 html 标签,因此没有兼容性问题,而 @import 只有 IE5 以上才能识别
    • link 方式样式的权重高于@import 的权重

    3、CSS 选择符

    选择器例子
    id 选择器#myid
    类选择器.myclassname
    标签选择器div,h1,p
    后代选择器h1 p
    相邻后代选择器(子)选择器ul>li
    兄弟选择器li~a
    相邻兄弟选择器li+a
    属性选择器a[rel=“external”]
    伪类选择器a:hover,li:nth-child
    伪元素选择器::before、::after
    通配符选择器*

    CSS 的优先级算法
    CSS 的优先级是根据样式声明的特殊性值来判断的。选择器的特殊性值分为四个等级,如下:

    1. 标签内选择符(!improtant) x,0,0,0
    2. id 选择符 0,x,0,0
    3. class 选择符/属性选择符/伪类选择符 0,0,x,0
    4. 元素和伪元素选择符 0,0,0,x

    计算方法

    • 每个等级的初始值为 0
    • 每个等级的叠加为选择器出现的次数相加
    • 不可进位,比如 0,99,99,99
    • 依次表示为:0,0,0,0
    • 每个等级计数之间没关联
    • 等级判断从左向右,如果某一位数值相同,则判断下一位数值
    • 如果两个优先级相同,则最后出现的优先级高,!important 也适用
    • 通配符选择器的特殊性值为:0,0,0,0
    • 继承样式优先级最低,通配符样式优先级高于继承样式
    • !important(权重),它没有特殊性值,但它的优先级是最高的,为了方便记忆,可以认为它的特殊性值为 1,0,0,0

    计算实例

    • #demoa{color:orange;}/特殊性值:0,1,0,1/
    • div#demoa{color:red;}/特殊性值:0,1,0,2/

    注意:

    • 样式应用时,CSS 会先查看规则的权重(!important),加了权重的优先级最高,当权重相同的时候,会比较规则的特殊性。
    • 规则中每出现一个选择器,就将它的特殊性进行叠加,这个叠加只限于对应的等级的叠加,不会产生进位。选择器特殊性值的比较是从左向右排序的,也就是说以 1 开头的特殊性值比所有以 0 开头的特殊性值要大。比如说特殊性值为 1000 的的规则优先级就要比特殊性值为 0999 的规则高。如果两个规则的特殊性值相等的时候,那么就会根据它们引入的顺序,后出现的规则的优先级最高
    • 相同特殊性值的声明,根据样式引入的顺序,后声明的规则优先级高(距离元素出现最近的)
    • 部分浏览器由于字节溢出问题出现的进位表现不做考虑

    4、伪类与伪元素区别

    CSS 引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说,伪类和伪元素是用来修饰不在文档树中的部分,比如,一句
    话中的第一个字母,或者是列表中的第一个元素。

    伪类用于当已有的元素处于某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的
    元素时,可以通过 :hover 来描述这个元素的状态。

    伪元素用于创建一些不在文档树中的元素,并为其添加样式。它们允许我们为元素的某些部分设置样式。比如说,我们可以通过::be
    fore 来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。

    有时伪元素使用了两个冒号(::)而不是一个冒号(:),这是 CSS3 的一部分,并尝试区分伪类和伪元素。大多数浏览器都支持这两个值。按照规则应该使用(::)而不是(:),从而区分伪类和伪元素。但是,由于在旧版本的 W3C 规范并未对此进行特别区分,因此目前绝大多数的浏览器都支持使用这两种方式表示伪元素。

    5、::before 和 :after 中双冒号和单冒号有什么区别?

    单冒号(:)用于 CSS3 伪类,双冒号(::)用于 CSS3 伪元素。(伪元素由双冒号和伪元素名称组成)。双冒号是在当前规范中引入的,用于区分伪类和伪元素。不过浏览器需要同时支持旧的已经存在的伪元素写法,比如 :first-line、:first-letter、:before、:after 等,而新的在 CSS3 中引入的伪元素则不允许再支持旧的单冒号的写法。

    ::before 和 ::after

    • 想让插入的内容出现在其它内容前,使用 ::before,否者,使用 ::after
    • 在代码顺序上,::after 生成的内容也比 ::before 生成的内容靠后
    • 如果按堆栈视角,::after 生成的内容会在 ::before 生成的内容之上

    6、关于伪类 LVHA 的解释

    a 标签有四种状态:链接访问前、链接访问后、鼠标滑过、激活,分别对应四种伪类 :link:visited:hover:active

    当链接未访问过时:

    • 当鼠标滑过 a 链接时,满足 :link 和 :hover 两种状态,要改变 a 标签的颜色,就必须将 :hover 伪类在 :link 伪类后面声明
    • 当鼠标点击激活 a 链接时,同时满足 :link、:hover、:active 三种状态,要显示 a 标签激活时的样式 :active,必须将 :active 声明放到 :link 和 :hover 之后

    当链接访问过时,情况基本同上,只不过需要将 :link 换成 :visited。这个顺序能不能变?可以,但也只有 :link 和 :visited 可以交换位置,因为一个链接要么访问过要么没访问过,不可能同时满足,也就不存在覆盖的问题。

    7、CSS3 新增的伪类

    伪类描述
    elem:nth-child(n)选中父元素下的第 n 个子元素,并且这个子元素的标签名为 elem,n 可以接受具体的数值,也可以接受函数
    elem:nth-last-child(n)作用同上,不过是从后开始查找
    elem:last-child选中最后一个子元素
    elem:only-child如果 elem 是父元素下唯一的子元素,则选中之
    elem:nth-of-type(n)选中父元素下第 n 个 elem 类型元素,n 可以接受具体的数值,也可以接受函数
    elem:first-of-type选中父元素下第一个 elem 类型元素
    elem:last-of-type选中父元素下最后一个 elem 类型元素
    elem:only-of-type如果父元素下的子元素只有一个 elem 类型元素,则选中该元素
    elem:empty选中不包含子元素和内容的 elem 类型元素
    elem:target选择当前活动的 elem 元素
    :not(elem)选择非 elem 元素的每个元素
    :enabled控制表单控件的禁用状态
    :disabled控制表单控件的禁用状态
    :checked单选框或复选框被选中

    8、CSS 中可继承的属性

    每个 CSS 属性定义的概述都指出了这个属性是默认继承的,还是默认不继承的。这决定了当你没有为元素的属性指定值时该如何计算
    值。当元素的一个继承属性没有指定值时,则取父元素的同属性的计算值。只有文档根元素取该属性的概述中给定的初始值(这里的意思应
    该是在该属性本身的定义中的默认值)。

    当元素的一个非继承属性(在 Mozillacode 里有时称之为 resetproperty)没有指定值时,则取属性的初始值 initialvalue(该值在该属性的概述里被指定)。

    有继承性的属性:

    1. 字体系列属性 font、font-family、font-weight、font-size、font-style、font-variant、font-stretch、font-size-adjust
    2. 文本系列属性 text-indent、text-align、text-shadow、line-height、word-spacing、letter-spacing、text-transform、direction、color
    3. 表格布局属性 caption-sideborder-collapseempty-cells
    4. 列表属性 list-style-type、list-style-image、list-style-position、list-style
    5. 光标属性 cursor
    6. 元素可见性 visibility
    7. 还有一些不常用的 speak,page,设置嵌套引用的引号类型 quotes 等属性

    注意:当一个属性不是继承属性时,可以使用 inherit 关键字指定一个属性应从父元素继承
    它的值,inherit 关键字用于显式地指定继承性,可用于任何继承性/非继承性属性。

    9、什么是包含块,对于包含块的理解?

    包含块(containingblock)就是元素用来计算和定位的一个框。

    1. 根元素(很多场景下可以看成是)被称为“初始包含块”,其尺寸等同于浏览器可视窗口的大小。
    2. 对于其他元素,如果该元素的 position 是 relative 或者 static,则“包含块”由其最近的块容器祖先盒的 contentbox 边界形成。
    3. 如果元素 position:fixed,则“包含块”是“初始包含块”。
    4. 如果元素 position:absolute,则“包含块”由最近的 position 不为 static 的祖先元素建立,具体方式如下:如果该祖先元素是纯 inline 元素,则规则略复杂:
      • 假设给内联元素的前后各生成一个宽度为 0 的内联盒子(inlinebox),则这两个内联盒子的 paddingbox 外面的包围盒就是内联元素的“包含块”;
      • 如果该内联元素被跨行分割了,那么“包含块”是未定义的,也就是 CSS2.1 规范并没有明确定义,浏览器自行发挥否则,“包含块”由该祖先的 paddingbox 边界形成。
    5. 如果没有符合条件的祖先元素,则“包含块”是“初始包含块”。

    10、为什么要初始化 CSS 样式?

    因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对 CSS 初始化往往会出现浏览器之间的页面显示差异。不过初始化样式会对 SEO 有一定的影响。

    css reset 和 normalize.css 的区别
    normalize.css 官网

    reset 的目的,是将所有的浏览器的自带样式重置掉,这样更易于保持各浏览器渲染的一致性。

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

    1. Normalize.css 保护了有价值的默认值。Reset 通过为几乎所有的元素施加默认样式,强行使得元素有相同的视觉效果。 相比之
      下,Normalize.css 保持了许多默认的浏览器样式。 这就意味着你不用再为所有公共的排版元素重新设置样式。 当一个元素在不同的浏览器中有不同的默认值时,Normalize.css 会力求让这些样式保持一致并尽可能与现代标准相符合。
    2. Normalize.css 修复了浏览器的 bug。它修复了常见的桌面端和移动端浏览器的 bug。这往往超出了 Reset 所能做到的范畴。关于这一点,Normalize.css 修复的问题包含了 HTML5 元素的显示设置、预格式化文字的 font-size 问题、在 IE9 中 SVG 的溢出、许多出现在各浏览器和操作系统中的与表单相关的 bug。
    3. Normalize.css 没有复杂的继承链。使用 Reset 最让人困扰的地方莫过于在浏览器调试工具中大段大段的继承链。在Normalize.css 中就不会有这样的问题,因为在我们的准则中对多选择器的使用时非常谨慎的,我们仅会有目的地对目标元素设置样式。
    4. Normalize.css 是模块化的。这个项目已经被拆分为多个相关却又独立的部分,这使得你能够很容易也很清楚地知道哪些元素被设置了特定的值。因此这能让你自己选择性地移除掉某些永远不会用到部分(比如表单的一般化)。
    5. Normalize.css 拥有详细的文档。Normalize.css 的代码基于详细而全面的跨浏览器研究与测试。这个文件中拥有详细的代码说明并在 Github Wiki 中有进一步的说明。这意味着你可以找到每一行代码具体完成了什么工作、为什么要写这句代码、浏览器之间的差异,并且你可以更容易地进行自己的测试。

    11、BFC(Block Formatting Context)块级格式化上下文

    块格式化上下文(BlockFormattingContext,BFC)是 Web 页面的可视化 CSS 渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。BFC 是一个独立的布局环境,可以理解为一个容器,在这个容器中按照一定规则进行物品摆放,并且不会影响其它环境中的物品。如果一个元素符合触发 BFC 的条件,则 BFC 中的元素布局不受外部影响。

    创建 BFC

    1. 根元素或包含根元素的元素
    2. 浮动元素 float=left|right 或 inherit(≠none)
    3. 绝对定位元素 position=absolute 或 fixed
    4. display=inline-block|flex|inline-flex|table-cell 或 table-caption
    5. overflow=hidden|auto 或 scroll(≠visible)

    12、IFC 行级格式化上下文

    IFC 指的是行级格式化上下文,它有这样的一些布局规则:

    • 行级上下文内部的盒子会在水平方向,一个接一个地放置。
    • 当一行不够的时候会自动切换到下一行。
    • 行级上下文的高度由内部最高的内联盒子的高度决定。

    参考资料:BFC、IFC

    13、margin 重叠问题的理解

    margin 重叠指的是在垂直方向上,两个相邻元素的 margin 发生重叠的情况。一般来说可以分为四种情形:

    • 第一种是相邻兄弟元素的 marin-bottom 和 margin-top 的值发生重叠。这种情况下我们可以通过设置其中一个元素为 BFC 来解决。
    • 第二种是父元素的 margin-top 和子元素的 margin-top 发生重叠。它们发生重叠是因为它们是相邻的,所以我们可以通过这一点来解决这个问题。我们可以为父元素设置 border-top、padding-top 值来分隔它们,当然我们也可以将父元素设置为 BFC 来解决。
    • 第三种是高度为 auto 的父元素的 margin-bottom 和子元素的 margin-bottom 发生重叠。它们发生重叠一个是因为它们相邻,一个是因为父元素的高度不固定。因此我们可以为父元素设置 border-bottom、padding-bottom 来分隔它们,也可以为父元素设置一个高度,max-height 和 min-height 也能解决这个问题。当然将父元素设置为 BFC 是最简单的方法。
    • 第四种情况,是没有内容的元素,自身的 margin-top 和 margin-bottom 发生的重叠。我们可以通过为其设置 border、padding 或者高度来解决这个问题。

    14、为什么需要清除浮动?清除浮动的方式?

    浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动之后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”。

    清除浮动是为了清除使用浮动元素产生的影响。浮动的元素,高度会塌陷,而高度的塌陷使我们页面后面的布局不能正常显示。

    清除浮动的方式

    1. 使用 clear 属性清除浮动。
    <div>
        <ul style="float:left">
            <li>1li>
            <li>2li>
            <li>3li>
        ul>
        <div style="clear:both">div>
    div> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 使用伪类
    <style>
        .clearfix{
            *zoom:1;
        }
        .clearfix:after{
            content:"";
            display:block;
            clear:both;
        }
    style>
    <div class="clearfix">
        <ul style="float:left">
            <li>1li>
            <li>2li>
            <li>3li>
        ul>
    div> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1. 触发 BFC 块级格式化上下文来清除浮动。因为 BFC 元素不会影响外部元素的特点,所以 BFC 元素也可以用来清除浮动的影响。
    
    <div style="float:left">
        <ul style="float:left">
            <li>1li>
            <li>2li>
            <li>3li>
        ul>
    div> 
    
    <div style="overflow:hidden">
        <ul style="float:left">
            <li>1li>
            <li>2li>
            <li>3li>
        ul>
    div> 
    
    <div style="display:inline-block">
        <ul style="float:left">
            <li>1li>
            <li>2li>
            <li>3li>
        ul>
    div>
    
    <div style="position:fixed">
        <ul style="float:left">
            <li>1li>
            <li>2li>
            <li>3li>
        ul>
    div> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    关于 clear
    官方对 clear 属性的解释是:“元素盒子的边不能和前面的浮动元素相邻。”,我们对元素设置 clear 属性是为了避免浮动元素对该元素的影响,而不是清除掉浮动。

    关于 zoom
    清除浮动,触发 hasLayout;zoom 属性是 IE 浏览器的专有属性,它可以设置或检索对象的缩放比例。解决 IE 下比较奇葩的 bug。譬如外边距(margin)的重叠,浮动清除,触发 ie 的 haslayout 属性等。

    当设置了 zoom 的值之后,所设置的元素就会就会扩大或者缩小,高度宽度就会重新计算了,这里一旦改变 zoom 值时其实也会发生重新渲染,运用这个原理,也就解决了 IE 下子元素浮动时候父元素不随着自动扩大的问题。

    zoom 属性是 IE 浏览器的专有属性,火狐和老版本的 webkit 核心的浏览器都不支持这个属性。

    15、visibility 的 collapse 属性在不同浏览器下有什么区别?

    • 对于一般的元素,它的表现跟 visibility:hidden;是一样的。元素是不可见的,但此时仍占用页面空间。
    • 但例外的是,如果这个元素是 table 相关的元素,例如 table 行,tablegroup,table 列,tablecolumngroup,它的表现却跟 display:none 一样,也就是说,它们占用的空间也会释放。

    在不同浏览器下的区别:

    • 在谷歌浏览器里,使用 collapse 值和使用 hidden 值没有什么区别。
    • 在火狐浏览器、Opera 和 IE11 里,使用 collapse 值的效果就如它的字面意思:table 的行会消失,它的下面一行会补充它的位置。

    16、display 有哪些值?

    • block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
    • none 元素不显示,并从文档流中移除。
    • inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
    • inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
    • list-item 像块类型元素一样显示,并添加样式列表标记。
    • table 此元素会作为块级表格来显示。
    • inherit 规定应该从父元素继承 display

    17、position 有哪些值?

    absolute
    生成绝对定位的元素,相对于值不为 static 的第一个父元素的 paddingbox (在计算定位距离的时候,padding 的值也要算进去)进行定位,也可以理解为离自己这一级元素最近的
    一级 position 设置为 absolute 或者 relative 的父元素的 paddingbox 的左上角为原点进行定位。

    fixed(老 IE 不支持)
    生成绝对定位的元素,相对于浏览器窗口进行定位。

    relative
    生成相对定位的元素,相对于其元素本身所在正常位置进行定位。

    static
    默认值。没有定位,元素出现在正常的流中(忽略 top,bottom,left,right,z-index 声明)。

    inherit
    规定从父元素继承 position 属性的值。

    sticky
    sticky 定位可以表现出 relative 和 fixed 两种定位结合,正常情况下是 relative,但是当 sticky 元素的父元素出现滚动条的时候,sticky 元素距离到设置的位置如(top: 0)时会表现为 fixed,相对于最近的滚动容器的 fixed。

    18、display、position 和 float 的相互关系

    1. 首先我们判断 display 属性是否为 none,如果为 none,则 position 和 float 属性的值不影响元素最后的表现。
    2. 然后判断 position 的值是否为 absolute 或者 fixed,如果是,则 float 属性失效,并且 display 的值应该被设置为 table 或者 block,具体转换需要看初始转换值。
    3. 如果 position 的值不为 absolute 或者 fixed,则判断 float 属性的值是否为 none,如果不是,则 display 的值则按上面的规则转换。注意,如果 position 的值为 relative 并且 float 属性的值存在,则 relative 相对于浮动后的最终位置定位。
    4. 如果 float 的值为 none,则判断元素是否为根元素,如果是根元素则 display 属性按照上面的规则转换,如果不是,则保持指定的 display 属性值不变。

    总的来说,可以把它看作是一个类似优先级的机制,“position:absolute” 和 “position:fixed” 优先级最高,有它存在的时候,浮动不起作用,‘display’ 的值也需要调整;其次,元素的 ‘float’ 特性的值不是 “none” 的时候或者它是根元素的时候,调整 ‘display’ 的值;最后,非根元素,并且非浮动元素,并且非绝对定位的元素,‘display’ 特性值同设置值。

    19、li 与 li 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

    浏览器会把 inline(inline-block) 元素间的空白字符(空格、换行、Tab 等)渲染成一个空格。而为了美观。我们通常是一个

  • 放在一行,这导致
  • 换行后产生换行字符,它变成一个空格,占用了一个字符的宽度。

    解决办法:

    1. 设置 float:left。不足:有些容器是不能设置浮动,如左右切换的焦点图等。
    2. 将所有
    3. 写在同一行。不足:代码不美观。
      • 内的字符尺寸直接设为 0,即 font-size:0。不足:
          中的其他字符尺寸也被设为 0,需要额外重新设定其他字符尺寸,且在 Safari 浏览器依然会出现空白间隔。
        • 消除
            的字符间隔 letter-spacing/word-spacing:-8px,不足:这也设置了
          • 内的字符间隔,因此需要将
          • 内的字符间隔设为默认 letter-spacing:normal。

    20、margin 和 padding 分别适合什么场景?

    • margin 是用来隔开元素与元素的间距;padding 是用来隔开元素与内容的间隔。
    • margin 用于布局分开元素使元素与元素互不相干。padding 用于元素与内容之间的间隔,让内容(文字)与(包裹)元素之间有一段距离。

    何时应当使用 margin:

    • 需要在 border 外侧添加空白时。
    • 空白处不需要背景(色)时。
    • 上下相连的两个盒子之间的空白,需要相互抵消时。如 15px+20px 的 margin,将得到 20px 的空白,即 margin 重叠。

    何时应当时用 padding:

    • 需要在 border 内测添加空白时。
    • 空白处需要背景(色)时。
    • 上下相连的两个盒子之间的空白,希望等于两者之和时。如 15px+20px 的 padding,将得到 35px 的空白。

    21、CSS3 all 属性

    all 属性实际上是所有 CSS 属性的缩写,表示,所有的 CSS 属性都怎样怎样,但是,不包括 unicode-bididirection 这两个 CSS 属性。支持三个 CSS 通用属性值,initial,inherit,unset。

    • initial 是初始值的意思,也就是该元素元素都除了 unicode-bidi 和 direction 以外的 CSS 属性都使用属性的默认初始值。

    • inherit 是继承的意思,也就是该元素除了 unicode-bidi 和 direction 以外的 CSS 属性都继承父元素的属性值。

    • unset 是取消设置的意思,也就是当前元素浏览器或用户设置的 CSS 忽略,然后如果是具有继承特性的 CSS,如 color,则使用继承值;如果是没有继承特性的 CSS 属性,如 background-color,则使用初始值。

    22、font-style 属性中 italic 和 oblique 的区别

    italic 和 oblique 这两个关键字都表示“斜体”的意思。它们的区别在于,italic 是使用当前字体的斜体字体,而 oblique 只是单纯地让文字倾斜。如果当前字体没有对应的斜体字体,则退而求其次,解析为 oblique,也就是单纯形状倾斜。

    23、width: auto 和 width: 100%的区别

    • width:100% 会使元素 box 的宽度等于父元素的 contentbox 的宽度。
    • width:auto 会使元素撑满整个父元素,margin、border、padding、content 区域会自动分配水平空间。

    24、min-width/max-width 和 min-height/max-height 属性间的覆盖规则?

    • max-width 会覆盖 width,即使 width 是行类样式或者设置了 !important。
    • min-width 会覆盖 max-width,此规则发生在 min-width 和 max-width。

    25、border 的特殊性

    • border-width 却不支持百分比。
    • border-style 的默认值是 none,有一部分人可能会误以为是 solid。这也是单纯设置 border-width 或 border-color 没有边框显示的原因。
    • border-style:double 的表现规则:双线宽度永远相等,中间间隔±1。
    • border-color 默认颜色就是 color 色值。
    • 默认 background 背景图片是相对于 paddingbox 定位的。

    26、line-height 的特殊性

    • 对于非替换元素的纯内联元素,其可视高度完全由 line-height 决定。对于文本这样的纯内联元素,line-height 就是高度计算的基石,用专业说法就是指定了用来计算行框盒子高度的基础高度。
    • 内联元素的高度由固定高度和不固定高度组成,这个不固定的部分就是这里的“行距”。换句话说,line-height 之所以起作用,就是通过改变“行距”来实现的。在 CSS 中,“行距”分散在当前文字的上方和下方,也就是即使是第一行文字,其上方也是有“行距”的,只不过这个“行距”的高度仅仅是完整“行距”高度的一半,因此,也被称为“半行距”。
    • 行距 = line-height+font-size。
    • border 以及 line-height 等传统 CSS 属性并没有小数像素的概念。如果标注的是文字上边距,则向下取整;如果是文字下边距,则向上取整。
    • 对于纯文本元素,line-height 直接决定了最终的高度。但是,如果同时有替换元素,则 line-height 只能决定最小高度。
    • 对于块级元素,line-height 对其本身是没有任何作用的,我们平时改变 line-height,块级元素的高度跟着变化实际上是通过改变块级元素里面内联级别元素占据的高度实现的。
    • line-height 的默认值是 normal,还支持数值、百分比值以及长度值。为数值类型时,其最终的计算值是和当前 font-size 相乘后的值。为百分比值时,其最终的计算值是和当前 font-size 相乘后的值。为长度值时原意不变。
    • 如果使用数值作为 line-height 的属性值,那么所有的子元素继承的都是这个值;但是,如果使用百分比值或者长度值作为属性值,那么所有的子元素继承的是最终的计算值。
    • 无论内联元素 line-height 如何设置,最终父级元素的高度都是由数值大的那个line-height 决定的。
    • 只要有“内联盒子”在,就一定会有“行框盒子”,就是每一行内联元素外面包裹的一层看不见的盒子。然后,重点来了,在每个“行框盒子”前面有一个宽度为 0 的具有该元素的字体和行高属性的看不见的“幽灵空白节点”。

    基线和 x-height
    字母 x 的下边缘(线)就是我们的基线。

    x-height 指的就是小写字母 x 的高度,术语描述就是基线和等分线(meanline)(也称作中线,midline)之间的距离。在 CSS 世界中,middle 指的是基线往上 1/2x-height 高度。我们可以近似理解为字母 x 交叉点那个位置。

    ex 是 CSS 中的一个相对单位,指的是小写字母 x 的高度,没错,就是指 x-height。ex 的价值就在其副业上不受字体和字号影响的内联元素的垂直居中对齐效果。内联元素默认是基线对齐的,而基线就是 x 的底部,而1ex 就是一个 x 的高度。

    27、vertical-align 的特殊性

    • vertical-align 的默认值是 baseline,即基线对齐,而基线的定义是字母 x 的下边缘。因此,内联元素默认都是沿着字母 x 的下边缘对齐的。对于图片等替换元素,往往使用元素本身的下边缘作为基线。:一个inline-block 元素,如果里面没有内联元素,或者 overflow 不是 visible,则该元素的基线就是其 margin 底边缘;否则其基线就是元素里面最后一行内联元素的基线。
    • vertical-align:top 就是垂直上边缘对齐,如果是内联元素,则和这一行位置最高的内联元素的顶部对齐;如果 display计算值是 table-cell 的元素,我们不妨脑补成元素,则和元素上边缘对齐。
    • vertical-align:middle 是中间对齐,对于内联元素,元素的垂直中心点和行框盒子基线往上 1/2x-height 处对齐。对于 table-cell 元素,单元格填充盒子相对于外面的表格行居中对齐。
    • vertical-align 支持数值属性,根据数值的不同,相对于基线往上或往下偏移,如果是负值,往下偏移,如果是正值,往上偏移。
    • vertical-align 属性的百分比值则是相对于 line-height 的计算值计算的。
    • vertical-align 起作用是有前提条件的,这个前提条件就是:只能应用于内联元素以及display 值为 table-cell 的元素。
    • table-cell 元素设置 vertical-align 垂直对齐的是子元素,但是其作用的并不是子元素,而是 table-cell 元素自身。

    28、overflow 的特殊性

    • 一个设置了 overflow:hidden 声明的元素,假设同时存在 border 属性和 padding 属性,则当子元素内容超出容器宽度
      高度限制的时候,剪裁的边界是 borderbox 的内边缘,而非 paddingbox 的内边缘。
    • HTML 中有两个标签是默认可以产生滚动条的,一个是根元素 ,另一个是文本域