# CSS&HTML精选面试题
# 元素水平垂直居中的方式
# 居中为什么尽量使⽤ transform(为什么不使⽤marginLeft/Top)**
在居中元素时,使用 transform
的主要原因是它可以提供更好的性能和更灵活的布局控制,相比于使用 marginLeft
和 marginTop
。
以下是使用 transform
进行居中的几个优势:
- 性能优化:
transform
属性可以触发 GPU 加速,这意味着浏览器可以使用硬件加速来处理元素的渲染,从而提高性能。相比之下,使用marginLeft
和marginTop
进行居中可能会导致页面的重排和重绘,性能较差。 - 灵活的布局控制:
transform
属性可以与其他布局属性(如position
、display
等)结合使用,提供更灵活的布局控制。例如,可以将元素设置为绝对定位(position: absolute
)并使用transform
属性进行居中,这样可以在不影响其他布局的情况下实现居中效果。 - 元素尺寸不影响布局:使用
transform
进行居中时,元素的尺寸不会影响其在布局中的位置。这意味着可以轻松地调整元素的大小而不会破坏居中效果。相比之下,使用marginLeft
和marginTop
进行居中时,元素的尺寸会影响其在布局中的位置,可能需要进行额外的计算和调整。
# CSS3 动画的实现方式有哪些,动手写一下将一个 div 在 1s 内移动 300px?
css3 实现动画主要有 3 种方式
- transition 过渡动画
- transform 2D 和 3D 转换
- animation 自定义动画
/* transition属性动画结合transform变化属性,实现元素移动一段距离的动画 */
#transitonDiv:hover {
transition: all 1s ease-in-out;
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transform: translateX(300px);
-ms-transform: translateX(300px);
-moz-transform: translateX(300px);
-webkit-transform: translateX(300px);
-o-transform: translateX(300px);
}
/* 通过animation属性,实现逐帧动画 */
#animationDiv:hover {
animation: animName 1s ease-in-out;
-webkit-animation: animName 1s ease-in-out;
-moz-animation: animName 1s ease-in-out;
-o-animation: animName 1s ease-in-out;
}
/* 定义关键帧 */
@keyframes animName {
0% {
transform: translateX(0px);
}
30% {
transform: translateX(100px);
}
60% {
transform: translateX(200px);
}
100% {
transform: translateX(300px);
}
}
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
33
34
35
36
37
此外还可以 window.requestAnimationFrame() 实现:
const element = document.getElementById('e');
let start;
function render(timestamp) {
if (start === undefined) {
start = timestamp;
}
const elapsed = timestamp - start;
//这里使用`Math.min()`确保元素刚好停在300px的位置。
element.style.transform = 'translateX(' + Math.min(0.3 * elapsed, 300) + 'px)';
console.log(element.style.transform)
if (elapsed < 1000) { // 在1秒后停止动画
window.requestAnimationFrame(render);
}
}
window.requestAnimationFrame(render);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 所有 css3 的动画都能用 GPU 加速么?
在 css 中,只有 3D 转换、opacity 透明、filter 滤镜和添加了 will-change 属性的元素,浏览器才会开启硬件(GPU)加速。
不过如果我们想要 2D、过渡等动画也能开启硬件加速,我们可以通过给这些元素加上transform: translateZ(0); 或transform: translate3d(0,0,0);来诱导浏览器开启硬件加速,但是我们不能滥用。
也可能通过添加 will-change 来实现。
为什么需要 GPU 硬件加速?
- CSS3 动画在移动多终端设备场景下,相⽐ PC 会⾯对更多的性能问题,主要体现在动画的卡顿与闪烁。
- 我们可以通过 GPU 硬件加速来解决这个问题
CPU 、GPU、硬件加速的关系?
- 硬件加速意味着图形处理单元(GPU)会协助你的浏览器渲染网页,做一些繁重的工作,而不是把这些工作全部丢给中央处理单元(CPU)来完成。
- 当一个 CSS 操作被硬件加速时,它的速度也会因为页面的渲染速度变快而得到提升。
CPU 和 GPU 都是处理单元
- CPU 位于计算机的主板上,它被称为计算机的大脑。GPU 位于计算机的显卡上,负责处理和渲染图像
- 此外,GPU 是专门为执行复杂的数学和几何计算而设计的,这些计算也是图形渲染的必要条件 -因此,将操作丢给 GPU 处理可以产生巨大的性能提升,也可以减少移动设备上的 CPU 争用。
硬件加速(又称 GPU 加速)
- 依赖于浏览器渲染页面时使用的分层模型。
- 当对页面上的元素进行某些操作(比如 3D 变换)时,该元素会被移动到属于它自己的“图层”,在那里它可以独立于页面的其他部分进行渲染,并在之后被合成(画到屏幕上)。
- 这样就隔离了内容的渲染,如果该元素的变换是帧之间唯一的变化,那么页面的其他部分就不必重新渲染,这样往往能够提供明显的速度优势。
- 不过这里需要说明一下:只有 3D 变换拥有属于自己的图层,2D 变换没有。
CSS 的 animation、transform 和 transition 不会自动进行 GPU 加速,一般是由浏览器缓慢的软件渲染引擎执行。 然而有些浏览器通过某些属性提供硬件加速,以获得更好的渲染性能。
开启 GPU 硬件加速可能触发的问题
硬件加速操作会创建一个所谓的合成渲染层(compositor layer),并上传到 GPU 进行合成。
然而,强行创造一个图层并不能解决某些页面上的性能瓶颈。
- 虽然图层创建技术可以提升页面速度,但有一定代价:它们会占用系统 RAM 和 GPU 上的内存(在移动设备上很有限),而且拥有大量的图层会产生不好的影响(尤其是在移动设备上)
- 所以必须明智地使用它们,确保其可以真正帮助页面性能,而且性能瓶颈不是由你页面上的其他操作造成的。
经过-webkit-transform: transition3d/translateZ 开启 GPU 硬件加速以后,有些时候可能会致使浏览器频繁闪烁或抖动,能够尝试如下办法解决之:
-webkit-backface-visibility: hidden; /* 各种前缀都要考虑,此处省略 */
-webkit-perspective: 1000; /* 各种前缀都要考虑,此处省略 */
2
# 如何画一个三角形
<style>
.triangle {
width: 0;
border: 50px solid transparent; /*边框颜色为透明*/
border-left-color: 50px solid blue; /*左三角形*/
}
</style>
<body>
<div class="triangle"></div>
</body>
2
3
4
5
6
7
8
9
10
# css选择器分类
基本的: 1.id选择器(id="name") 2.类选择器(class="head") 3.标签选择器(body, div, ul, li) 4.全局选择器(*) 复杂的: 1.组合选择器(.head .head_logo) 2.后代选择器 (#head .nav ul li 从父集到子孙集) 3.群组选择器 (div, span, img {color:Red} 具有相同样式的标签分组显示) 4.继承选择器 5.伪类选择器(链接样式,a元素的伪类) 6.子选择器(div>p, 带大于号>) 7.CSS相邻相邻兄弟选择器(h1+p, 带加号+)
# 使元素消失的方法有哪些?
- 1.opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
- 2.visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
- 3.display:none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉
- 4.z-index=-999,让元素低于页面基本元素的层级
- 5.设置 posoition 为 absolute 或 fixed,通过设置 top、left 等值,将其移出可视区域。
- 6.利用 transfrom:
transform: scale(0);``transform: translateX(-99999px);
- 7.设置大小为0:
height: 0;width: 0;font-size:0;overflow: hidden;
- 8.clip-path 裁剪
- 9.aria-hidden 属性,读屏软件不可读,占据空间,可见。
- hidden 属性,HTML5 新增属性,相当于 display: none;
<div hidden></div>
# 如何开启GPU加速
translateZ() 或者 translate3d()
<video>
和<canvas>
标签CSS filters
will-change
元素覆盖时,比如使用了 z-index 属性
优点:使用 transform、opacity、filters、will-change 等属性时,会直接在 GPU 中完成处理,这些属性的变化不会引起回流重绘
缺点:GPU 渲染字体会导致字体模糊,过多的 GPU 处理会导致内存问题
# 请使用 html + css 实现以下效果,且不管浏览器如果缩放,始终保持下图在浏览器水平和垂直方向的中间(十字架需css绘制)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>align</title>
<style type="text/css">
.container{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100%;
width: 100%;
background-color: #ccc;
}
.top{
width: 30px;
height: 50px;
background-color: #fff;
border: 2px solid blue;
border-bottom: 0;
}
.middle{
display: flex;
background-color: #fff;
}
.left, .right{
width: 50px;
height: 30px;
background-color: #fff;
}
.left{
border: 2px solid blue;
border-right: 0;
margin-right: 15px;
}
.right{
border: 2px solid blue;
border-left: 0;
margin-left: 15px;
}
.bottom{
width: 30px;
height: 50px;
background-color: #fff;
border: 2px solid blue;
border-top: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="top"></div>
<div class="middle">
<div class="left"></div>
<div class="right"></div>
</div>
<div class="bottom"></div>
</div>
</body>
</html>
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 说说CSS选择器以及这些选择器的优先级
- !important
- 内联样式(1000)
- ID选择器(0100)
- 类选择器/属性选择器/伪类选择器(0010)
- 元素选择器/伪元素选择器(0001)
- 关系选择器/通配符选择器(0000)
# 盒模型
标准模型和IE模型的区别:
IE盒模型和标准盒模型的总宽度都是由四个部分组成的:margin,border,padding,content
IE 模型包含了content、padding 和 border 的值,而标准盒模型的宽度只有内容 content 部分,是独立的。
box-sizing
box-sizing 属性可以为三个值之一:content-box(default),border-box,padding-box:
content-box,border和padding不计算入width之内
padding-box,padding计算入width内
border-box,border和padding计算入width之内,其实就是怪异模式了
# 你知道什么是BFC么
BFC 全称为块级格式化上下文 (Block Formatting Context) ,可以说BFC就是一个作用范围,把它理解成是一个独立的容器,并且这个容器里box的布局与这个容器外的box毫不相干。
触发BFC的条件:
- 根元素或其它包含它的元素
- 浮动元素 (元素的 float 不是 none)
- 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
- 内联块 (元素具有 display: inline-block)
- 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
- 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
- 具有overflow 且值不是 visible 的块元素
- 弹性盒(flex或inline-flex)
- display: flow-root
- column-span: all
BFC的约束规则:
- 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流)
- 处于同一个BFC中的元素相互影响,可能会发生外边距重叠
- 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
- 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算
- 浮动盒区域不叠加到BFC上
BFC可以解决的问题:
- 防止 margin 重叠 (同一个BFC内的两个两个相邻Box的 margin 会发生重叠,触发生成两个BFC,即不会重叠)
- 清除内部浮动 (创建一个新的 BFC,因为根据 BFC 的规则,计算 BFC 的高度时,浮动元素也参与计算)
- 自适应多栏布局,避免某元素被浮动元素覆盖 (BFC的区域不会与float box重叠。因此,可以触发生成一个新的BFC)
# 你对 Flex 布局的了解
容器属性(使用在flex布局容器上的属性)
- justify-content 定义了子元素在主轴(横轴)上的对齐方式
.container {
justify-content: center | flex-start | flex-end | space-between | space-around;
/* 主轴对齐方式:居中 | 左对齐(默认值) | 右对齐 | 两端对齐(子元素间边距相等) | 周围对齐(每个子元素两侧margin相等) */
}
2
3
4
- align-items 定义了定义项目在交叉轴(竖轴)上对齐方式
.container {
align-items: center | flex-start | flex-end | baseline | stretch;
/* 侧轴对齐方式:居中 | 上对齐 | 下对齐 | 项目的第一行文字的基线对齐 | 如果子元素未设置高度,将占满整个容器的高度(默认值) */
}
2
3
4
- align-content 定义多根轴线的对齐方式
.container {
align-content: center | flex-start | flex-end | space-between | space-around | stretch;
/* 默认值:与交叉轴的中点对齐 | 与交叉轴的起点对齐 | 与交叉轴的终点对齐 | 与交叉轴两端对齐 | 每根轴线两侧的间隔都相等 | (默认值):轴线占满整个交叉轴 */
}
2
3
4
- flex-direction 主轴(横轴)方向
.container {
flex-direction: row | row-reverse | column | column-reverse;
/* 主轴方向:水平由左至右排列(默认值) | 水平由右向左 | 垂直由上至下 | 垂直由下至上 */
}
2
3
4
- flex-wrap 换行方式
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
/* 换行方式:不换行(默认值) | 换行 | 反向换行 */
}
2
3
4
- flex-flow flex-flow属性是flex-direction属性和flex-wrap的简写
.container {
flex-flow: <flex-direction> || <flex-wrap>;
/* 默认值:row nowrap */
}
2
3
4
项目属性(使用在容器内子元素上的属性)
- flex-grow 定义项目的放大比例,默认为0,即使有剩余空间也不放大
如果所有子元素flex-grow为1,那么将等分剩余空间,如果某个子元素flex-grow为2,那么这个子元素将占据2倍的剩余空间
.item {
flex-grow: <number>; /* default 0 */
}
2
3
- flex-shrink 定义项目的缩小比例,默认为1,即如果空间不足,子元素将缩小。
如果所有子元素flex-shrink都为1,某个子元素flex-shrink为0,那么该子元素将不缩小
.item {
flex-shrink: <number>; /* default 1 */
}
2
3
- flex-basis 定义在分配多余空间之前,项目占据的主轴空间
默认auto,即子元素本来的大小,如果设定为一个固定的值,那么子元素将占据固定空间
.item {
flex-basis: <length> | auto; /* default auto */
}
2
3
- flex flex属性是flex-grow, flex-shrink 和 flex-basis的简写
默认值为0 1 auto,即有剩余空间不放大,剩余空间不够将缩小,子元素占据自身大小
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
2
3
flex有两个快捷值:auto和none,分别代表1 1 auto(有剩余空间则平均分配,空间不够将等比缩小,子元素占据空间等于自身大小)和0 0 auto(有剩余空间也不分配,空间不够也不缩小,子元素占据空间等于自身大小)
- order 定义项目的排列顺序。数值越小,排列越靠前,默认为0
.item {
order: <integer>;
}
2
3
- align-self 定义单个子元素的排列方式
例如align-items设置了center,使得所有子元素居中对齐,那么可以通过给某个子元素设置align-self来单独设置子元素的排序方式
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
2
3
参考资料: 阮一峰Flex布局 (opens new window)
# 清楚浮动的方法有哪些?
- 使用额外的空元素清除浮动:
在浮动元素的父元素的末尾添加一个空的块级元素,并为其设置样式 clear: both;
。这会使父元素自动适应浮动元素的高度。
<div class="parent">
<div class="float-left"></div>
<div class="float-left"></div>
<div style="clear: both;"></div>
</div>
2
3
4
5
6
这种方法简单易用,但需要添加额外的 HTML 元素。
- 使用伪元素清除浮动:
使用伪元素 ::after
在浮动元素的父元素中插入一个空的块级元素,并为其设置样式 clear: both;
。
.parent::after {
content: "";
display: table;
clear: both;
}
2
3
4
5
6
这种方法不需要添加额外的 HTML 元素,但需要在 CSS 中定义伪元素的样式。
- 使用 clearfix 类清除浮动:
定义一个 .clearfix
类,并为其设置样式 overflow: auto;
或 overflow: hidden;
。然后将该类应用于浮动元素的父元素。
.clearfix::after {
content: "";
display: table;
clear: both;
}
.clearfix {
overflow: auto;
}
2
3
4
5
6
7
8
9
10
在父元素中添加 .clearfix
类,可以清除浮动并保持父元素的高度正常。
- 使用 CSS 弹性布局(Flexbox):
将父元素设置为 display: flex;
,这样子元素将自动成为弹性项目,并根据需要进行自动伸缩。
.parent {
display: flex;
}
2
3
4
使用 Flexbox 布局可以更方便地管理浮动元素,并自动解决高度塌陷的问题。
# 说说你对 HTML 语义化的理解 ?
HTML 语义化是指我们在写 HTML 结构时用有英文语义的标签,使 HTML 更易于开发人员和机器的阅读和理解。
非语义元素的例子:
语义元素示例: