css 常见知识点总汇

189 阅读20分钟

1. link 和 @import 都能导入一个样式文件,它们有什么区别嘛?

  • link 是 HTML 标签,除了能导入 CSS 外,还能导入别的资源,比如图片、脚本和字体等;而 @import 是 CSS 的语法,只能用来导入 CSS;
  • link 导入的样式会在页面加载时同时加载,@import 导入的样式需等页面加载完成后再加载;
  • link 没有兼容性问题,@import 不兼容 ie5 以下;
  • link 可以通过 JS 操作 DOM 动态引入样式表改变样式,而@import不可以。

2.c s s 选择器优先级

  • 10000:!important;
  • 01000:内联样式;
  • 00100:ID 选择器;
  • 00010:类选择器、伪类选择器、属性选择器;
  • 00001:元素选择器、伪元素选择器;
  • 00000:通配选择器、后代选择器、兄弟选择器;

可以看到内联样式(通过元素中 style 属性定义的样式)的优先级大于任何选择器;而给属性值加上 !important 又可以把优先级提至最高,就是因为它的优先级最高,所以需要谨慎使用它,以下有些使用注意事项:

  • 一定要优先考虑使用样式规则的优先级来解决问题而不是 !important;
  • 只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important;
  • 永远不要在你的插件中使用 !important;
  • 永远不要在全站范围的 CSS 代码中使用 !important;

3. c s s 继承性

字体相关:font-familyfont-stylefont-sizefont-weight 等;

文本相关:text-aligntext-indenttext-decorationtext-shadowletter-spacingword-spacingwhite-spaceline-heightcolor 等;

列表相关:list-stylelist-style-imagelist-style-typelist-style-position 等;

其他属性:visibilitycursor 等;

对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为:

inherit:继承父元素对应属性的计算值;

initial:应用该属性的默认值,比如 color 的默认值是 #000

unset:如果属性是默认可以继承的,则取 inherit 的效果,否则同 initial

revert:效果等同于 unset,兼容性差。

4. c s s 盒模型

在 CSS 中任何元素都可以看成是一个盒子,而一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)。盒模型有 2 种:标准盒模型和 IE 盒模型,本别是由 W3C 和 IExplore 制定的标准。

4.1标准盒模型

如果给元素设置如下样式:

.box {
    width: 200px;
    height: 200px;
    padding: 10px;
    border: 1px solid #eee;
    margin: 10px;
}

标准盒模型认为:盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框

所以 .box 元素内容的宽度就为 200px,而实际的宽度则是 width + padding-left + padding-right + border-left-width + border-right-width = 200 + 10 + 10 + 1 + 1 = 222。

3. c s s 继承性

字体相关:font-familyfont-stylefont-sizefont-weight 等;

文本相关:text-aligntext-indenttext-decorationtext-shadowletter-spacingword-spacingwhite-spaceline-heightcolor 等;

列表相关:list-stylelist-style-imagelist-style-typelist-style-position 等;

其他属性:visibilitycursor 等;

对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为:

inherit:继承父元素对应属性的计算值;

initial:应用该属性的默认值,比如 color 的默认值是 #000

unset:如果属性是默认可以继承的,则取 inherit 的效果,否则同 initial

revert:效果等同于 unset,兼容性差。

4. c s s 盒模型

在 CSS 中任何元素都可以看成是一个盒子,而一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)。盒模型有 2 种:标准盒模型和 IE 盒模型,本别是由 W3C 和 IExplore 制定的标准。

4.1标准盒模型

如果给元素设置如下样式:

.box {
    width: 200px;
    height: 200px;
    padding: 10px;
    border: 1px solid #eee;
    margin: 10px;
}

标准盒模型认为:盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框

所以 .box 元素内容的宽度就为 200px,而实际的宽度则是 width + padding-left + padding-right + border-left-width + border-right-width = 200 + 10 + 10 + 1 + 1 = 222。

3. c s s 继承性

字体相关:font-familyfont-stylefont-sizefont-weight 等;

文本相关:text-aligntext-indenttext-decorationtext-shadowletter-spacingword-spacingwhite-spaceline-heightcolor 等;

