1.水平垂直居中

1.margin: 0 auto;水平2.text-align: center;水平3.行高,垂直4.表格,center,middle;水平垂直5.display:table-cell;模拟表格,all6.绝对定位,50%减自身宽高7.绝对定位,上下左右全0,margin:auto8.绝对定位加相对定位。不需要知道宽高9.IE6,IE7:给父元素设一个font-size:高度/1.14,vertical-align:middle





css面试题 - 图1
/ 1.flex布局 /
.parent {
width: 500px;
height: 500px;
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.children {
width: 200px;
height: 200px;
background: orange;
}
/ 2.绝对定位,上下左右全0,margin:auto /
.parent {
width: 500px;
height: 500px;
background: red;
position: relative;
}
.children {
width: 200px;
height: 200px;
background: orange;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
/ 3.绝对定位,上左50%,再用transform:translate偏移自身宽高的50% /
.parent {
width: 500px;
height: 500px;
background: red;
position: relative;
}
.children {
width: 200px;
height: 200px;
background: orange;
position: absolute;
top: 50%;
left: 50%;
transform:translate(-50%,-50%);
}
/ 4.子元素position: relative;横向利用margin auto,垂直还是利用定位和平移translate /
.parent {
width: 500px;
height: 500px;
background: red;
}
.children {
width: 200px;
height: 200px;
background: orange;
position: relative;
top: 50%;
margin-left: auto;
margin-right: auto;
transform:translateY(-50%);
}
/ 5.table布局 /
.parent {
width: 500px;
height: 500px;
background: red;
display: table;
text-align: center;
}
.children {
width: 200px;
height: 200px;
background: orange;
display: table-cell;
vertical-align: middle;
}
css面试题 - 图2
这只是一部分还有很多,可以自己尝试着做一下

2.清除浮动

css面试题 - 图3


children1

children1




css面试题 - 图4
css面试题 - 图5
.fahter{
width: 400px;
border: 1px solid deeppink;
}
.children1{
width: 200px;
height: 200px;
background: darkorange;
}
.children2{
width: 120px;
height: 120px;
background: darkmagenta;
}
.footer{
width: 900px;
height: 100px;
background: darkslateblue;
}
css面试题 - 图6
css面试题 - 图7 css面试题 - 图8
如上我们想让children1 和children2 浮动,但是设置了之后发现footer也上去了,而且父元素的宽度变成了一条线,这是因为没有给父元素设置高度,当没有浮动的时候就会子元素就会撑开父元的高度,当有浮动的时候就不会撑开了,这个时候就需要清除浮动了。
方法一:额外标签法,在div中添加一个标签clear

children1

children1

额外标签法


.clear{
clear:both;
}
方法二:after伪元素
.clearfix:after{/伪元素是行内元素 正常浏览器清除浮动方法/
content: “”;
display: block;
height: 0;
clear:both;
visibility: hidden;
}
.clearfix{
zoom: 1;/ie6清除浮动的方式 号只有IE6-IE7执行,其他浏览器不执行/
}
css面试题 - 图9
方法三:使用after 和before两个伪元素
css面试题 - 图10
.clearfix:after,.clearfix:before{
content: “”;
display: table;
}
.clearfix:after{
clear: both;
}
.clearfix{
*zoom: 1;
css面试题 - 图11
方法四:父元素overflow
.fahter{
width: 400px;
border: 1px solid blue;
overflow: hidden;
}
原理:

  • 因为该属性进行超出隐藏时需要计算盒子内所有元素的高度, 所以会隐式清除浮动
  • 创建BFC条件(满足一个)

    3.css预编译器

    https://blog.csdn.net/joehonv/article/details/81699572
    https://segmentfault.com/a/1190000018337119?utm_source=tag-newest
    https://zhuanlan.zhihu.com/p/38715068
    css预处理是基于css的一些缺陷,扩展了一套属于自己的语法,使编写的css可以复用、减少冗余代码,提高样式代码的可维护性。
    目前最主流的三个预处理器 Less、Sass 和 Stylus。Less 的基本语法属于「CSS 风格」,而 Sass、Stylus 相比之下激进一些,利用缩进、空格和换行来减少需要输入的字符。不过区别在于 Sass、Stylus 同时也兼容「CSS 风格」代码。三者的嵌套语法都是一致的,甚至连引用父级选择器的标记 & 也相同。区别只是 Sass 和 Stylus 可以用没有大括号的方式书写。

    4.margin:auto 为什么可以实现垂直居中?

    想要实现垂直方向的居中可以用绝对定位:
    css面试题 - 图12
    div {
    width: 20px;
    height: 20px;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    }
    css面试题 - 图13
    块状水平元素,如div元素(下同),在默认情况下(非浮动、绝对定位等),水平方向会自动填满外部的容器;如果有margin-left/margin-right,padding-left/padding-right,border-left-width/border-right-width等,实际内容区域会响应变窄。
    但是,当一个绝对定位元素,其对立定位方向属性同时有具体定位数值的时候,流体特性就发生了。具有流体特性绝对定位元素的margin:auto的填充规则和普通流体元素一模一样,含有以下特性:

  • 如果一侧定值,一侧auto,auto为剩余空间大小;

  • 如果两侧均是auto, 则平分剩余空间

    5.说说CSS选择器以及这些选择器的优先级

  • !important

  • 内联样式(1000)
  • ID选择器(0100)
  • 类选择器/属性选择器/伪类选择器(0010)
  • 元素选择器/关系选择器/伪元素选择器(0001)
  • 通配符选择器(0000)

    6.你知道什么是BFC么

    https://juejin.im/post/59b73d5bf265da064618731d
    https://juejin.im/entry/59c3713a518825396f4f6969
    https://juejin.im/post/5cee1b38e51d4556be5b39e1
    https://zhuanlan.zhihu.com/p/184905483
    BFC 全称为块级格式化上下文 (Block Formatting Context) 。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个BFC就是一个独立的行政单位的意思。可以说BFC就是一个作用范围,把它理解成是一个独立的容器,并且这个容器里box的布局与这个容器外的box毫不相干。
    特性:

  • 使 BFC 内部浮动元素不会到处乱跑;

  • 和浮动元素产生边界。

    触发BFC的条件

  • float的值不为none;

  • overflow的值不为visible;
  • position的值为fixed / absolute;
  • display的值为table-cell / table-caption / inline-block / flex / inline-flex。

    BFC的约束规则

  • 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流)

  • 处于同一个BFC中的元素相互影响,可能会发生外边距重叠
  • 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
  • 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算 ———-》利用这个特性可以清除浮动
  • 浮动盒区域不叠加到BFC上

    BFC可以解决的问题

  1. 解决浮动元素令父元素高度塌陷的问题如,父元素div包含几个子div,这几个子元素都为浮动时,父元素高度坍塌,这是因为浮动的子元素脱离了文档流,漂浮于父元素之上,父元素检测不到子元素的存在,获取不到子元素高度,所以看起来父元素没有高度了。父元素后面的布局也就乱了,这时,可以给父元素添加属性overflow:hidden,当然,这只是一种BFC的做法,还可以display: table-cell;或position: fixed;或position: absolute;

触发了BFC的容器就是页面上的一个完全隔离开的容器,容器里的子元素绝对不会影响到外面的元素,为了保证这个规则,触发了BFC的父元素在计算高度时,不得不让浮动的子元素也参与进来,变相的实现了清楚内部浮动的目的。
但有的时候出于布局需要也可能无法给父元素设置这些属性,解决高度坍塌还有让父元素也浮动起来,或添加一个高度,但这种适用于已知道子元素高度

  1. 解决自适应布局的问题PC端的网页,左右两栏布局很常见,一般左侧定宽,右侧主体页面宽度自适应变化,通常是用浮动来实现的;它利用了块级元素占满一行的特性,使得右边的元素可以随着页面宽度的变化而变化,又利用了浮动的特性,让左侧元素覆盖在右侧元素上方,同时还能挤开下方元素的内容,让页面看起来是两栏的效果,但随着右边元素的增加,超出了左边元素的高度后,文字就会环绕左侧元素,这显然不是我们想要的效果,因为右侧元素触发了BFC,触发BFC的容器就是页面上的一个完全隔离开的容器,容器中的子元素绝对不会影响到外面的元素,为了保证这个规则,触发了BFC的右侧元素为了将内部元素和左侧浮动元素隔离开,不得不形成这样左右完全隔离的两栏,同时,如果右侧元素依旧是块级元素,那么他尽可能占满一行的特性还在,这样就保证了右侧元素依旧是自适应的
  2. 解决外边距垂直方向重合问题

垂直方向上两个兄弟元素外边距会取最大值,而不是取和,那么我们可以通过触发BFC来防止他们之间相互影响。为其中一个元素的外边包裹一层父元素,并且触发父元素BFC,比如:overflow:hidden,这样打破原有格局,就不再会重叠啦!另外我们可以用padding来代替marging,有点是简单易懂,缺点是如果根据设计本来就需要设置padding样式,那就没办法用了
总结:

  • 垂直外边距重叠问题
  • 去除浮动 ——》 父元素添加overflow:hidden; (触发BFC) :原理: 因为该属性进行超出隐藏时需要计算盒子内所有元素的高度, 所以会隐式清除浮动 。
  • 自适用两列布局(float + overflow

    7.了解盒模型么

    css面试题 - 图14

    W3C盒子模型):元素的宽高大小表现为内容的大小
    (IE盒子模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。

    9.如何实现左侧宽度固定,右侧宽度自适应的布局




    利用float + margin实现:原理是创建bfc

    css面试题 - 图15
    .box {
    height: 200px;
    }

    .box > div {
    height: 100%;
    }

    .box-left {
    width: 200px;
    float: left;
    background-color: blue;
    }

    .box-right {
    margin-left: 200px;
    background-color: red;
    }
    css面试题 - 图16

利用calc计算宽度

css面试题 - 图17
.box {
height: 200px;
}

.box > div {
height: 100%;
}

.box-left {
width: 200px;
float: left;
background-color: blue;
}

.box-right {
width: calc(100% - 200px);
float: right;
background-color: red;
}
css面试题 - 图18

利用float + overflow实现

css面试题 - 图19
.box {
height: 200px;
}

.box > div {
height: 100%;
}

.box-left {
width: 200px;
float: left;
background-color: blue;
}

.box-right {
overflow: hidden;
background-color: red;
}
css面试题 - 图20

利用flex实现

css面试题 - 图21
.box {
height: 200px;
display: flex;
}

.box > div {
height: 100%;
}

.box-left {
width: 200px;
background-color: blue;
}

.box-right {
flex: 1; // 设置flex-grow属性为1,默认为0
overflow: hidden;
background-color: red;
}
css面试题 - 图22

10.用过Flex么,能简单介绍一下

https://juejin.im/post/58e3a5a0a0bb9f0069fc16bb
https://juejin.im/post/5e72eca86fb9a07cd80f410f

小提示:如果在项目中使用过,可简单介绍一下自己使用Flex解决过什么问题,这里我在项目中印象比较深刻的是使用Flex解决上面内容高度不固定,下面内容高度自动撑满父容器剩余高度的问题。

如果不是很清楚Flex,可以查看阮一峰的文章Flex 布局教程:语法篇。面试官追问,那么除了Flex,你还知道Grid么?这个由于兼容性问题,我一直没有好好研究过,这里可查看阮一峰的文章CSS Grid网格布局教程。
flex: 1; === flex: 1 1 0%;

  • 第一个参数表示: flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
  • 第二个参数表示: flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
  • 第三个参数表示: flex-basis**给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小**

    11.伪类和伪元素的区别

    1)伪类(pseudo-classes)

  • 其核⼼就是⽤来选择DOM树之外的信息,不能够被普通选择器选择的⽂档之外的元素,⽤来添加⼀些选择器的特殊效果。

  • ⽐如:hover :active :visited :link :visited :first-child :focus :lang等
  • 由于状态的变化是⾮静态的,所以元素达到⼀个特定状态时,它可能得到⼀个伪类的样式;当状态改变时,它⼜会失去这个样式。
  • 由此可以看出,它的功能和class有些类似,但它是基于⽂档之外的抽象,所以叫 伪类。

2)伪元素(Pseudo-elements)

  • DOM树没有定义的虚拟元素
  • 核⼼就是需要创建通常不存在于⽂档中的元素,
  • ⽐如::before ::after 它选择的是元素指定内容,表示选择元素内容的之前内容或之后内容。
  • 伪元素控制的内容和元素是没有差别的,但是它本身只是基于元素的抽象,并不存在于⽂档中,所以称为伪元素。⽤于将特殊的效果添加到某些选择器

2)伪类与伪元素的区别

  • 表示⽅法
    • CSS2 中伪类、伪元素都是以单冒号:表示,
    • CSS2.1 后规定伪类⽤单冒号表示,伪元素⽤双冒号::表示,
    • 浏览器同样接受 CSS2 时代已经存在的伪元素(:before, :after, :first�line, :first-letter 等)的单冒号写法。
    • CSS2 之后所有新增的伪元素(如::selection),应该采⽤双冒号的写法。
    • CSS3中,伪类与伪元素在语法上也有所区别,伪元素修改为以::开头。浏览器对以:开头的伪元素也继续⽀持,但建议规范书写为::开头
  • 定义不同
    • 伪类即假的类,可以添加类来达到效果
    • 伪元素即假元素,需要通过添加元素才能达到效果
  • 总结:
    • 伪类和伪元素都是⽤来表示⽂档树以外的”元素”。
    • 伪类和伪元素分别⽤单冒号:和双冒号::来表示。
    • 伪类和伪元素的区别,关键点在于如果没有伪元素(或伪类),
    • 是否需要添加元素才能达到效果,如果是则是伪元素,反之则是伪类。

