CSS 八股文
一、盒模型与基础显示模型
什么是盒模型?
盒模型是浏览器在渲染元素的时候采用的一种盒子模型。包含了content、padding、border、margin四个部分。
**请说明 content / padding / border / margin 各自的含义。 **
- content:代表着盒子模型的内容区域
- padding:是内容区域和边框之间的内边距
- border:是盒子的边框
- margin:是边框和外部元素的外边距
标准盒模型和 IE 盒模型有什么区别?
标准盒子模型的宽度在定义的时候是由content决定的。
而IE盒子模型的宽度是由content+padding+border决定的。
box-sizing: content-box 和 box-sizing: border-box 的区别是什么?box-sizing: content-box就是将盒子模型设置为标准盒子,这也是盒子模型的默认值。
而box-sizing: border-box就是将盒子模型设置为IE盒子,这种盒子模型更适合在生产中做实际布局。
width: 200px 在两种盒模型下分别表示什么?
在标准盒子模型的时候width: 200px代表了content区域占据了200像素的宽度,如果在padding上增加宽度,将会增加这个元素整体大小。
在IE盒子模型的时候width: 200px代表 了content加padding再加上border的区域占据了200像素的宽度,如果这个时候增加padding的宽度,元素的大小是不变的,但是内容content区域会被挤压。
display: block、inline、inline-block 的区别是什么?
1、display: block:代表着将当前元素定义为块级元素,可以定义宽高,默认的宽度是占满父容器可用宽度。
2、display: inline:代表了将当前元素定义为行内元素,不能定义宽高。元素大小由content进行撑开。
3、display: inline-block:代表了将当前元素定义为行内元素,但是可以定义宽高。
块级元素和行内元素各自有哪些特点?
块级元素能够独占一行。默认从上往下排列,默认宽度占满父元素的可用宽度。并且可以嵌入别的块级和行内元素
行内元素是和其他元素在同一行的,默认从左往右排列,元素大小由内容撑开,并且只能嵌入别的行内元素。
在现代css中,区分不明显,所有的元素都可以通过dispaly定义属性。
line-height 和 height 的区别是什么?line-height是一行文字的行高,代表了一行的宽度,或者块级元素中每一行的宽度。height是盒子的高度。
设置一个元素的背景色时,背景会填充到哪些区域?
背景会填充到content区域和padding区域,不会填充到border和margin区域。
再具体到背景部分是否会侵入border区域,需要盒子的类型。
裁剪范围还可以使用background-clip进行控制。
border-box,会绘制到border区域。
content-box,不会绘制到border区域。
而padding-box就只会侵入到padding区域,而不会填边框里面。
追问:
为什么项目里一般会全局加 box-sizing: border-box?
因为这样 width/height 更符合直觉,设置的宽高会包含 padding 和 border,布局更稳定,不容易因为加内边距或边框把盒子撑大。
尤其在响应式布局和组件化开发中,border-box 能减少尺寸计算成本,提高布局稳定性。
inline 为什么设置 width、height 不生效?
因为 inline 元素参与的是行内格式化上下文,它主要跟随文本流排版,尺寸通常由内容和行高决定,而不是像块级盒子那样按显式宽高布局。
背景色会铺到 margin 吗?为什么?
不会。margin 表示元素和外界之间的间隔,不属于元素自身绘制区域。背景通常只绘制到 border 内部范围。
单行文字垂直居中为什么常用 line-height = height?那多行为什么不行?
因为单行文本的行盒高度等于 line-height,把它设成和容器高度一致时,文字在视觉上会垂直居中。多行文本每一行都有自己的 line box,整体排版不再等同于单个 line-height,所以这种方式不适合多行。
二、选择器、优先级、继承
CSS 常见选择器有哪些?请尽量说全。
1、*:通配符选择器,可以使用*选中全局元素。
2、body:标签选择器,通过元素的名字进行选中
3、body div:后代标签选择器,可以选中某个元素中的里面所有后代
4、body > div:子代选择器,只选直接子元素。
5、.类名:类选择器,可以在html为元素设置class属性,之后使用类选择器进行选中
6、#id名:id选择器,同类名选择器
7、h1 + p :相邻兄弟选择器。
8、input[type="text"] { }:属性选择器,
1 | [class^="icon-"] { } /* 以 icon- 开头 */ |
也是属性选择器的一种。
9、伪类选择器,选中的是状态
1 | a:hover { } /* 鼠标悬停 */ |
10、伪元素选择器,选“虚拟出来的部分”
1 | ::before { } |
CSS 选择器优先级怎么计算?
!importent > 行内样式 > id选择器 > class选择器/伪类/属性选择器 > 标签选择器/伪元素选择器 > 通配符选择器 > 继承下来的属性
!important、行内样式、id、class、标签,优先级顺序是什么?!important > 行内样式 > id > class > 标签
优先级相同的时候,最终谁生效?
谁在后谁生效。
伪类和伪元素有什么区别?
伪类元素用于选中某些元素的状态,而伪元素用于选中某些元素中虚拟出来的部分。
常见伪类有哪些?
:hover
:focus
:first-child
:last-child
:nth-child(2n)
常见伪元素有哪些?
::before
::after
::first-line
::section
CSS 中哪些属性可以继承?
一些文本相关的属性,如 color、font-family、line-height 等是可以继承的。
哪些通常不能继承?
一些盒子相关的属性,如 width、height、margin、padding 等通常是不能继承的。
如何理解 CSS 的覆盖原则和继承规则?
CSS 的覆盖原则是指当多个规则作用于同一元素时,浏览器会根据优先级、来源和位置等因素来决定哪个规则最终生效。优先级较高的规则会覆盖优先级较低的规则。
CSS 的继承规则是指某些属性会自动从父元素继承到子元素,这些属性主要是与文本相关的属性,如 color、font-family、line-height 等。对于不继承的属性,子元素需要显式地设置才能生效。
三、定位与层叠
position 有哪些取值?分别有什么区别?
position的取值有:
1、fixed : 脱离文档流,让当前元素基于视口定位
2、relative : 不脱离文档流,保留其自己的原来位置,并通过top、left、right、bottom等属性相对于原来的位置进行位移。
3、absolute : 脱离文档流,让当前元素基于最近进行定位设置过的祖先元素的绝对位置定位。都没有设置过的话就相对初始html块进行定位
4、sticky :不脱离文档流,让当前元素在页面滑动到某一阈值的时候进行吸附定位
5、static :默认值,元素按照正常的文档流进行定位
relative 和 absolute 的区别是什么?
relative 不会让元素脱离文档流,元素的位置是相对于它正常位置的偏移。
absolute 定位会让元素脱离文档流,元素的位置是相对于最近的做过定位父元素的定位。
absolute 的定位参考系是谁?
是其最近做过定位的父元素。没有的话相对根元素html定位
fixed 和 sticky 的核心区别是什么?
核心区别是fixed脱离文档流,sticky不脱离文档流。
fixed是让元素相对于视口进行定位,通常可以做一些返回顶部的按钮等。
sticky是让元素在页面滑动到某一阈值的时候,相对视口进行吸附定位。
z-index 为什么有时候写了没效果?
1、元素没有定位:z-index要在定位后的元素上更容易生效
2、不在一个层叠的上下文中
3、元素被别的层叠规则限制
两个嵌套元素都设置了 position: absolute,子元素的 top 是相对谁算的?
是最接近的做过定位的祖先元素,如果父元素设置了 position: absolute,那么子元素的 top 就是相对于父元素计算的。
元素脱离文档流有哪些方式?
通过position属性,设置为fixed、absolute。
通过float属性脱离文档流。
什么是文档流?
文档流:元素本来应该在页面里占的位置和排列规则。
什么是脱离文档流?
这个元素不再按照原来的排队规则占位置了。
脱离文档流会导致什么?
脱离文档流会导致元素不占位置了,可能会导致一些重叠或者父元素高度塌陷等问题。
四、BFC、浮动、margin 塌陷
什么是 BFC?
中文是块格式化上下文。
可以用来做组件,BFC中的块级元素排版要在其内部进行解决,不要影响外部。可以理解为页面中的一个独立布局容器,容器内部的块级元素布局规则与外部相互隔离。
BFC 有什么作用?
1、清除浮动 如果父元素的内部子元素是浮动的,父元素可能撑不开。通过设置BFC可以让父元素正常撑开
2、防止margin塌陷 父子之间、兄弟之间的垂直外边距折叠问题,BFC 常能隔离掉。
3、防止元素被浮动的元素覆盖,实现布局隔离。
哪些方式可以触发 BFC?
1、设置overflow:hidden、auto、scroll
2、position:absolute、fixed
3、float: left/right
4、display: inline-block
5、display: flow-root
什么是 margin 塌陷(外边距折叠)?
存在父子元素之间的margin塌陷一般是,为子元素设置margin-top之后,本来想着是子元素和父元素之间产生外边距,结果发现是连着父元素一起和再外层的元素之间产生了边距,这就是子元素“顶穿”了父元素。
存在于兄弟元素之间的margin塌陷就是,为A元素设置margin为x,为B元素设置margin为y之后,本以为两者之间的距离应该是x+它,但是实际上是取大值。
margin 塌陷一般出现在哪些场景?
一般出现在没有为元素做块格式化上下文的场景。
怎么解决?
为元素做块格式化上下文,将其块环境与周边做隔离。
什么是浮动?
让元素脱离普通文档流,吸附在父元素周围指定位置
浮动会带来什么问题?
会带来周围的元素环绕在周边,可能会导致父元素高度塌陷等问题。
清除浮动有哪些方法?
为父元素建立块格式化上下文。
1、可以父元素::after{//在最下面添加一个伪元素
content: “”;//空元素
display: block;//声明为块级元素,能撑开父元素
clear: both;//清除浮动
}
2、设置 overflow: hidden/auto
为什么父元素不给高度时,子元素浮动后父元素可能塌陷?
因为父元素是由子元素撑开的,当子元素浮动元素脱离了文档流,父元素无法感知到它的高度,所以父元素的高度为0,导致塌陷。
五、Flex 布局
什么是 Flex 布局?
Flex是弹性布局,它主要用于处理平面布局,处理元素在主轴方向上的排列、对齐、分配剩余空间,以及水平垂直居中等问题。
它适合解决什么问题?
适合解决一维布局问题,主要是处理元素在主轴方向上的排列、对齐、分配剩余空间,以及水平垂直居中等问题。
Flex 容器和 Flex 项目分别是什么?
当一个元素写了属性: display:”flex”,那他就是一个Flex容器,其中别的子元素就是Flex项目。
主轴和交叉轴是什么?
主轴的方向是由flex-direction指定的,默认情况下为row,可以设置为column。
即主轴方向是Flex元素中项目的默认排列方向,默认是水平排列。
交叉轴是和主轴垂直的方向的轴。
flex-direction、justify-content、align-items 分别控制什么?
flex-direction控制主轴的方向。row、column、row-reverse、column-reverse。
justify-content控制元素在主轴上的排列方式。flex-start、center、flex-end、space-between、space-around、space-evenly。
align-items控制元素在交叉轴上的排列方式。flex-start、center、flex-end、stretch、baseline
flex-wrap、align-content 分别在什么场景下生效?
flex-warp:决定是否换行,当文字超过content预设width的时候生效。nowarp,wrap,wrap-reverse
align-content:当有多行时,控制行与行之间的对齐方式。flex-start、center、flex-end、stretch、space-between、space-around、space-evenly
flex-grow、flex-shrink、flex-basis 分别是什么意思?
flex-grow:定义有剩余的空间时候,项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
flex-shrink:定义空间不足时,项目的缩小比例,默认为1,即如果空间不足,项目将缩小。
flex-basis:定义在分配多余空间之前,项目占据的主轴空间。默认值为auto,即项目的本来大小。
flex: 1 到底等价于什么?
flex-grow:1
flex-shrink:1
flex-basis:0%
为什么 Flex 子项里经常要写 min-width: 0?
因为当子项中有内容的时候,浏览器的默认行为是展示所有内容,而我们告知浏览器,这个子项的min-width: 0,浏览器就被允许它在 Flex 布局中继续收缩,常用于文本省略场景。。
align-items 和 align-content 的区别是什么?
align-items 是控制单行的交叉轴对齐方式,而 align-content 是控制多行之间的对齐方式。
六、布局与居中
水平居中有哪些实现方式?
1、text-align:center : 行内元素水平居中
2、margin: 0 auto : 块级元素(有宽度)水平居中
3、flex布局默认轴 justify-content:center : flex布局水平居中
4、父元素position 子元素:position: absolute; left:50%;transform:translateX(-50%);
垂直居中有哪些实现方式?
1、{height:60px; line-height:60px;} : 行内元素垂直居中
2、{display:flex; align-items:center} : flex布局交叉轴居中
3、父元素position 子元素:position: absolute; top:50%; transform:translateY(-50%);
水平垂直居中有哪些实现方式?
1、{display:flex; justify-content:center; align-items:center} : flex布局水平垂直居中
2、父元素position 子元素:position: absolute; top:50%; left:50%; transform:translate(-50%,-50%);
3、{text-align:center;height:60px; line-height:60px; } 行内元素水平垂直居中
4、Grid布局 {display:grid; place-items: center;}
三栏布局有哪些实现方式?
1、浮动元素,float:left; float:right; 中间元素设置margin: 0 auto;
2、flex布局 {display:flex} .left{width:200px} .flexbox{flex:1} .right{width:130px}
3、圣杯布局 / 双飞翼布局
左侧固定、右侧自适应布局有哪些实现方式?
1、flex
2、Grid布局
{
display: grid;
gird-template-column:repeat(auto-fit, minmax(200px, 1fr));
}
如何实现图片在容器中的居中显示?
1、父元素设置为flex布局,然后再使用justify-content和align-items调整它的居中。
2、单行对象也可以通过text-align和line-hight来完成居中
七、隐藏、溢出、省略号
**隐藏一个元素有哪些方式? **
1、display: none
2、visibility: hidden
3、opacity: 0
4、position属性把元素移出视口
5、transform属性把元素消掉
display: none、visibility: hidden、opacity: 0 的区别是什么?
1、display: none是把盒子都直接去掉
2、visibility: hidden是把元素隐藏了,但是元素仍然占位
3、opacity: 0 是把元素的透明度设置为0,元素不可见,但仍然占位并且可点击。
overflow 有哪些常见取值?
hidden、auto、scroll、visible
分别有什么作用?
1、hidden:内容被修剪,并且其余内容不可见。
2、auto:如果内容溢出元素框,则添加滚动条。
3、scroll:无论内容是否溢出元素框,都添加滚动条。
4、visible:默认值,内容不会被修剪,会呈现在元素框之外。
单行文本省略号怎么实现?
{
overflow:hidden;
min-width:0;
while-space:nowarp;
text-overflow:ellipsis;
}
多行文本省略号怎么实现?
{
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:3;
overflow:hidden;
}
元素“消失”但仍占位、可点击、不可点击,这几种情况怎么区分?
1、消失后占位:visibility:hidden 不可点击
2、消失后占位且可点击:opacity:0
3、消失后不占位 display:none
八、响应式与单位
常见的响应式布局方案有哪些?
1、媒体查询:通过@media设置不同的断点,在不同的屏幕尺寸下应用不同的样式。
2、弹性布局:通过flex布局的特性,让元素根据屏幕尺寸自动调整大小和位置。
3、百分比布局:使用百分比单位设置元素的宽度和高度,使其相对于父元素进行调整。
4、grid布局,通过auto-fit配合repeat函数使用
媒体查询 @media 怎么用?
@media() 括号中填入条件,例如min-width或者max-width,意思是当当前视口宽度大于等于min-width生效,或者小于等于max-width生效
常见断点如何理解?
常见断点是根据不同设备的屏幕尺寸来划分的,例如:
- 小屏设备(手机):max-width: 767px
- 大屏设备(桌面):min-width: 1024px
- 也可以根据内容的适应性来设置断点,例如当某个组件在某个宽度下开始变形了,可以设置一个断点来调整它的样式。
px、em、rem、vw、vh 的区别是什么?
px是像素单位
em是相对当前容器或者父元素的字体大小的单位,如果当前容器font:16px,别的设置为2em,那么这个尺寸就是32px。存在继承问题
rem是相对根元素的字体大小单位。主要注意的是如果我们更改根元素的大小,是可以继承给后面的元素的,之后是按照这个新的字体大小进行计算。如果在子元素中设置回px会以px单位为准。
vw是相对于视口宽度的单位,1vw等于视口宽度的1%。
vh是相对于视口高度的单位,1vh等于视口高度的1%。
em 和 rem 的区别是什么?
em是相对自身的容器中字体的大小的单位,rem是相对根元素如html的字体大小的单位。
移动端适配为什么常用 rem 或 vw?
因为移动端的手机屏幕大小不一,使用rem和vm比较好控制元素大小和布局适配各个型号手机
meta viewport 在移动端适配里起什么作用?
头信息里的, 告诉浏览器:页面宽度按设备宽度来,初始缩放比例为 1。
不写的话,浏览器会按一个更大的虚拟布局宽度进行渲染,导致页面像一个桌面网页用小视口设备去看
九、动画、过渡、图形
transition 和 animation 的区别是什么?
transition是从一个状态变换到另外一个状态,中间自动补过程。必须要有一个触发条件,只管两点之间的变化
animation是一个完整的动画过程,可以有多个关键帧,定义了从开始到结束的整个动画过程。可以设置动画的持续时间、延迟、重复次数等属性。
transition 的常用子属性有哪些?
属性、触发时长、速度曲线、延迟
animation 的常用子属性有哪些?
动画名称、持续时间、速度曲线、延迟、重复次数、动画方向、动画填充模式等。
@keyframes 是干什么的?
用于定义动画的“过程”,里面定义了各个关键帧
为什么 hover 动效用 transform(面试重点)
因为 transform 不会触发重排和重绘,性能更好。相比直接修改 width/height/top/left等属性,transform 只会触发合成层的变化,不会引起布局和绘制的重新计算,因此在动画效果上更流畅。
animation-fill-mode 有哪些常见取值?分别是什么意思?
animation-fill-mode用于控制动画结束后停在哪些状态。常见取值有:
1、none:默认值,动画结束后元素会回到动画开始前的状态。
2、forwards:动画结束后元素会停在动画结束时的状态。
3、backwards:动画开始前元素会停在动画开始时的状态。
4、both:动画开始前元素会停在动画开始时的状态,动画结束后元素会停在动画结束时的状态。
animation-timing-function 常见值有哪些?
animation-timing-function用于控制动画的速度曲线,常见值有:
1、linear:匀速动画,动画的速度保持不变。
2、ease:默认值,动画的速度先慢后快再慢。
3、ease-in:动画的速度逐渐加快。
4、ease-out:动画的速度逐渐减慢。
5、ease-in-out:动画的速度先逐渐加快再逐渐减慢。
为什么 hover 动效常用 transform,而不是直接改 width / height / top / left?
transform不会触发重排和重绘,性能优秀。并且transform是合成层的变化,只会在视觉上产生动画,而不是真的影响页面布局
如何用 CSS 画一个三角形?
当一个盒子的宽高都是零,却给border设置宽度,并透明化,再为上下左右任何一个位置的border设置颜色,就会产生朝向这个方向的三角形
如何画一条 0.5px 的线?
使用transform和scale进行缩放
border + 缩放
十、性能与工程化意识
什么是重排(reflow)和重绘(repaint)?
重排是指当元素的几何属性发生改变时,浏览器需要重新计算元素的位置和大小等信息的过程。盒子尺寸变化就需要重排。
重绘是指当元素的外观属性发生改变时,浏览器需要重新绘制元素的过程。颜色背景这种属性就可以重绘。
重排和重绘的区别是什么?
重排需要动整体的渲染布局,重新进行计算,代价更大,性能开销更多
重绘只需要重新绘制元素,不需要重新计算布局,性能开销较小。
重排一定会重绘,但是重绘不一定重排。
哪些操作容易触发重排?
放缩,移动position,改变元素的尺寸,添加或删除元素,改变字体大小等都会触发重排。
如何减少重排和重绘?
使用transform和opacity属性,它只会在触发的时候在合成层满足视觉改变
减少对DOM的频繁操作,合并修改之后批量处理
避免读写交替,一边改样式一边读取元素
离线修改后再回流
减少复杂的选择器和嵌套操作
link 和 @import 的区别是什么?
link是HTML标签引入CSS文件,@import是CSS语法引入CSS文件。
link是页面加载的时候的并行请求,@import要等当前 CSS 解析到它时再处理,加载更晚
为什么有时要做 CSS 初始化(reset / normalize)?
不同浏览器对默认样式的处理不一样,可能会导致页面在不同浏览器上显示不一致。通过 CSS 初始化,可以统一不同浏览器的默认样式,确保页面在各个浏览器上有一致的外观和行为。
CSS3 常见新特性有哪些
1、Flex布局
2、Grid布局
3、媒体查询
4、动画和过渡