列表相关:list-stylelist-style-imagelist-style-typelist-style-position 等;

其他属性:visibilitycursor 等;

对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为:

inherit:继承父元素对应属性的计算值;

initial:应用该属性的默认值,比如 color 的默认值是 #000

unset:如果属性是默认可以继承的,则取 inherit 的效果,否则同 initial

revert:效果等同于 unset,兼容性差。

4. c s s 盒模型

在 CSS 中任何元素都可以看成是一个盒子,而一个盒子是由 4 部分组成的:内容(content)、内边距(padding)、边框(border)和外边距(margin)。盒模型有 2 种:标准盒模型和 IE 盒模型,本别是由 W3C 和 IExplore 制定的标准。

4.1标准盒模型

如果给元素设置如下样式:

.box {
    width: 200px;
    height: 200px;
    padding: 10px;
    border: 1px solid #eee;
    margin: 10px;
}

标准盒模型认为:盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框

所以 .box 元素内容的宽度就为 200px,而实际的宽度则是 width + padding-left + padding-right + border-left-width + border-right-width = 200 + 10 + 10 + 1 + 1 = 222。

4.2 ie 盒子模型

IE 盒模型认为:盒子的实际尺寸 = 设置的宽/高 = 内容 + 内边距 + 边框

.box 元素所占用的实际宽度为 200px,而内容的真实宽度则是 width - padding-left - padding-right - border-left-width - border-right-width = 200 - 10 - 10 - 1 - 1 = 178。

现在高版本的浏览器基本上默认都是使用标准盒模型,而像 IE6 这种老古董才是默认使用 IE 盒模型的。

4.3 盒模型的转换

在 CSS3 中新增了一个属性 box-sizing,允许开发者来指定盒子使用什么标准,它有 2 个值:

  • content-box:标准盒模型;
  • border-box:IE 盒模型;

5. css四种格式化上下文

格式化上下文(Formatting Context)是 CSS2.1 规范中的一个概念,大概说的是页面中的一块渲染区域,规定了渲染区域内部的子元素是如何排版以及相互作用的。

5.1 BFC (Block Formatting Context) 块级格式化上下文;

概念:块格式化上下文,它是一个独立的渲染区域,只有块级盒子参与,它规定了内部的块级盒子如何布局,并且与这个区域外部毫不相干。

5.11 BFC 渲染规则

  1. 内部的盒子会在垂直方向,一个接一个地放置;
  2. 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠;
  3. 每个元素的 margin 的左边,与包含块 border 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此;
  4. BFC 的区域不会与 float 盒子重叠;
  5. BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算 BFC 的高度时,浮动元素也参与计算。

5.12 怎么触发bfc

  1. 根元素:html
  2. 非溢出的可见元素:overflow 不为 visible
  3. 设置浮动:float 属性不为 none
  4. 设置定位:position 为 absolute 或 fixed
  5. 定义成块级的非块级元素:display: inline-block/table-cell/table-caption/flex/inline-flex/grid/inline-grid

5.13 BFC的应用场景

  1. 自适应的两栏布局

    应用原理: BFC 的区域不会和浮动区域重叠,所以就可以把侧边栏固定宽度且左浮动,而对右侧内容触发 BFC,使得它的宽度自适应该行剩余宽度。

  2. 清除内部浮动

    应用原理: 浮动造成的问题就是父元素高度坍塌,所以清除浮动需要解决的问题就是让父元素的高度恢复正常。而用 BFC 清除浮动的原理就是:计算 BFC 的高度时,浮动元素也参与计算。只要触发父元素的 BFC 即可。

  3. 防止垂直margin 合并

    应用原理: 同一个 BFC 下的垂直 margin 会发生合并。所以如果让 2 个元素不在同一个 BFC 中即可阻止垂直 margin 合并。那如何让 2 个相邻的兄弟元素不在同一个 BFC 中呢?可以给其中一个元素外面包裹一层,然后触发其包裹层的 BFC,这样一来 2 个元素就不会在同一个 BFC 中了。

BFC的应用场景有代码