4)相同之处:

  • 伪类和伪元素都不出现在源⽂件和DOM树中。也就是说在html源⽂件中是看不到伪类和伪元素的。不同之处:
  • 伪类其实就是基于普通DOM元素⽽产⽣的不同状态,他是DOM元素的某⼀特征。
  • 伪元素能够创建在DOM树中不存在的抽象对象,⽽且这些抽象对象是能够访问到的。

    12.绝对定位

    小提示:这个建议大家好好回忆一下,例如子元素是相对父元素的padding、border还是content进行定位之类的,当时面试官问的就这么细。

    13.说说z-index有什么需要注意的地方

    css面试题 - 图23

14.熟悉CSS3动画么

15.Flex实现两列布局

css面试题 - 图24


.box {
height: 200px;
display: flex;
}

.box > div {
height: 100%;
}

.box-left {
width: 200px;
background-color: blue;
}

.box-right {
flex: 1; // 设置flex-grow属性为1,默认为0
overflow: hidden;
background-color: red;
}
css面试题 - 图25

16.绝对定位、固定定位和z-index

小提示:感谢CBU技术部的面试官。

绝对定位

  • 一旦给元素加上absolutefloat就相当于给元素加上了display:block
  • absolute元素覆盖正常文档流内元素(不用设z-index,自然覆盖)
  • 可以减少重绘和回流的开销(如absolute+ top:-9999em,或absolute + visibility:hidden,将动画效果放到absolute元素中)

    属性介绍

  • static,默认值。位置设置为static的元素,它始终会处于文档流给予的位置。

  • inherit,规定应该从父元素继承 position 属性的值。但是任何的版本的 Internet Explorer (包括 IE8)都不支持属性值 “inherit”。
  • fixed,生成绝对定位的元素。默认情况下,可定位于相对于浏览器窗口的指定坐标。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。不论窗口滚动与否,元素都会留在那个位置。但当祖先元素具有transform属性且不为none时,就会相对于祖先元素指定坐标,而不是浏览器窗口。
  • absolute,生成绝对定位的元素,相对于距该元素最近的已定位的祖先元素进行定位。此元素的位置可通过 “left”、”top”、”right” 以及 “bottom” 属性来规定。
  • relative,生成相对定位的元素,相对于该元素在文档中的初始位置进行定位。通过 “left”、”top”、”right” 以及 “bottom” 属性来设置此元素相对于自身位置的偏移。

