面试题整理(一): HTML + CSS 题目
1. 问题:什么是重绘,什么是回流?如何减少回流?
重绘(Repaint):
重绘是指当元素样式发生改变,但不影响其布局的情况下,浏览器重新绘制元素的过程。例如,修改元素的背景颜色、字体颜色等。
回流(Reflow):
回流是指当元素的布局属性发生改变,需要重新计算元素在页面中的布局位置时,浏览器重新进行布局的过程。例如,修改元素的宽度、高度、位置等。
回流的成本比重绘高得多,因为它涉及重新计算元素的几何属性和页面布局。而重绘只需要重新绘制已计算好的元素样式。
如何减少:
- 使用 CSS 动画代替 JavaScript 动画:CSS 动画利用 GPU 加速,在性能方面通常比 JavaScript 动画更高效。使用 CSS 的
transform
和opacity
属性来创建动画效果,而不是改变元素的布局属性,如宽度、高度等。 - 使用
translate3d
开启硬件加速:将元素的位移属性设置为translate3d(0, 0, 0)
,可以强制使用 GPU 加速。这有助于避免回流,并提高动画的流畅度。 - 避免频繁操作影响布局的样式属性:当需要对元素进行多次样式修改时,可以考虑将这些修改合并为一次操作。通过添加/移除 CSS 类来一次性改变多个样式属性,而不是逐个修改。
- 使用
requestAnimationFrame
:通过使用requestAnimationFrame
方法调度动画帧,可以确保动画在浏览器的重绘周期内执行,从而避免不必要的回流。这种方式可确保动画在最佳时间点进行渲染。 - 使用文档片段(Document Fragment):当需要向 DOM 中插入大量新元素时,可以先将这些元素添加到文档片段中,然后再将整个文档片段一次性插入到 DOM 中。这样做可以减少回流次数。(虚拟 dom vue 的方式)
- 让元素脱离文档流:position:absolute / position:fixed / float:left,(只是减少回流,不是避免回流。)
- 使用
visibility: hidden
替代display: none
:visibility: hidden
不会触发回流,因为元素仍然占据空间,只是不可见。而使用display: none
则会将元素从渲染树中移除,引起回流。
2. 问题:Margin 塌陷问题如何解决?BFC 是什么? 怎么触发?
<html>
<head>
<style type="text/css">
.box {
width: 100px;
height: 100px;
background-color: red;
}
#box1 {
margin-bottom: 200px;
}
#box2 {
margin-top: 100px;
}
</style>
</head>
<body>
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
</body>
</html>
margin塌陷问题:上面例子两个 div 的间隔为200px,取 margin 重叠部分的更大值(这是正常情况,符合 CSS 的外边距合并规则),如果希望间隔 300px,可为每个 div 触发 BFC。
BFC定义:全称叫块级格式化上下文 (Block Formatting Context),一个独立的渲染区域,有自己的渲染规则,与外部元素不会互相影响。
BFC触发方式:
设置了 float 属性(值不为 none)
设置了 position 属性为 absolute 或 fixed
设置了 display 属性为 inline-block
设置了 overflow 属性(值不为 visible)
3. 问题:如何隐藏一个元素
方式 | 占位 | 点击事件 |
---|---|---|
display: none | ❌ | ❌ |
opacity: 0 | ✅ | ✅ |
visibility: hidden | ✅ | ❌ |
clip-path: circle(0) | ✅ | ❌ |
position:absolute; top: -999px; | ❌ | ✅ |
4. 问题:overflow 不同值的区别。
属性值 | 效果 |
---|---|
visible (默认值) |
内容溢出容器时,会呈现在容器之外,不会被隐藏或截断。这意味着溢出的内容会覆盖其他元素。 |
hidden |
内容溢出容器时,会被隐藏,不可见。这意味着超出容器的部分将被截断并隐藏。 |
scroll |
如果内容溢出容器,将会显示滚动条以便查看溢出内容。用户可以滚动内容以查看被隐藏的部分。即使内容没有溢出,也会显示滚动条,但它们会被禁用。 |
auto |
与 scroll 类似,如果内容溢出容器,会显示滚动条。但与 scroll 不同的是,滚动条仅在内容溢出时才会出现,否则会被禁用。 |
inherit |
继承父元素的 overflow 值。 |
5. 问题:三栏布局的实现方式(圣杯模型)
三栏布局是一种常见的网页布局方式,通常包括一个固定宽度的左侧栏、一个固定宽度的右侧栏以及一个自适应宽度的主要内容区域。
- Flex 布局
<html>
<head>
<style type="text/css">
.container {
display: flex;
}
.left, .right {
width: 200px;
}
.main {
flex: 1; /* 自动扩展填充剩余空间 */
}
</style>
</head>
<body>
<div class="container">
<div class="left" style="border: 1px solid black;">Left Sidebar</div>
<div class="main" style="border: 1px solid black;">Main Content</div>
<div class="right" style="border: 1px solid black;">Right Sidebar</div>
</div>
</body>
</html>
- 浮动布局
<html>
<head>
<style type="text/css">
.container {
width: 100%;
}
.left {
width: 200px;
float: left;
}
.main {
margin-left: 200px; /* 宽度等于左侧栏宽度 */
margin-right: 200px; /* 宽度等于右侧栏宽度 */
}
.right {
width: 200px;
float: right;
}
</style>
</head>
<body>
<div class="container">
<div class="left" style="border: 1px solid black;">Left Sidebar</div>
<div class="right" style="border: 1px solid black;">Right Sidebar</div>
<div class="main" style="border: 1px solid black;">Main Content</div>
</div>
</body>
</html>
- Grid 布局
<html>
<head>
<style type="text/css">
.container {
display: grid;
grid-template-columns: 200px 1fr 200px; /* 列的宽度 */
}
</style>
</head>
<body>
<div class="container">
<div class="left" style="border: 1px solid black;">Left Sidebar</div>
<div class="main" style="border: 1px solid black;">Main Content</div>
<div class="right" style="border: 1px solid black;">Right Sidebar</div>
</div>
</body>
</html>
- 绝对定位布局
<html>
<head>
<style type="text/css">
.container {
position: relative;
}
.left, .right {
width: 200px;
position: absolute;
top: 0;
}
.left {
left: 0;
}
.right {
right: 0;
}
.main {
margin: 0 200px; /* 宽度等于左右侧栏宽度 */
}
</style>
</head>
<body>
<div class="container">
<div class="left" style="border: 1px solid black;">Left Sidebar</div>
<div class="main" style="border: 1px solid black;">Main Content</div>
<div class="right" style="border: 1px solid black;">Right Sidebar</div>
</div>
</body>
</html>
6. 问题:calc() 方法
calc()
是 CSS 中的一个函数,用于动态计算样式属性的值。calc()
主要用于解决以下问题:
响应式布局:calc()
可以根据不同的屏幕尺寸和视口大小,动态调整元素的尺寸或间距,以实现响应式布局。这有助于确保页面在不同设备上的显示效果良好。
动态尺寸调整:calc()
可用于根据其他元素的尺寸或动态内容的大小来计算元素的尺寸。这在构建复杂的布局时非常有用。
优化代码:calc()
可减少不必要的 CSS 代码和样式属性的硬编码,以实现更灵活、可维护和自适应的布局。
property: calc(expression);
其中 expression
是一个包含数值、运算符和单位的表达式。您可以在 calc()
中执行各种数学运算,例如加法、减法、乘法和除法。
以下是一些示例,展示了 calc()
如何用于解决不同问题:
- 自适应宽度:
.container {
width: calc(100% - 200px); /* 宽度减去200像素 */
}
- 响应式间距:
.box {
margin: calc(1rem + 5%); /* 间距基于字体大小和视口宽度 */
}
- 动态尺寸:
.dynamic {
width: calc(50% - 20px); /* 宽度减去20像素 /height: calc(2 3em); /* 高度是字体大小的3倍 */
}
7. 问题:实现 一个固定长宽div 在屏幕上垂直水平居中
<html>
<head>
<style type="text/css">
.centered-div {
width: 200px; /* 设置固定宽度 */
height: 100px; /* 设置固定高度 */
background-color: #f0f0f0;
position: absolute;
top: 50%; /* 上边距设置为屏幕高度的一半 */
left: 50%; /* 左边距设置为屏幕宽度的一半 */
transform: translate(-50%, -50%); /* 使用 transform 属性将 div 居中 */
text-align: center; /* 文本水平居中 */
line-height: 100px; /* 文本垂直居中 */
}
</style>
</head>
<body>
<div class="centered-div">
<p>This is a centered div.</p>
</div>
</body>
</html>
8. 问题:渐进增强(progressive enhancement)和优雅降级(graceful degradation)
"渐进增强"(progressive enhancement)和 "优雅降级"(graceful degradation)都是前端开发中的策略,旨在处理不同浏览器和设备的兼容性问题。有助于确保您的网站在各种环境中能够提供尽可能良好的用户体验。
渐进增强(progressive enhancement):
- 渐进增强的理念是从基本的、核心的功能开始,然后逐渐增强用户体验。
- 首先为所有用户提供基本的功能和内容,确保网站在所有浏览器和设备上都可以访问和使用。
- 随着浏览器能力的提升,逐步添加更高级和更复杂的功能和效果,以提供更富有吸引力的用户体验。
- 渐进增强强调的是从用户需求和核心功能出发,然后根据能力来增强功能和效果。
考虑一个按钮样式的示例:
/* 基本样式:无样式的按钮 */
.button {
padding: 10px 20px;
border: none;
background-color: transparent;
color: #333;
}
/* 增强样式:添加背景颜色和鼠标悬停效果 */
.button-enhanced {
background-color: #007bff;
color: #fff;
cursor: pointer;
}
/* 渐进增强:所有按钮都具有基本样式,但只有现代浏览器支持增强样式 */
在这个示例中,按钮具有基本样式,即使在不支持 CSS3 的旧浏览器中也可以正常工作。然后,在现代浏览器中,使用增强样式来提供更好的外观和交互效果。
优雅降级(graceful degradation):
优雅降级的理念是首先构建功能丰富的版本,然后在较低能力的浏览器上提供一种相对简化的版本。
先构建适用于现代浏览器的版本,包括高级功能和效果。
针对不支持这些功能的旧浏览器,提供一个更基本、但仍然可访问的版本,以确保核心功能仍然可用。
优雅降级强调的是在功能丰富的版本的基础上创建简化版本,以适应旧浏览器或不支持某些功能的情况。
考虑一个多媒体播放器的示例:
/* 高级样式:包括大型播放按钮和控件 */
.player {
/* 高级样式的 CSS 规则 */
}
/* 简化样式:隐藏高级控件,仅显示基本播放器 */
.player-simple {
/* 仅包括基本样式的 CSS 规则 */
}
/* 优雅降级:高级浏览器使用高级样式,不支持高级样式的浏览器使用简化样式 */
在这个示例中,高级浏览器使用包括大型播放按钮和更多控件的高级样式。但在不支持这些样式的浏览器中,简化样式将隐藏高级控件,仅显示基本的播放器控件。
9. 问题:iframe 有哪些优缺点及使用场景
<iframe>
(内联框架)是 HTML 中的一个标签,用于在当前页面中嵌入另一个页面。
优点:
- 分离内容:
<iframe>
允许将不同来源或不同内容的页面嵌套在一起。这有助于将内容分隔开,允许不同团队或服务提供商提供各自的内容。 - 实现跨域通信:
<iframe>
可用于实现跨域通信,例如在父页面和嵌套的<iframe>
页面之间传递数据,从而创建丰富的嵌入式应用程序。 - 安全性:
<iframe>
可以提高安全性,因为它可以将来自不受信任的来源的内容隔离在一个独立的沙盒中,以防止对主页面的恶意攻击。 - 无需刷新:
<iframe>
允许在不刷新整个页面的情况下加载新内容,这对于实现动态加载内容或应用程序非常有用。
缺点: - 性能问题:每个
<iframe>
都会加载一个新页面,这可能会导致性能问题,特别是在多个嵌套的<iframe>
页面存在时。 - 可访问性问题:
<iframe>
可能会导致可访问性问题,因为屏幕阅读器可能不会正确处理嵌套的页面。确保提供替代文本和合适的ARIA标记以提高可访问性。 - 不利于 SEO:搜索引擎通常不会索引嵌套在
<iframe>
中的内容,这可能对网站的搜索引擎优化(SEO)产生负面影响。 - 兼容性问题:某些浏览器和设备可能不正确支持
<iframe>
,或者可能需要特殊处理以确保它们正确显示。
使用场景: - 嵌入外部内容:例如,将 YouTube 视频、Google 地图或社交媒体小部件嵌入网页。
- 分离组件:将不同部分的网页分开以进行模块化开发。这对于大型应用程序或团队协作非常有用。
- 安全沙盒:将不受信任的内容隔离在一个沙盒中,以提高安全性。
- 跨域通信:在不同源的页面之间进行数据交换,以创建富客户端应用程序。
10. 问题:CSS 盒子模型
用于排列和定位网页上的元素的基本概念。它定义了每个HTML元素周围的一个矩形区域(或盒子),这个盒子包括内容、内边距、边框和外边距。CSS盒子模型有以下四个主要部分:
内容(Content):这是盒子的内部部分,包含元素的实际内容,例如文本、图像或其他媒体。内容的大小可以通过设置宽度(width
)和高度(height
)属性来控制。
内边距(Padding):内边距是内容和边框之间的空白区域。可以使用padding
属性来设置内边距的大小。内边距的大小影响了内容与盒子边界之间的距离。
边框(Border):边框位于内边距的外部,围绕着内容和内边距。边框的样式、颜色和宽度可以通过border
属性进行设置。
外边距(Margin):外边距是盒子与其相邻元素之间的空白区域。外边距的大小可以通过margin
属性来设置。外边距影响了盒子与其他元素之间的距离。
+-----------------------------+
| Margin (外边距) |
| |
| +---------------------+ |
| | Border (边框) | |
| | | |
| | Padding (内边距) | |
| | | |
| | Content (内容) | |
| | | |
| +---------------------+ |
| |
| Margin (外边距) |
| |
+-----------------------------+
11. 问题:HTML5 的特性
- 语义元素:HTML5引入了一些新的语义元素,如
<header>
、<footer>
、<nav>
、<section>
等,以更好地描述网页的结构,提高可读性和可访问性。 - 多媒体支持:HTML5提供了内置的多媒体支持,包括
<audio>
和<video>
元素,使音频和视频的嵌入更加简单,而无需使用第三方插件(如Flash)。 - Canvas:引入了
<canvas>
元素,允许通过JavaScript创建和操作图形,用于绘制图表、游戏和应用程序。 - 本地存储:HTML5引入了Web Storage和IndexedDB,允许在客户端存储数据,以提高离线应用程序的性能。
- 新表单元素:HTML5引入了新的表单元素,如
<input type="date">
、<input type=email">
、<input type="range">
等,使表单更具交互性和用户友好性。 - Web Workers:HTML5引入了Web Workers,允许在后台运行JavaScript,以提高Web应用程序的响应性,而不会阻塞用户界面。
- WebSocket:HTML5引入了WebSocket,一种用于实时通信的协议,可用于创建实时聊天和多人游戏等。
- 地理位置:HTML5允许网页访问用户的地理位置信息,以便创建地理位置相关的应用程序,如地图和位置服务。
- SVG:HTML5支持可缩放矢量图形(SVG),允许创建矢量图形和图表,以便在不同分辨率的屏幕上显示。
- 拖放:HTML5引入了拖放API,允许在网页中实现拖放操作,使用户界面更直观。
- 离线应用程序:HTML5引入了应用程序缓存,使Web应用程序能够在离线时继续工作。
- 新事件API:HTML5引入了新的事件API,如addEventListener,使事件处理更加灵活和强大。
12. 问题:CSS3 的特性
- 圆角边框:通过
border-radius
属性,可创建圆角边框,包括圆形、椭圆和自定义形状。 - 阴影和发光效果:使用
box-shadow
和text-shadow
属性,可以为元素添加阴影和发光效果。 - 渐变背景:通过
linear-gradient
和radial-gradient
属性,可以创建渐变背景,包括线性和径向渐变。 - 多列布局:通过
column-count
和column-width
等属性,可以创建多列布局,类似于报纸的排版。 - 变换:使用
transform
属性,可以对元素进行旋转、缩放、倾斜和平移等变换。 - 过渡:通过
transition
属性,可以创建元素状态之间的平滑过渡效果,例如鼠标悬停时的渐变效果。 - 动画:使用
@keyframes
规则和animation
属性,可创建CSS动画,使元素可实现复杂的运动和效果。 - 2D和3D转换:CSS3支持2D和3D转换,可以实现元素在平面和三维空间的旋转、缩放和倾斜。
- 字体嵌入:通过
@font-face
规则,可以在网页上嵌入自定义字体,以提供更多的字体选择。 - 透明度:使用
opacity
属性,可以控制元素的透明度,使元素可以半透明或完全不透明。 - 栅格布局:通过
display: grid
属性,可以创建更复杂的网格布局,用于定位和对齐元素。 - 自定义属性:使用CSS变量(
var()
)来定义和重用自定义属性,以简化样式表的管理。 - 用户界面控件:CSS3引入了样式化的用户界面控件,如滚动条、复选框和单选框的自定义样式。
- 响应式设计:通过媒体查询和弹性布局,CSS3支持响应式设计,以适应不同的屏幕尺寸和设备。
13. 问题:CSS 中选择器的优先级,权重计算方式
- !important规则: 如果有
!important
声明,那么该规则具有最高的优先级。 - 特定性: 特定性值的大小来排序,特定性值较大的规则具有更高的优先级,权重计算方式如下:
- 内联样式:每个内联样式规则的特定性为1000。
- ID选择器:每个ID选择器的特定性为100。
- 类选择器、属性选择器和伪类选择器:每个类选择器、属性选择器和伪类选择器的特定性为10。
- 元素选择器和伪元素选择器:每个元素选择器和伪元素选择器的特定性为1。
案例: #header
:特定性值为100(1个ID选择器)。.menu-item
:特定性值为10(1个类选择器)。ul li
:特定性值为2(2个元素选择器)。
- 覆盖规则: 如果两个规则具有相同的特定性,后面定义的规则将覆盖先前定义的规则,因此后定义的规则具有更高的优先级。
14. 问题:HTML5 input 元素 type 属性
- text:用于接受单行文本输入。
- password:用于密码输入,输入的字符会被掩盖。
- radio:用于单选按钮,用户可以在一组选项中选择一个。
- checkbox:用于复选框,用户可以选择多个选项。
- number:用于输入数字,可以包括上下箭头来增减数值。
- range:用于输入范围,例如滑动条。
- date:用于日期输入。
- time:用于时间输入。
- file:用于文件上传。
- color:用于颜色选择器。
- hidden:用于存储数据,但不会在页面中显示。
- submit:用于提交表单。
- reset:用于重置表单。
- button:用于创建自定义按钮。
15. 问题:CSS 中属性的继承性
可继承的属性(Inherited Properties):
color
:控制文本颜色。font
:包括font-family、font-size、font-style、font-weight等属性。line-height
:控制行高。text-align
:控制文本对齐方式。text-indent
:控制首行缩进。text-transform
:控制文本转换为大写、小写或首字母大写。visibility
:控制元素的可见性。
不可继承的属性(Non-inherited Properties):
border
:包括border-width
、border-style
、border-colo
r等属性。margin
:包括margin-top
、margin-right
、margin-bottom
、margin-left
。padding
:包括padding-top
、padding-right
、padding-bottom
、padding-left
。background
:包括background-color
、background-image
、background-repeat
等属性。width
:控制元素的宽度。height
:控制元素的高度。position
:控制元素的定位方式(例如,relative
、absolute
、fixed
)。top
、right
、bottom
、left
:控制元素的位置。display
:控制元素的显示方式(例如,block
、inline
、none
)。float
:控制元素的浮动方式。
16. 问题:画一条 0.5px 的线
<html>
<head>
<style type="text/css">
.thin-line {
height: 1px; /* 设置线的高度为1像素 */
background: #000; /* 设置线的颜色 */
transform: scaleY(0.5); /* 使用scale缩放高度为0.5,模拟较细的线 */
transform-origin: 0 0; /* 设置变换的原点为左上角,确保线的位置正确 */
margin: 0; /* 可以根据需要调整上下外边距,以控制线的位置 */
}
</style>
</head>
<body>
<div class="thin-line"></div>
</body>
</html>
17. 问题:position 的值
- static(静态定位):
- 默认值。
- 元素按照文档流正常排列,不受其他定位属性影响。
top
、right
、bottom
、left
属性不起作用。
- relative(相对定位):
- 元素相对于其正常位置定位。
- 可以使用
top
、right
、bottom
、left
属性来调整元素的位置。 - 相对定位不会脱离文档流,其他元素仍然占据原来的位置。
- absolute(绝对定位):
- 元素相对于最近的已定位祖先元素定位,如果没有已定位的祖先元素,则相对于初始包含块(通常是浏览器窗口)定位。
- 使用
top
、right
、bottom
、left
属性来精确控制位置。 - 绝对定位会脱离文档流,不再占据原来的位置。
- fixed(固定定位):
- 元素相对于视口定位,不随页面滚动而移动。
- 使用
top
、right
、bottom
、left
属性来控制位置。 - 固定定位脱离文档流,不占据原来的位置。
- sticky(粘性定位):
- 元素在跨越特定阈值前表现为相对定位,之后表现为固定定位。
- 通常用于创建“粘性”导航栏或侧边栏。
- 使用
top
、right
、bottom
、left
属性来控制位置。