以上内容参考c s s原理-[Formatting Context]

5.2 IFC 行内格式化上下文

IFC 的形成条件非常简单,块级元素中仅包含内联级别元素,需要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个 IFC。

5.21 IFC 渲染规则

  1. 子元素在水平方向横排排列,并且垂直方向七点为元素的顶部;
  2. 子元素只会计算横向样式空间,[padding,border,margin],垂直方向的样式空间不会被计算[padding,border,margin],
  3. 垂直方向上,子元素会以不同的形式来对齐(vertical-align)
  4. 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的线盒(行框)(line box)。线盒的宽度是由包含块(containing box)和与其中的浮动来决定;
  5. IFC 中的 line box 一般左右边贴紧其包含块,但 float 元素会优先排列。
  6. IFC 中的 line box 高度由 line-height 计算规则来确定,同个 IFC 下的多个 line box 高度可能会不同;
  7. 当内联级盒子的总宽度少于包含它们的 line box 时,其水平渲染规则由 text-align 属性值来决定;
  8. 当一个内联盒子超过父元素的宽度时,它会被分割成多盒子,这些盒子分布在多个 line box 中。如果子元素未设置强制换行的情况下,inline box 将不可被分割,将会溢出父元素。

5.22 IFC 的应用场景

  • 水平居中:当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。
  • 垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align: middle,其他行内元素则可以在此父元素下垂直居中。

5.3 FFC (Flex Formatting Context) 弹性格式化上下文;

就是flex布局这里就不多介绍了请看阮一峰的文章f le x 布局

5.4 GFC (Grid Formatting Context) 栅格式化上下文;

内容过多建议查看阮一峰的文章Grid 网格布局教程

6. css的值和单位(px,em,rem, vw/vh)

6.1 px

其实屏幕分辨率是指在屏幕的横纵方向上的像素点数量,比如分辨率 1920×1080 意味着水平方向含有 1920 个像素数,垂直方向含有 1080 个像素数。px表示css像素,在css中是绝对的长度单位,也是基础单位,其他长度单位会被浏览器换算成px。但是对于设备而言p x又是相对单位,比如说宽高为2px正常屏幕下,其实就是4个像素点,而在设备像素比(devicePixelRatio) 为 2 的 Retina 屏幕下,它就有 16 个像素点。所以屏幕尺寸一致的情况下,屏幕分辨率越高,显示效果就越细腻。

6.2 相对单位em

em 是 CSS 中x相对的长度单位。

  1. 在 font-size 中使用是相对于父元素的 font-size 大小,比如父元素 font-size: 16px,当给子元素指定 font-size: 2em 的时候,经过计算后它的字体大小会是 32px;
  2. 在其他属性中使用是相对于自身的字体大小,如 width/height/padding/margin 等;

em计算的时候会层层计算:比如

<div>
    <p></p>
</div>
div { font-size: 2em; }
p { font-size: 2em; }

对于上面的例子 由于html 的字体大小是16px,所以p标签最终计算出来后的字体大小是 16 * 2 * 2 = 64px

6.3 相对单位rem

rem(root em) 和em一样也是相对长度单位,不过rem 相对的是html 根元素的font-size 值。

rem 由于是基于 html 的 font-size 来计算,所以通常用于自适应网站或者 H5 中。

比如在做 H5 的时候,前端通常会让 UI 给 750px 宽的设计图,而在开发的时候可以基于 iPhone X 的尺寸 375px * 812px 来写页面,这样一来的话,就可以用下面的 JS 依据当前页面的视口宽度自动计算出根元素 html 的基准 font-size 是多少。