浮动、绝对定位和固定定位会脱离文档流,相对定位不会脱离文档流,绝对定位相对于该元素最近的已定位的祖先元素,如果没有一个祖先元素设置定位,那么参照物是body层。
绝对定位相对于包含块的起始位置:

  • 如果祖先元素是块级元素,包含块则设置为该元素的内边距边界。
  • 如果祖先元素是行内元素,包含块则设置为该祖先元素的内容边界。

问答题:

  • 定位的元素的起始位置为父包含块的内边距(不会在border里,除非使用负值,会在padding里)
  • 定位的元素的margin还是能起作用的
  • background属性是会显示在border里的
  • z-index是有层叠层级的,需要考虑同一个层叠上下文的层叠优先级
  • z-index是负值不会覆盖包含块的背景色(但是如果有内容,会被包含块的内容覆盖)
  • z-index的值影响的元素是定位元素以及flex盒子
  • 上面一个定位元素,下面一个正常流的元素,定位元素会覆盖在正常流元素之上,除非给z-index是负值
  • 页面根元素html天生具有层叠上下文,称之为“根层叠上下文”

    17.css预编译语言是什么

    18.pc端和移动端像素不同,如何兼容?

    第一种是通过响应式或页面终端判断去实现一套资源适配所有终端; 
    优势:只需维护一套资源,维护成本较低。
      劣势:需加载适配各个终端的各个资源,在不同终端通过响应式布局实现不同展现,部分交互效果需要在页面中做终端判断,代价较大,若图片资源为一套,部分图片在超高分辨率设备(例如iphone系列)下会失真,且在非wifi情况下即使加了延时加载也易出现加载慢的情况。
      技术选型:jquery(或原生js等)+ 响应式 + 前端模块加载器(seajs或RequireJS等)+ css预处理器(sass 或less等)。jquery较好的兼容性配合响应式可相对代价较小地实现跨终端。前端模块加载器主要负责按需加载,以提高页面加载速度,css预处理器 的变量、运算、嵌套等特性可大大提高手动计算响应式的效率,妈妈再也不用担心我把比例算错了。当然后两者可参考需求及成本决定是否采用。
    第二种是通过终端判断分别调取两套资源以适配所有终端。

