2023-05-29
CSS
00
请注意,本文编写于 547 天前,最后修改于 306 天前,其中某些信息可能已经过时。

目录

面试题
入门基础
CSS概述
@规则
CSS文件用什么字符编码呢?
link 和 @import的区别
重要的CSS属性
position
样式继承
控制继承
initial与revert的区别
all:revert 样式格式化
CSS是如何工作的
常见问题
当浏览器遇到无法解析的CSS会怎样?
CSS如何降级?
CSS有哪些样式表
CSS为什么不建议使用@import方式加载css?
CSS 单位
line-height
盒模型
CSS选择器
选择器分类
选择器优先级
JS操作CSS
脚本化内联样式
查询计算出的样式
脚本化CSS类
脚本化样式表

本文系统梳理CSS基础知识及面试常见问题。详细介绍了样式继承、CSS单位、CSS行高、CSS选择器及优先级、脚本化CSS等。

面试题

开门见山,先说一说CSS基础相关面试题

  1. position属性有哪些值,absoluted相对于谁定位?
  2. 关于样式继承 说一说inhertinitialunsetrevert 之间的区别
  3. css是如何工作的?它的解析顺序是什么?如何降级?
  4. 你知道哪些css单位,如何进行适配移动端适配, 等比放大方案rem vw
  5. line-height 行高如何计算?
  6. 你知道有哪些CSS选择器?它们的优先级如何计算?说一说常见的伪类选择器
  7. CSS文件用什么字符编码呢?
  8. link@import都能导入一个样式文件,它们有什么区别吗?
  • CSS 全称 Cascading Style Sheets 层叠样式表,将网页的内容与样式进行分离
  • 层叠:应用文档中任何给定元素的样式规则是各个来源的“层叠”效果
    • web浏览器的默认样式
    • 文档的样式表
    • 每个独立的html元素的style属性

入门基础