(function (doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
        psdWidth = 750,  // 设计图宽度
        recalc = function () {
            var clientWidth = docEl.clientWidth;
            if ( !clientWidth ) return;
            if ( clientWidth >= 640 ) {
                docEl.style.fontSize = 200 * ( 640 / psdWidth ) + 'px';
            } else {
                docEl.style.fontSize = 200 * ( clientWidth / psdWidth ) + 'px';
            }
        };
​
    if ( !doc.addEventListener ) return;
    // 绑定事件的时候最好配合防抖函数
    win.addEventListener( resizeEvt, debounce(recalc, 1000), false );
    doc.addEventListener( 'DOMContentLoaded', recalc, false );
    
    function debounce(func, wait) {
        var timeout;
        return function () {
            var context = this;
            var args = arguments;
            clearTimeout(timeout)
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
    }
})(document, window);
​

比如当视口是 375px 的时候,经过计算 html 的 font-size 会是 100px,这样有什么好处呢?好处就是方便写样式,比如从设计图量出来的 header 高度是 50px 的,那我们写样式的时候就可以直接写:

header {
    height: 0.5rem;
}

6.4 vw/vh (相对单位)

vw 和 vh 分别是相对于屏幕视口宽度和高度而言的长度单位:

  • 1vw = 视口宽度均分成 100 份中 1 份的长度;
  • 1vh = 视口高度均分成 100 份中 1 份的长度;

相对视口的单位,除了 vw/vh 外,还有 vmin 和 vmax:

  • vmin:取 vw 和 vh 中值较小的;
  • vmax:取 vw 和 vh 中值较大的;

7. 1px边框线问题

Retina 显示屏比普通的屏幕有着更高的分辨率,所以在移动端的 1px 边框就会看起来比较粗,为了美观通常需要把这个线条细化处理。

最完美的解决方案:媒体查询+伪类+ transform 实现

.scale-1px-bottom {
    position: relative;
    border:none;
}
@media (-webkit-min-device-pixel-ratio: 2) {
  .scale-1px-bottom::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    background: #000;
    width: 100%;
    height: 1px;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
     }
  }
​
​
​

同时设置4个方向的边框线 写在项目里自己要添加关于媒体查询的内容哟

.scale-1px {
    position: relative;
    margin-bottom: 20px;
    border:none;
}
.scale-1px::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    border: 1px solid #000;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 200%;
    height: 200%;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    -webkit-transform-origin: left top;
    transform-origin: left top;
}
​

8.清除浮动

浮动概念: 浮动元素会脱离文档流并向左/向右浮动,直到碰到父元素或者另一个浮动元素。

需要清除浮动的原因,它造成的问题?

因为浮动元素会脱离正常的文档流,并不会占据文档流的位置,所以如果一个父元素下面都是浮动元素,那么这个父元素就无法被浮动元素所撑开,这样一来父元素就丢失了高度,这就是所谓的浮动造成的父元素高度坍塌问题。

父元素高度一旦坍塌将对后面的元素布局造成影响,为了解决这个问题,所以需要清除浮动,让父元素恢复高度,那该如何做呢?

清除浮动的两种方式:1BFC 清除浮动,2.clear清除浮动

8.1 BFC清除浮动

原理: 计算BFC元素的高度的时候浮动的子元素的高度也会计算在内,就是利用这条规则清除浮动的。

假设一个父元素 parent 内部只有 2 个子元素 child,且它们都是左浮动的,这个时候 parent 如果没有设置高度的话,因为浮动造成了高度坍塌,所以 parent 的高度会是 0,此时只要给 parent 创造一个 BFC,那它的高度就能恢复了。

而产生 BFC 的方式很多,我们可以给父元素设置overflow: auto 来简单的实现 BFC 清除浮动,但是为了兼容 IE 最好用 overflow: hidden。

.parent {
    overflow: hidden;
}
​

8.2 通过clear 清除浮动

.clearfix {  // ie低版本浏览器兼容
    zoom: 1;
}
.clearfix::after {
    content: ""; // 内容为空保证高度为0
    display: block;  //clear: both; 只对块元素起作用
    clear: both;  // 清除浮动的关键
}
​

可以结合这个 codepen demo 一起理解上图的 clear 清楚浮动原理。

上面这个 demo 或者图里为了展示需要所以给伪元素的内容设置为了 ::after,实际使用的时候需要设置为空字符串,让它的高度为 0,从而父元素的高度都是由实际的子元素撑开。

参考:CSS中的浮动和清除浮动,梳理一下

9. 清除浏览器的默认样式