优势:可根据不同端做个性设计及个性化信息推送且可按需加载,如移动端可配合重力感应、不同手势做各种炫酷拽效果,pc页面可不受流量限制做适合pc端的效果。
  劣势:需维护两套资源,维护成本增加。
  技术选型:zepto(或xui等移动端轻量级框架)+ 响应式 + 前端模块加载器 + css预处理器 + 终端适配。zepto作为jquery的移动端版本,依然延续其自身优势,大幅优化了移动端API且摒弃了兼容”非现代浏览器”的冗余代码,成为移动端轻 便可用的js框架代表,对于习惯了jquery的同学来说简直是不二之选!
  终端适配目前一般通过ua判断来实现。ua判断可放在服务端也可放在页面中,在代理服务器中做跳转更快、更准确且不走应用程序层,即使浏览器禁用了js依然可以跳转到相应的地址,同时秉承着公共服务放在服务端这样的云端服务理念,我们选择了通过代理服务器做终端适配。
User-Agent嗅探,即Web浏览器发送一个Web页面或资源请求时,会发送一个User-Agent首部作为HTTP请求的一部分,那么我们就可以在服务器端获取想要的信息,进而判断并引导用户到达相应的页面地址。

二、pc上的网站在移动端上怎么办?
如果把移动端的可视区域(320-768)的话,大部分网站都会因为太窄而显示错乱;所以浏览器默认把viewport设置为一个较宽的值 980px或1024px,至少保证PC网站在移动端上可以显示,只不过出现了横向滚动条而已。