CSS概述

  • 语法 选择器 { 属性:属性值;//...}
    • image.png
  • 仅支持多行注释/* ... */,不支持单行注释 //
  • 计算样式: 计算的结果,一组用于实际显示元素的样式属性和值
    • document.styleSheets
  • 属性: 定义视觉特性某一指标的变量
  • 复合属性: 经常在一起使用的样式属性组合起来使用一个特殊的复合属性
    • 比如fontfont-familyfont-sizefont-weight组成
  • 非标准属性: 浏览器尝试实现的非标准CSS属性, 在属性名前面加一个厂商前缀。
    • Firefox -moz-
    • Chrome -webkit
    • IE -ms-

定义样式的两种方式

  • 行内样式也称内联样式
    • 形如 style="margin-top:20px;color:red;"
  • 定义样式表
    • .p {text-index: 5in; color: red;}
    • <link rel="stylesheet" href="mystyles.css" type="text/css">

@规则

CSS 规则是样式表的主体,通常样式表会包括大量的规则列表。但有时候也有需要在样式表中包含一些其他的信息,比如字符集,导入其它外部样式表,字体等,这些需要专门的语句表示--即@规则

  • @namespace 告诉css引擎必须考虑XML命名空间
  • @media 如果满足媒体查询的条件则规则组里的规则生效
  • @page 在打印文档时修改某些CSS属性。
  • @font-face 指定了一个用于显示的自定义字体
  • @keyframes 描述CSS动画的关键帧
  • @document 如果文档样式表满足给定条件则条件规则组里的规则生效。 (推延至 CSS Level 4 规范,又被移除)
  • @charset "UTF-8"; 定义样式所使用的字符集
  • @import 用于告诉CSS引擎引入的一个外部样式表
  • @supports 用于查询特定的CSS是否生效,可以结合not、and 和 or等一起使用。
css
/* 如果支持自定义属性,则把body颜色设置为变量varName指定的颜色 */ @supports(--foo: green) { body { color: var(--varName); } }

CSS文件用什么字符编码呢?

某个样式表文件到底用什么字符编码,浏览器一套识别顺序(优先级从高到低):

  • 文件开头的Byte Order mark字符值,一般编辑器并不能看到文件头里的BOM值,要使用十六进制编辑器;
  • HTTP响应头里的 content-type字段包含的charset所指定的值,比如 Content-type: text/css; charset=utf-8
  • CSS头里定义的@charset规则里指定的字符编码
  • <link>标签里的charset属性,该条已在HTML5中废除
  • 默认就是 UTF-8
  • link是HTML标签,除了能导入CSS外,还能导入别的资源,比如图片favorite.ico、脚本和字体等;而@import是CSS语法,只能用来导入CSS;
  • link导入的样式不会阻塞DOM解析,它是并行下载,@import则是需要等页面加载完成后再加载
  • link可以通过JS操作DOM动态引入样式表改变样式,而@import不可以

重要的CSS属性

position

它指定了应用到元素的定位类型

  • static 默认属性 置顶元素按照常规的文档流进行定位
  • absolute 指定元素相对于它包含的元素进行定位。脱离文档流,要么相对于最近定位的祖先元素,要么是相对于文档本身(html标签的父元素)
  • fixed 该值相对于浏览器窗口进行定位。固定定位的元素总是显示在那里,不随文档其他部分而滚动。脱离文档流
  • reactive 按照常规文档流进行定位,它的定位相对于它在文档流中的位置进行调整
  • sticky 生成粘性定位的元素, 容器的位置根据正常文档流计算得出

注意事项:

  • absolutestickyfixed会受到transform | perspective | filter属性的影响

    position: fixed 能够相对于浏览器窗口放置有一个条件,那就是不能有任何祖先元素设置了 transform、perspective 或者 filter 样式属性。 引用自vue Teleport

  • z-index 只对兄弟元素叠加应用效果

颜色、透明度、半透明度

  • 颜色定义的几中方法
    • 十六进制 #fafafa #eee
    • rgba rgba(255,255,255, 0) 最后一位是透明度 【0, 1】
    • HSL (色相-饱和度-值)
  • 透明度
    • opacity 取值【0, 1】 IE 用 filter filter: alpha(opacity=75)
  • 部分可见 overflowclip

样式继承

继承的理解:设置在父元素或祖先元素上的样式被子元素继承。

  • 不可继承的CSS属性:displaymarginborderpaddingbackgroundheightmin-heightmax-heightwidthmin-widthmax-widthoverflowpositionleftrighttopbottomz-indexfloatcleartable-layoutvertical-alignpage-break-afterpage-bread-beforeunicode-bidi
  • 所有元素可继承:visibilitycursor。 内联元素可继承:letter-spacingword-spacingwhite-spaceline-heightcolorfontfont-familyfont-sizefont-stylefont-variantfont-weighttext-decorationtext-transformdirection
  • 终端块状元素可继承:text-indenttext-align
  • 列表元素可继承:list-stylelist-style-typelist-style-positionlist-style-image

哪些属性属于默认继承很大程度上是由常识决定的。

控制继承

  • inherit  开启继承
  • initial  让当前属性恢复为默认值。
  • unset   如果属性是自然继承那么就是 inherit,否则和 initial一样
  • revert   当前属性的样式恢复为浏览器默认的样式
  • all    批量设置(如all:unset), 值为以上四个值之一。

initial与revert的区别

html
<!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <style> .revert-ol { list-style: none; } </style> </head> <body> <ol class="revert-ol" style="list-style-type: revert"> <li>ol标签浏览器内置的样式为 ol{ list-style-type: decimal }</li> <li>revert关键字可以让当前元素的样式还原成浏览器内置的样式</li> </ol> <hr> <ol class="revert-ol" style="list-style-type: initial"> <li>CSS属性list-style-type的默认值对于disc</li> <li>initial关键字可以让当前属性恢复为默认值</li> </ol> </body> </html>

运行效果

all:revert 样式格式化

html
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <style> .ui-button { display: inline-block; line-height: 20px; font-size: 14px; text-align: center; color: #4c5161; border-radius: 4px; padding: 10px 15px; min-width: 80px; border: none; background-color: #2a80eb; color: #fff; box-sizing: border-box; font-family: inherit; cursor: pointer; overflow: visible; } </style> </head> <body> <button>button标签浏览器默认样式</button> <button class="ui-button">button.ui-button美美的按钮</button> <br><br><br> <button class="ui-button" style="all:initial">button.ui-button style="all:initial"</button> <button class="ui-button" style="all:revert">button.ui-button style="all:revert"</button> </body> </html>

运行效果

参考资料:

CSS是如何工作的

image.png

CSS解析方式: 从右往左(为了最快定位到目标元素)

常见问题

当浏览器遇到无法解析的CSS会怎样?

浏览器什么也不会做,继续解析下一个CSS样式,错误的属性、值及规则都会跳过。(除了注释、CSS规则集及@规则外,定义的一些别的东西都将被浏览器忽略)。

CSS如何降级?

css
.box { width: 500px; /* 不支持calc函数的浏览器将会降级为 500px */ width: calc(100%-50px); }

CSS有哪些样式表

  • 内部样式表 <style>
  • 行内样式表(内联式)style属性
  • 外部样式表 (外链式) <link rel="stylesheet" href="CSS的文件路径">

CSS为什么不建议使用@import方式加载css?

  • 首先link标签href 是异步加载,只有当前css文件被下载解析之后,浏览器才知道还有另外的一个CSS需要下载,这时候才去下载 解析构建 渲染等,
  • 因此使用@import引起堵塞css解析延迟会加长页面白屏时间,所以要避免使用@import 尽量采用link标签方式引入。

CSS 单位

image.png

  1. em 相对长度单位。是相对于父元素的字体大小进行计算的。
    • 如果当前对行内文本的字体尺寸没被人为设置,则相对于浏览器的默认字体尺寸
    • 任意浏览器的默认字体都是16px1em=16px,那么10px=0.625em
    • 为了简化font-size的换算,需要在CSS中body选择器中声明 font-size: 62.5%,这就是的em值变为 16px*62.5%=10px=1em 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了.
  2. rem 相对于跟元素(html)的font-size的单位。 >=IE9
  3. ex ch排版用的单位
    • ex 只得是小写字母x的高度,不同字体小写x的高度是不一样的。
    • chex类似,它是基于数字0的宽度计算的,会随着字体的变化而变化。而0的宽度通常是对字体的平均字符宽度,它是一个估计值。由于ch是一个近似等宽的单元,所以在设置容器的宽度时很有用,比如一个容器想要显示指定个数的字符串时,就可以使用这个单位。save.gif
  4. vw|vh|vmax| vmin
    • vw  视窗宽度的百分比 网页视口高度的1/100
    • vh  视窗高度的百分比
    • vmaxvwvh的较大值
    • vminvwvh的较小值
  5. 绝对单位 pxptpccmmmin
    • px像素Pixel 相对于显示器屏幕分辨率
    • 1in = 25.4mm = 2.54cm = 6pc = 72pt = 96px
    • 1pc = 16px 1pt = 1.3333px
  6. 百分比单位
    • 盒模型的百分比 简单说就是相对于块级盒模型
      • widthmax-widthmin-width:值为百分比时,其相对于包含块的 width 进行计算
      • heightmax-heightmin-height:值为百分比时,其相对于包含块的 height 进行计算;
      • paddingmargin:值为百分比时,如果是水平的值,就是相对于包含块的 width 进行计算;如果是垂直的值,就是相对于包含块的 height 进行计算。
    • 文本中的百分比
      • font-size会继承父元素的font-size
      • line-height根据font-size进行计算;
      • vertical-align根据line-height进行计算;
      • text-indent如果是水平的,则根据width进行计算,如果是垂直的,则根据height进行计算
    • 定位中的百分比 相对于定位的元素
    • 变换中的百分比 相对于当前元素
  7. 屏幕尺寸
    • image.png
    • window.screen.height 屏幕高度 667
    • window.innerHeight 网页视口高度 553
    • document.body.clientHeight body 高度

line-height

浏览器默认文字大小 16px 默认行高: 18pxinlne-height) 行高 = 文字大小+上间距+下间距

行高的作用: 当行高值为父容器的高度时,可以让父容器中的文字垂直显示

当给一个独立的元素设置行高值的时候,除了以px为单位的行高值与文字大小无关,其他都与文字大小有关(与文字大小的积)

行高单位赋值文字大小行高值
px20px20px20px
em2em20px20px
%200%20px40px
不带单位220px40px

盒子嵌套:

  • 给父元素设置行高值,子元素的行高(子元素没有设置行高的情况下)可以实现继承,
  • 如果设置的行高时具体数值比如2则子元素行高=子元素字体*2
行高单位父元素line-height父元素文字大小子元素文字大小子元素行高值
px20px20px30px20px
em2em20px30px40px
%200%20px30px40px
不带单位220px30px60px

盒模型

在页面中,每一个元素被表示成一个矩形的方框,被称为盒子。元素在页面中会生成盒子,一张页面由一个或多个盒子组成,这就是盒模型。 盒子从内到外由内容(Content)、内边距(Padding)、边框(Border)和外边距(Margin)组成,如下图:

image.png

关于盒模型内容比较多,将在我的下一篇文章《CSS盒模型与布局》中讲解.

CSS选择器

选择器分类

CSS选择器.png

选择器优先级

image.png

规则总结

  1. !important > 内联样式 > ID选择器 > 【类选择器|属性选择器|伪类选择器】> 元素选择器 > 通配符选择器
    • 类选择器、属性选择器及伪类选择器,权重都一样不管是哪一种
      • 如有遇到属性选择器或伪类选择器>类选择器,请检查是否有选择器叠加
    • 关系(层次)选择器属于叠加选择器,请参考下面的权重计算
    • 伪元素选择器不与其他选择器冲突,故不参与比较
    • 选择器优先于html元素选择器
  2. 权重问题
    • 权重计算采用不进位制,即无论多少个class选择器叠加都小于ID选器器的优先级
    • 含多个权重的选择器优先级比较应该拆开来看,依次从高到底比较
    • 通过计数的方式比较,计数大的优先级高
    • 相同权重后写的者优先(class属性值类的顺序不影响优先级)
      • 类选择器 a b c 属于嵌套关系 .a .c 与 .b .c 谁后写谁的优先级高

JS操作CSS

脚本化内联样式

脚本化CSS最直接了当的方法是修改style属性。style属性的值是CSSDeclaration对象。

  • ele.style.fontSize = '24px'
  • ele.setAttribute | ele.getAttribute方法
  • ele.style.cssText = 'font-size:24px' 注意:
  • 有个特殊情况 cssFloat (因为float是JS保留字)
  • IOS10不支持ele.style.xxx= 'XXX'写法,推荐使用setAttribute方法

优点:

  • 设置样式非常方便

缺点:

  • 如果属性值带有单位,或者读取复合属性的值 解析就不那么方便

所以如果需要查询样式时,就需要使用计算样式

查询计算出的样式

getComputedStyle(elt: Element, pseudoElt?: string | null): CSSStyleDeclaration 与内联样式之间的异同

相同点

  • 计算样式也是CSSdeclaration对象

不同点

  • 但它是只读的
  • 计算样式的值是绝对值
  • 不返回复合属性
  • 计算样式的cssText属性为定义

缺点

  • 读取fontFamily属性时返回 ‘arial,helvetica,sans-serif’的值,你无法获知系统使用的哪种字体
  • 某些属性可能会得到“auto”,这也大概不是你想要的(可通过ele.getBoundingClientRect方法解决)

脚本化CSS类

  • ele.className = 'XXX'
  • ele.classList 该属性值是一个DOMTokenList对象,一个只读的类数组对象
    • .add .remove .toggle .contains方法
    • 该对象具有 “实时性”

脚本化样式表

  • document.styleSheets CSSStyleSheet对象
  • 开启or关闭样式表 document.styleSheets[X].disable = boolean
  • 查询 var firstRules = document.styleSheets[0].cssRules[0] (IE是.rules)
  • 增加规则 .insertRules('XXX', index) IE .addRules
  • 删除规则 .deleteRules(index) IE .removeRules
  • 创建样式表
    • 非IE8
      • var s = document.createElement('style');
      • s.innerHTML = '*{color:red;}';
      • document.head.appendChild(s);
    • IE && <= IE8
      • var s = document.createStyleSheet();
      • s.cssText = '*{color:red;}';

本文作者:郭敬文

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!