针对同一个类型的 HTML 标签,不同的浏览器往往有不同的表现,所以在网站制作的时候,开发者通常都是需要将这些浏览器的默认样式清除,让网页在不同的浏览器上能够保持一致。

针对清楚浏览器默认样式参考CSS 大师 Eric A. Meyer 写的reset.css

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}
​

除了 reset.css 外,后来又出现了 Normalize.css 。关于 Normalize.css, 其作者 necolas 专门写了一篇文章介绍了它,并谈到了它和 reset.css 的区别。这个是他写那篇文章的翻译版:让我们谈一谈 Normalize.css

9. 长文本溢出处理

这个偷个懒就不写写那么多描述

查看以上这些方案的示例: codepen demo

10. 常用的布局方,两栏布局三栏布局

这里不多写了看我之前的知乎文章:常见的两栏布局三栏布局,圣杯双飞翼布局方案

11.响应式布局方案

对响应式布局的理解: 就是根据网页页面的放大缩小或者不同的机型,显示出来的页面效果是一样美观的。

11.1 移动端响应式布局方案。

  • Rem 等比缩放,根据根元素字体设定rem的值
  • 设备尺寸发生变化,从写计算根元素的字体大小,这样说有元素的大小就会跟着自适应
  • 用flex 辅助布局

11.2 手机端p c 端公用同一套代码

11.3 大屏幕适配

  • 大块轮廓用vw vh(百分比布局):小块写固定
  • 样式不满意在用媒体查询微调
  • 用flex 辅助布局

12. 前端需要注意哪些SEO

  1. 合理的titledescriptionkeywords:搜索对着三项的权重逐个减小,title值强调重点即可,重要关键词出现不要超过2次,而且要靠前,不同页面title要有所不同;description把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面description有所不同;keywords列举出重要关键词即可
  1. 语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页
  1. 重要内容HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取
  1. 重要内容不要用js输出:爬虫不会执行js获取内容
  1. 少用iframe:搜索引擎不会抓取iframe中的内容
  1. 非装饰性图片必须加alt
  1. 提高网站速度:网站速度是搜索引擎排序的一个重要指标

13. 如何进行网站性能优化

  • content方面

    • 减少HTTP请求:合并文件、CSS精灵、inline Image
    • 减少DNS查询:DNS缓存、将资源分布到恰当数量的主机名
    • 减少DOM元素数量
  • Server方面

    • 使用CDN
    • 配置ETag
    • 对组件使用Gzip压缩
  • Cookie方面

    • 减小cookie大小
  • css方面

    • 将样式表放到页面顶部
    • 不使用CSS表达式
    • 使用<link>不使用@import
  • Javascript方面

    • 将脚本放到页面底部
    • javascriptcss从外部引入
    • 压缩javascriptcss
    • 删除不需要的脚本
    • 减少DOM访问
  • 图片方面

    • 优化图片:根据实际颜色需要选择色深、压缩
    • 优化css精灵
    • 不要在HTML中拉伸图片

你有用过哪些前端性能优化的方法?

  • 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
  • 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
  • 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
  • 当需要设置的样式很多时设置className而不是直接操作style
  • 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作
  • 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)
  • 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳
  • 避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示比div+css布局慢

谈谈性能优化问题

  • 代码层面:避免使用css表达式,避免使用高级选择器,通配选择器
  • 缓存利用:缓存Ajax,使用CDN,使用外部js和css文件以便缓存,添加Expires头,服务端配置Etag,减少DNS查找等
  • 请求数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载
  • 请求带宽:压缩文件,开启GZIP

前端性能优化最佳实践?

  • 性能评级工具(PageSpeed 或 YSlow)
  • 合理设置 HTTP 缓存:Expires 与 Cache-control
  • 静态资源打包,开启 Gzip 压缩(节省响应流量)
  • CSS3 模拟图像,图标base64(降低请求数)
  • 模块延迟(defer)加载/异步(async)加载
  • Cookie 隔离(节省请求流量)
  • localStorage(本地存储)
  • 使用 CDN 加速(访问最近服务器)
  • 启用 HTTP/2(多路复用,并行加载)
  • 前端自动化(gulp/webpack)