19.box-sizing

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

  • content-box 标准盒子模型
    默认值,标准盒子模型。 [width](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width)[height](https://developer.mozilla.org/zh-CN/docs/Web/CSS/height) 只包括内容的宽和高, 不包括边框(border),内边距(padding),外边距(margin)。注意: 内边距、边框和外边距都在这个盒子的外部。 比如说,.box {width: 350px; border: 10px solid black;} 在浏览器中的渲染的实际宽度将是 370px。 尺寸计算公式:
    width = 内容的宽度
    height = 内容的高度
    宽度和高度的计算值都不包含内容的边框(border)和内边距(padding)。
  • border-box ie盒模型
    [width](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width)[height](https://developer.mozilla.org/zh-CN/docs/Web/CSS/height) 属性包括内容,内边距和边框,但不包括外边距。这是当文档处于 Quirks模式 时Internet Explorer使用的盒模型。注意,填充和边框将在盒子内 , 例如, .box {width: 350px; border: 10px solid black;} 导致在浏览器中呈现的宽度为350px的盒子。内容框不能为负,并且被分配到0,使得不可能使用border-box使元素消失。 尺寸计算公式:
    _width_ = border + padding + 内容的宽度
    _height_ = border + padding + 内容的高度

    20.height:100%和height:100vh的区别

    vw:viewpoint width,视窗宽度,1vw等于视窗宽度的1%。vh:viewpoint height,视窗高度,1vh等于视窗高度的1%。vmin:vw和vh中较小的那个。vmax:vw和vh中较大的那个。
    vh就是当前屏幕可见高度的1%,也就是说
    height:100vh == height:100%;
    但是当元素没有内容时候,设置height:100%,该元素不会被撑开,此时高度为0,
    但是设置height:100vh,该元素会被撑开屏幕高度一致。
  1. 居中对齐的方式
  2. bfc
    块级格式化上下文,
  3. scope中改变 element css
    1.样式穿透 >>> .el-input { width: 178px; }
    ::deep Sass 之类的预处理器无法正确解析 >>> 需要用::deep
    2.

    1. 3.命名空间。
  4. flex兼容性 ie都不兼容

  5. 解决css3的兼容性问题 postcss
    https://www.cnblogs.com/mmykdbc/p/6921608.html

    21.box-sizing

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

    属性值

  • content-box
    默认值,标准盒子模型。 [width](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width)[height](https://developer.mozilla.org/zh-CN/docs/Web/CSS/height) 只包括内容的宽和高, 不包括边框(border),内边距(padding),外边距(margin)。注意: 内边距、边框和外边距都在这个盒子的外部。 比如说,.box {width: 350px; border: 10px solid black;} 在浏览器中的渲染的实际宽度将是 370px。 尺寸计算公式:
    width = 内容的宽度
    height = 内容的高度
    宽度和高度的计算值都不包含内容的边框(border)和内边距(padding)。
  • border-box
    [width](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width)[height](https://developer.mozilla.org/zh-CN/docs/Web/CSS/height) 属性包括内容,内边距和边框,但不包括外边距。这是当文档处于 Quirks模式 时Internet Explorer使用的盒模型。注意,填充和边框将在盒子内 , 例如, .box {width: 350px; border: 10px solid black;} 导致在浏览器中呈现的宽度为350px的盒子。内容框不能为负,并且被分配到0,使得不可能使用border-box使元素消失。 尺寸计算公式:
    _width_ = border + padding + 内容的宽度
    _height_ = border + padding + 内容的高度

    22.1px边框问题

    https://www.cnblogs.com/lyt0207/p/12350741.html

    23.分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景

    display: none (不占空间,不能点击)(场景,显示出原来这里不存在的结
    构)
     visibility: hidden(占据空间,不能点击)(场景:显示不会导致页面结
    构发生变动,不会撑开)
     opacity: 0(占据空间,可以点击)(场景:可以跟 transition 搭配)

如何实现样式隔离

解题:

  • 初阶:
    • 是什么:
    • 为什么:
      • 全局污染:原生CSS不支持局部作用域,容易出现全局冲突,特别在当前 spa、微前端 盛行的情况下,多人同时开发一个应用时,如果没有规则限制,很容易出现样式冲突
      • 层叠混乱:并且css支持层叠,即使冲突了也没法很快知道
      • 依赖管理混乱:并且,你很难知道某个样式规则被哪些地方用到,随着项目的发展你可能会积累一堆实际已经没用,但不敢删除的样式规则(append-only stylesheets)
        • 性能差、维护成本高
      • 引入顺序、组件嵌套,都可能导致样式冲突
    • 怎么做:BEM、CSS modules、CSS Layer、css-in-js(styled-component)、web component、iframe、vue-scoped
  • 中阶:
    • BEM命名规则:使用简单,可读性强(Block)、元素(Element)、修饰符(Modifier),
      • 缺点是依赖开发者遵循命名规则,容易出问题;依然有命名成本,需要小心规避不出现冲突,可能导致命名会特别长
      • 包括 antd 之类的组件库,至今依然使用类似 bem 的命名规则
    • CSS Modules:模块化的 css 文件,这是一种在构建时添加 scope 信息的工程化手段,例如使用 css-loader 并设置 modules=true
      • 简单易用,能够用工具替代规范约束;能够复用一堆 css 预处理器
      • 缺点:依赖构建工具,可能影响构建速度;最终代码可读性差,debug 成本高;css-modules 能力比较弱,不支持变量等,通常需要配合 less 等预处理器使用 ```javascript .title { color: red; }

._3zyde4l1yATCOkgn-DBWEL { color: red; }

  1. - CSS-IN-JS:把样式代码直接写在组件中,并最终生成为 style 代码 + 唯一选择器,插入页面;或生成行内样式,插入组件标签中
  2. - 优点:可选择工具非常多 styled-componetsvanilla-extract 等;样式与组件强相关,不太会造成历史遗留代码问题;
  3. - 缺点:大多数都是运行时生成样式代码,运行时开销大(运行时代码 + 动态生成);代码可读性差,不容易 debug;不能复用成熟的预处理工具
  4. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/26698409/1661669838390-eff70638-fb52-4455-95b7-0889381fb289.png#clientId=u641cf19f-60ab-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=634&id=u72c23f97&margin=%5Bobject%20Object%5D&name=image.png&originHeight=860&originWidth=1080&originalType=binary&ratio=1&rotation=0&showTitle=false&size=323755&status=done&style=none&taskId=ue3cc53f3-55fb-46da-92e1-f96f6a2ceec&title=&width=796)
  5. - iframe:嵌套子页面
  6. - 优点:严格意义的样式与内容隔离
  7. - 缺点:iframe 太重,成本略高,除微应用场景外不建议使用;严格隔离,所以无法影响全局样式
  8. - web component:用于封装html结构、js逻辑、样式结构的浏览器原生 api,能够有效隔离 web component 与页面代码
  9. - 优点:浏览器原生支持;严格意义上的样式隔离,与 iframe 效果差不多;
  10. - 缺点:学习成本略高;浏览器兼容问题;无法影响全局样式
  11. - Vue Scopedvue sfc 提供的样式隔离手段
  12. - 优点:简单,且支持 deep 等指令后,能够实现子组件的样式效果;配合 sfc 规则,样式结构更清晰
  13. - 缺点:只适用于 vue 框架;只适用于组件级别的样式定义
  14. ```javascript
  15. <style scoped>
  16. .example {
  17. color: red;
  18. }
  19. </style>
  20. <template>
  21. <div class="example">hi</div>
  22. </template>
  23. <style>
  24. .example[data-v-f3f3eg9] {
  25. color: red;
  26. }
  27. </style>
  28. <template>
  29. <div class="example" data-v-f3f3eg9>hi</div>
  30. </template>
  • css 新 layer 规范:在 css 基础上加多一个 layer 概念,明确定义部分样式集的层叠优先级:对于处在不同层中的样式,无视样式本身的权重,后声明的层中的样式优先级更高,不在层中的样式优先级最高
    • 优点:未来可期;算是解决问题的一种新尝试;
    • 缺点:本质上,只是一个组织 CSS、避免选择器权重导致问题的方式,不是样式隔离手段;还未成为正式规范,但算的上一个创新特性,未来必然会影响 css 写法
      • 高阶:
  • 可能顺带复习一下你所熟悉的 css-in-js 工具的实现原理,按需介绍
  • 可以重点提一提 vanilla-extract,这是一个 0 运行时的高效 css-in-js 框架