CSS篇-6
1. 如果将<html>
元素的font-size
设置为10rem
,那么当用户调整或拖曳浏览器窗口时,其文本大小会受到影响吗?
不会受到影响。rem
单位是相对于根元素(即<html>
元素)的font-size
计算的。一旦<html>
的font-size
被明确设置为10rem
,这个值就固定下来了。除非<html>
本身的font-size
定义受到媒体查询(media query)等影响而改变,否则其内部元素(如果使用rem
作为单位)的大小会基于这个固定的10rem
进行计算,而不会直接随着浏览器窗口大小的变化而改变。如果希望文本随窗口大小变化,可以使用vw
或vh
等视口相关单位,或者通过媒体查询动态调整<html>
的font-size
。
2. 请谈谈你对BFC(块级格式化上下文)规范的理解。
BFC,全称是 Block Formatting Context,即“块级格式化上下文”。它是CSS可视化渲染的一部分,是一个独立的渲染区域,在这个区域内部,块级盒子的布局方式是独立的,并且不会影响到区域外部的元素。
理解BFC有几个核心要点:
-
独立性: BFC内部的布局与外部完全隔离,BFC内部的元素不会影响到外部,反之亦然。
-
边界折叠: 在同一个BFC中,相邻的块级元素的垂直外边距(margin)会发生折叠(margin collapse)。而不同BFC之间的外边距不会折叠。
-
包含浮动: BFC可以包含浮动元素。当一个父元素创建了BFC,它会自动包含其内部的浮动子元素,从而避免父元素高度塌陷的问题。
-
清除浮动: BFC的一个常见应用就是用来清除浮动,通过触发BFC来使父元素包裹浮动子元素。
创建BFC的常见条件包括:
-
<html>
根元素。 -
float
的值不是none
。 -
position
的值为absolute
或fixed
。 -
display
的值为inline-block
、table-cell
、table-caption
、flex
、inline-flex
、grid
、inline-grid
。 -
overflow
的值不是visible
。
3. 你对IFC(内联格式化上下文)规范又有什么理解呢?
IFC,全称是 Inline Formatting Context,即“内联格式化上下文”。它是针对内联元素(如文本、<span>
、<a>
、<em>
等)的布局规则。
IFC的特点主要有:
-
水平排列: IFC中的内联元素会从包含块的顶部开始,一个接一个地水平排列。
-
线框(Line Box): 每个IFC会生成一系列的“线框”(Line Box),这些线框的高度由其包含的内联元素中最高的实际高度决定(注意:
vertical-align
会影响元素在行内的对齐方式,但不会直接影响线框的高度,除非元素本身撑高了线框)。 -
高度计算: 线框的高度不受竖直方向的
padding
和margin
影响,但内联元素自身的padding
和margin
会影响其自身的尺寸。 -
浮动元素扰乱: IFC中的线框通常左右贴紧整个IFC,但会被
float
元素扰乱,浮动元素会脱离文档流并占据一部分水平空间。 -
没有块级元素: IFC中不能直接包含块级元素。如果在一个内联格式化上下文的内部插入一个块级元素,那么这个块级元素会将其父元素分割成两个匿名块(匿名盒子),这两个匿名块各自形成一个IFC,并与块级元素垂直排列。换句话说,块级元素会“打断”当前的IFC。
4. 请谈谈你对GFC(网格布局格式化上下文)规范的理解。
GFC,全称是 Grid Layout Formatting Context,即“网格布局格式化上下文”。它是CSS Grid布局的核心概念。
当一个元素的display
属性值被设置为grid
或inline-grid
时,这个元素就成为了一个网格容器(Grid Container),并创建了一个新的GFC。在这个GFC内部:
-
独立的渲染区域: 网格容器会为其内容创建一个独立的渲染区域。
-
行列定义: 开发者可以在网格容器上定义网格的行(
grid-template-rows
)和列(grid-template-columns
),以及行间距(grid-row-gap
)和列间距(grid-column-gap
)等。 -
网格项目定位: 网格容器的直接子元素会成为网格项目(Grid Item)。可以通过在网格项目上设置
grid-row
、grid-column
、grid-area
等属性,来精确地定义每一个网格项目在网格中的位置和所占空间。 -
双轴控制: Grid布局提供了二维的布局控制,即可以同时控制行和列,这与Flexbox(通常是单轴)有所不同,使其非常适合构建复杂的页面布局。
简单来说,GFC定义了网格容器如何通过网格线、网格轨道和网格单元格来对其内容进行布局,以及这些网格项目如何相互作用和定位。
5. 请谈谈你对FFC(自适应格式化上下文,即Flex Formatting Context)的理解。
FFC,全称是 Flex Formatting Context,即“弹性格式化上下文”或“自适应格式化上下文”。它是CSS Flexbox布局的核心。
当一个元素的display
属性值被设置为flex
或inline-flex
时,这个元素就成为了一个弹性容器(Flex Container),并创建了一个新的FFC。
-
弹性容器与弹性单元: 弹性容器的直接子元素会成为弹性单元(Flex Item)。
-
单轴布局: Flexbox主要用于一维布局,即沿主轴或交叉轴进行布局。它提供强大的对齐、空间分配和排序能力。
-
内部独立性: FFC定义了弹性容器内弹性单元的布局方式,但弹性单元内部以及弹性容器外部的元素布局不受其影响,保持独立性。
-
动态伸缩: 弹性单元可以根据容器的可用空间进行伸缩(收缩或放大),这使得Flexbox非常适合响应式设计和组件布局。
总结来说,FFC定义了弹性容器内弹性单元如何沿主轴和交叉轴进行排列、对齐和分配空间,以实现灵活的布局。
6. 访问超链接后,hover
样式就不出现的原因是什么?应该如何解决?
这个问题通常发生在CSS伪类选择器的顺序问题上。浏览器默认或用户定义的“已访问链接”样式(a:visited
)可能会覆盖掉“鼠标悬停”样式(a:hover
)。
原因:
CSS对伪类选择器有一定的优先级,当存在冲突时,后面的规则会覆盖前面的。如果样式表中a:visited
的规则出现在a:hover
的规则之后,那么当链接被访问过时,a:visited
的样式就会生效,并且覆盖掉a:hover
的样式,导致hover
效果不出现。
解决方法:
将CSS伪类选择器的排列顺序改为L→V→H→A,即:
-
a:link
(未访问的链接) -
a:visited
(已访问的链接) -
a:hover
(鼠标悬停在链接上) -
a:active
(链接被点击时)
这个顺序可以用一个口诀来记忆:LoVe HAte(爱恨情仇)。通过这种顺序,确保hover
和active
的状态能够正确覆盖link
和visited
的状态,从而实现预期的交互效果。
7. 什么是外边距重叠(margin collapse)?重叠的结果是什么?
外边距重叠,通常称为“margin折叠”(margin-collapse),是CSS中一个特有的现象。它指的是在某些情况下,相邻的两个或多个块级盒子的垂直外边距(margin-top
和margin-bottom
)会结合成一个单独的外边距。
触发条件:
外边距折叠主要发生在以下三种情况:
-
相邻兄弟元素: 两个毗邻的兄弟元素,上面的元素的
margin-bottom
与下面元素的margin-top
发生折叠。 -
父子元素: 当父元素没有
padding
、border
,并且没有创建BFC,其margin-top
(或margin-bottom
)会与它的第一个(或最后一个)子元素的margin-top
(或margin-bottom
)发生折叠。 -
空块级元素: 一个空的块级元素,如果自身没有
border
、padding
、content
,并且没有设置height
或min-height
,那么它的margin-top
和margin-bottom
会发生折叠。
折叠结果遵循以下计算规则:
-
都是正数: 当两个相邻的外边距都是正数时,折叠的结果是它们两者中较大的值。
-
都是负数: 当两个相邻的外边距都是负数时,折叠的结果是两者中绝对值较大的值。
-
一正一负: 当两个外边距一正一负时,折叠的结果是两者相加的和。
示例:
-
元素A的
margin-bottom: 20px;
,元素B的margin-top: 30px;
,折叠后间距为30px
。 -
元素A的
margin-bottom: -10px;
,元素B的margin-top: -20px;
,折叠后间距为-20px
。 -
元素A的
margin-bottom: 20px;
,元素B的margin-top: -5px;
,折叠后间距为15px
。
8. rgba()
和opacity
的透明效果有什么不同?
rgba()
和opacity
都能实现透明效果,但它们的作用对象和继承性有本质的区别。
-
作用对象:
-
opacity
:作用于整个元素及其所有内容(包括文本、背景、边框、子元素等)。它设置的是整个元素的整体不透明度。 -
rgba()
:只作用于颜色的指定通道。通常用于设置元素的背景色、文本颜色、边框颜色等。它控制的是颜色的透明度,而不是整个元素的透明度。
-
-
继承性:
-
opacity
:具有继承性。如果父元素设置了opacity: 0.5;
,那么它的所有子元素也会继承这个透明度,并且子元素自身的透明度会在此基础上叠加(例如,子元素再设置opacity: 0.8;
,那么它相对于根元素的不透明度将是0.5 * 0.8 = 0.4
)。 -
rgba()
:不具有继承性。它只影响当前元素的颜色属性。如果父元素设置了background-color: rgba(0,0,0,0.5);
,其子元素不会继承这个背景色或其透明度,子元素会拥有自己的背景。
-
总结:
-
如果你想让整个元素及其所有内容(包括子元素)都变得透明,使用
opacity
。 -
如果你只想让元素的背景色、文字颜色或边框颜色等“颜色”部分变得透明,而不影响子元素或文字本身的清晰度,使用
rgba()
。
9. CSS中可以让文字在垂直和水平方向上重叠的两个属性是什么?
-
垂直方向:
line-height
。当line-height
的值小于font-size
时,行高会小于字体大小,导致文本行之间出现重叠。 -
水平方向:
letter-spacing
。当letter-spacing
的值为负数时,字符之间的间距会减小,甚至使字符发生重叠。
10. 关于letter-spacing
的妙用?
letter-spacing
除了调整字符间距外,它还有一个非常实用的妙用:
-
消除
inline-block
元素间的换行符空格间隙。
当多个inline-block
元素在HTML中因为换行、空格或制表符而分隔时,浏览器会将其渲染为可见的空格。这种空格会占用一定的水平空间,导致布局出现意外的间隙。
可以通过在父元素上设置font-size: 0;
(或letter-spacing: -4px;
等负值,具体数值需根据字体和浏览器调整)来消除这些间隙。然后在inline-block
子元素上重新设置正常的font-size
。
例如:<div class="parent"><div class="item">Item 1</div><div class="item">Item 2</div> </div>
.parent {font-size: 0; /* 消除间隙的关键 */ } .item {display: inline-block;font-size: 16px; /* 恢复子元素的字体大小 *//* ...其他样式 */ }
虽然
font-size: 0;
是更常见的做法,但letter-spacing
(配合word-spacing
)也能通过负值来尝试消除这种间隙,但效果可能不如font-size: 0;
稳定和彻底,因为它只影响字符间距,而font-size: 0;
直接让字体宽度为0。
11. 有几种方式可以对一个DOM元素设置它的CSS样式?
对DOM元素设置CSS样式主要有以下三种方式:
-
外链式(External Stylesheet):
-
将CSS代码写在一个独立的
.css
文件中。 -
通过
<link>
标签在HTML文档的<head>
部分引入。 -
优点: 实现了结构(HTML)与样式(CSS)分离,便于维护和管理;浏览器会缓存CSS文件,提高加载速度。
-
示例:
<link rel="stylesheet" href="styles.css">
-
-
内嵌式(Internal Stylesheet):
-
将CSS代码写在HTML文档的
<head>
部分中的<style>
标签内。 -
优点: 适用于样式仅限于当前页面或测试用;不需要额外的HTTP请求。
-
缺点: 不利于多页面共享样式;没有实现完全分离。
-
示例:
<head><style>h1 { color: blue; }</style> </head>
-
-
行内式(Inline Style):
-
将CSS代码直接写在HTML元素的
style
属性中。 -
优点: 优先级最高,直接作用于当前元素;适用于少量、特定元素的定制样式。
-
缺点: 无法实现样式复用;不利于维护(样式与结构混淆);降低可读性。
-
示例:
<p style="color: red; font-size: 18px;">这段文字是红色的</p>
-
12. 在CSS中,可以通过哪些属性定义,使得一个DOM元素不显示在浏览器可视范围内?
让DOM元素不显示在浏览器可视范围内,有多种方法,根据需求选择不同的属性:
最基本和常用的方式:
-
display: none;
-
元素会从文档流中完全移除,不占据任何空间。
-
屏幕阅读器也无法访问该元素。
-
不会触发重绘(repaint)和回流(reflow),性能较好。
-
-
visibility: hidden;
-
元素会隐藏,但在文档流中仍占据其原有的空间。
-
屏幕阅读器可以访问该元素。
-
会触发重绘,但不会触发回流。
-
技巧性和其他方式:
-
设置宽高为0:
-
width: 0; height: 0;
-
元素依然在文档流中,但因为没有尺寸所以不可见。如果元素有
padding
、border
或margin
,可能仍会占据空间。 -
会触发回流和重绘。
-
-
设置透明度为0:
-
opacity: 0;
-
元素完全透明,但仍然占据空间,并且可以响应事件(如点击)。
-
屏幕阅读器可以访问该元素。
-
通常只触发重绘。
-
-
设置
z-index
为负值并配合position
:-
position: absolute; z-index: -9999;
(或relative
,fixed
) -
将元素定位到其他内容下方,使其被其他内容覆盖而不可见。
-
元素仍在文档流中(如果
position: relative
),或脱离文档流(如果absolute
/fixed
)。 -
会触发回流和重绘。
-
-
clip-path
或clip
(旧属性):-
通过裁剪路径来隐藏元素的一部分或全部。
-
clip-path: polygon(0 0, 0 0, 0 0, 0 0);
或clip: rect(0 0 0 0);
-
元素仍占据空间。
-
-
transform: scale(0);
或transform: translate(-9999px, -9999px);
-
scale(0)
将元素缩放到零尺寸。 -
translate
将元素移动到屏幕外很远的地方。 -
元素仍占据空间(
translate
不影响文档流,scale(0)
可能使它不占据视觉空间)。 -
通常只触发重绘(或层合成)。
-
选择哪种方式取决于具体的场景和需求,比如是否需要保留空间、是否响应事件、是否需要被屏幕阅读器访问以及性能考量等。
13. 常用的块级元素标签及其特征有哪些?
常用的块级元素(Block-level Elements)标签及其特征如下:
常用块级标签示例:
-
<div>
:最常用的块级容器。 -
<h1>
到<h6>
:标题标签。 -
<p>
:段落标签。 -
<ul>
、<ol>
、<li>
:无序列表、有序列表及其列表项。 -
<dl>
、<dt>
、<dd>
:定义列表、定义术语、定义描述。 -
<form>
:表单容器。 -
<table>
:表格容器。 -
<address>
:地址信息。 -
<article>
、<aside>
、<details>
、<figcaption>
、<figure>
、<footer>
、<header>
、<hgroup>
、<main>
、<nav>
、<section>
、<summary>
(HTML5语义化标签)
块级元素的特征:
-
独占一行: 无论内容多少,块级元素都会默认占据其父元素的整个可用宽度,并且会在其前后各产生一个换行符,使得其自身以及后续元素从新的一行开始显示。
-
可以设置宽、高: 可以通过CSS的
width
和height
属性来明确设置其宽度和高度。 -
可以设置
margin
和padding
:margin-top
、margin-bottom
、margin-left
、margin-right
以及padding-top
、padding-bottom
、padding-left
、padding-right
都有效,并且可以控制元素与其周围元素的空间以及内容与边框的空间。 -
可以嵌套块级元素和内联元素: 块级元素内部通常可以包含其他块级元素和内联元素。
14.常用的行内元素标签及其特征有哪些?
常用的行内元素(Inline-level Elements)标签及其特征如下:
常用行内标签示例:
-
<span>
:最常用的行内容器,用于文本或其他行内内容的样式化。 -
<a>
:超链接。 -
<img>
:图像。 -
<strong>
、<em>
:强调文本。 -
<input>
、<textarea>
、<select>
、<option>
、<button>
:表单控件。 -
<code>
、<var>
、<kbd>
、<samp>
:代码、变量、键盘输入、示例输出。 -
<br>
:换行符(一个特殊的行内元素,不包含内容)。
行内元素的特征:
-
在行内显示: 多个行内元素会在同一行内水平排列,直到一行排满,然后才会在下一行继续显示。
-
内容撑开宽、高: 默认情况下,行内元素的宽度和高度由其内部内容的尺寸决定,不能通过CSS的
width
和height
属性来直接设置。 -
部分
margin
和padding
有效:-
水平方向的
margin-left
和margin-right
有效。 -
垂直方向的
margin-top
和margin-bottom
无效(或者说不会影响其占据的实际空间)。 -
水平方向的
padding-left
和padding-right
有效。 -
垂直方向的
padding-top
和padding-bottom
有效,但它们会增加元素的视觉高度,而不会影响其所占据的行高,可能导致内容重叠。
-
-
通常只能嵌套行内元素: 行内元素内部通常只能包含其他行内元素或纯文本,不能直接包含块级元素。如果需要在行内元素中嵌套块级元素,通常需要将该行内元素转换为块级或行内块级元素(如
display: block;
或display: inline-block;
)。
特殊情况:
有一些行内元素(如<img>
、<input>
、<textarea>
、<select>
)虽然默认是行内元素,但它们可以设置width
、height
、margin-top
、margin-bottom
等属性。这是因为它们被设计为“可替换元素”(Replaced Elements),其内容由外部资源(如图片文件)决定,它们的尺寸特性更接近于块级元素。
15. 如何避免文档流中的空白符合并现象?
空白符合并(Whitespace Collapsing)是标准文档流中一个常见的特性,尤其在处理文本和内联元素时。它指的是浏览器会将连续的空白符(空格、tab、换行符等)合并为一个单一的空格来显示。
要避免这种现象,可以通过设置white-space
CSS属性来修改这一特性。white-space
属性决定了元素内部空白符的显示方式,以及是否允许文本换行。
white-space
属性值及其效果:
-
normal
(默认值):-
合并连续的空白符。
-
不渲染换行符(除非有
<br>
标签)。 -
文本会自动换行以适应容器宽度。
-
-
nowrap
:-
合并连续的空白符。
-
不渲染换行符。
-
文本不会自动换行,内容会显示在一行上,可能超出容器。
-
-
pre
:-
不会合并空白符(保留所有空格和制表符)。
-
渲染换行符(即保留HTML源代码中的换行)。
-
文本不会自动换行(类似于
<pre>
元素)。
-
-
pre-wrap
:-
不会合并空白符。
-
渲染换行符。
-
文本会自动换行以适应容器宽度。
-
-
pre-line
:-
合并连续的空白符。
-
渲染换行符。
-
文本会自动换行以适应容器宽度。
-
如何避免空白符合并现象:
如果你希望保留HTML源码中所有的空白符和换行符,并让它们原样显示,最常用的属性值是:
-
white-space: pre-wrap;
:这是最灵活且常用的选择,它保留了所有空白符和换行符,同时允许文本根据容器宽度自动换行。 -
white-space: pre;
:如果你想要完全模仿<pre>
标签的行为(保留空白符和换行符,且不自动换行),可以使用这个。
示例:
<div style="white-space: pre-wrap;">这是一段包含 多余空格和换行符的文本。
</div>
这段文本将按照HTML源码中的格式(包括多余的空格和换行)显示,并且会在达到容器宽度时自动换行。
注意: 对于inline-block
元素之间的空白间隙问题(而非文本内容本身的空白符),通常通过设置父元素的font-size: 0;
或使用HTML注释来消除(注释本身是 不可解析的代码内容,插入后相当于 “填充” 了标签间的位置,让浏览器无法识别出空白符,从而切断间隙的产生条件),white-space
属性主要用于控制文本内容的空白符显示。
16. 常见的兼容性问题有哪些?
CSS兼容性问题在前端开发中非常常见,主要体现在不同浏览器(IE、Chrome、Firefox、Safari等)对CSS属性、HTML标签解析方式以及渲染引擎的差异上。以下是一些常见的兼容性问题及其解决方案:
-
浏览器默认的
margin
和padding
不同:-
问题: 不同浏览器对HTML元素的默认外边距和内边距有差异,导致布局不一致。
-
解决方案: 使用CSS重置(Reset CSS)或规范化(Normalize CSS)。最简单粗暴的方法是在CSS文件开头添加:
* {margin: 0;padding: 0;/* 也可以加上 box-sizing: border-box; */ }
或者使用Normalize.css这样的库,它在重置的同时保留了浏览器的一些有用默认样式。
-
-
不同浏览器下
button
按钮的默认样式不一致:-
问题:
button
元素的默认样式在不同浏览器下差异较大。 -
解决方案: 重置
button
的所有样式:button { border: none; background: transparent; cursor: pointer; /* 其他样式 */ }
,然后自定义样式。
-
-
怪异模式问题(缺少或错误的DOCTYPE声明):
-
问题: 漏写或写错DOCTYPE声明会导致浏览器进入怪异模式,从而采用非标准的渲染方式(例如IE盒模型),引起布局混乱。
-
解决方案: 始终在HTML文档的开头使用推荐的HTML5 DOCTYPE声明:
<!DOCTYPE html>
。这是避免怪异模式最有效的方法。
-
-
相邻块级元素的垂直外边距重叠问题:
-
问题: 在IE和Firefox等浏览器中都存在,相邻两个
div
的margin-left
和margin-right
不会重叠,但是margin-top
和margin-bottom
会重叠。 -
解决方案:
-
理解并接受这是CSS规范的一部分,而不是Bug。
-
养成良好的代码编写习惯,统一使用
margin-top
或margin-bottom
来控制垂直间距,而不是混用。 -
在需要避免折叠时,可以触发BFC(如设置
overflow: hidden;
,或将其中一个元素设置为inline-block
等)。 -
利用
padding
或border
将元素隔开,阻止折叠。
-
-
总结: 最佳实践是使用Reset CSS或Normalize CSS,并在开发过程中进行充分的浏览器兼容性测试。
17. 透明度具有继承性,如何取消透明度的继承?
使用opacity
属性设置的透明度是具有继承性的,这意味着如果父元素设置了opacity
,其所有子元素都会变得透明,并且子元素自身的透明度会在此基础上叠加。
要“取消”这种继承,实际上是避免使用opacity
,转而使用rgba()
或hsla()
颜色值。
解决方案:
使用rgba()
(Red, Green, Blue, Alpha)或hsla()
(Hue, Saturation, Lightness, Alpha)给元素的背景颜色、文本颜色、边框颜色等属性设置透明度,而不是给元素本身设置opacity
。
rgba()
和hsla()
的特点:
-
它们只作用于所指定的颜色属性,例如
background-color
、color
、border-color
。 -
它们不会影响元素内部的子元素,子元素将保持其自身的不透明度,而不会继承父元素的颜色透明度。
示例:
问题代码(使用opacity
导致继承):
<div class="parent">父元素内容<div class="child">子元素内容</div>
</div>
.parent {background-color: black;opacity: 0.5; /* 父元素及其子元素都会半透明 */padding: 20px;
}
.child {background-color: blue;color: white;
}
效果:父元素的背景、文本以及子元素的背景和文本都会变得半透明。
解决方案(使用rgba()
避免继承):
<div class="parent">父元素内容<div class="child">子元素内容</div>
</div>
.parent {background-color: rgba(0, 0, 0, 0.5); /* 只有背景色半透明 */padding: 20px;
}
.child {background-color: blue;color: white; /* 子元素保持完全不透明 */
}
效果:只有父元素的背景色是半透明的,父元素内部的文本以及子元素的背景和文本都保持完全不透明。
通过这种方式,你可以实现只让元素的特定颜色属性(如背景)透明,而不会影响到其子元素的显示效果。
18. CSS中,自适应的单位都有哪些?
CSS中用于实现自适应布局的单位主要有以下几类,它们可以根据不同的基准进行动态调整:
-
百分比(%):
-
相对基准: 通常相对于父元素(或包含块)的尺寸。
-
例子:
width: 50%;
(宽度是父元素宽度的50%)。对于font-size
,百分比是相对于父元素的font-size
。对于line-height
,百分比是相对于元素自身的font-size
。
-
-
视口单位(Viewport Units):
-
这些单位是相对于浏览器视口(Viewport)的尺寸。视口是指浏览器窗口中显示网页内容的区域,不包括滚动条和工具栏。
-
vw
(Viewport Width): 相对于视口宽度的1%。例如,1vw
等于视口宽度的1%。 -
vh
(Viewport Height): 相对于视口高度的1%。例如,1vh
等于视口高度的1%。 -
vmin
(Viewport Minimum): 相对于视口宽度和高度中较小的一个的1%。例如,如果视口宽度是800px,高度是600px,那么1vmin
就是6px。 -
vmax
(Viewport Maximum): 相对于视口宽度和高度中较大的一个的1%。例如,如果视口宽度是800px,高度是600px,那么1vmax
就是8px。
-
-
相对字体大小单位:
-
这些单位是相对于元素字体大小或根元素字体大小的。
-
em
: 相对于当前元素(或其父元素)的font-size
。如果元素没有设置font-size
,它会继承父元素的font-size
。这种相对性是累加的,可能导致复杂的计算。-
例子: 如果父元素
font-size
是16px
,子元素font-size
是1.2em
,那么子元素字体大小是16px * 1.2 = 19.2px
。
-
-
rem
(Root Em): 相对于根元素(<html>
元素)的font-size
。这种单位避免了em
的累加性问题,使得所有元素的大小都以根元素为基准,更易于控制和实现整体缩放。-
例子: 如果
html { font-size: 16px; }
,那么1rem
就等于16px
。
-
-
总结:
这些自适应单位为响应式设计提供了强大的工具,允许元素尺寸根据父元素、视口或字体大小等动态调整,从而更好地适应不同设备和屏幕尺寸。
19. 请说说rem
和em
的区别。
rem
和em
都是CSS中的相对单位,主要用于字体大小和长度的设置,但它们计算的基准不同:
-
em
单位:-
基准:
em
是相对于**当前元素自身font-size
**的大小。如果当前元素没有设置font-size
,则会继承其父元素的font-size
。 -
累加性(Compoundability): 这是
em
最需要注意的特点。如果存在多层嵌套,em
会逐层继承和累加父元素的font-size
。-
例如:
html { font-size: 16px; }
-
div { font-size: 1.2em; /* 16px * 1.2 = 19.2px */ }
-
p { font-size: 1.2em; /* 19.2px * 1.2 = 23.04px */ }
-
-
应用场景: 适用于那些需要保持相对于父元素内容比例的场景,例如行高(
line-height
)、文本缩进(text-indent
)。
-
-
rem
单位:-
基准:
rem
是相对于**根元素(<html>
元素)的font-size
**的大小。 -
非累加性: 无论元素嵌套多深,
rem
的计算都只依赖于<html>
元素的font-size
。这使得rem
在控制全局字体大小和进行响应式布局时更加可预测和易于管理。-
例如:
html { font-size: 16px; }
-
div { font-size: 1.2rem; /* 16px * 1.2 = 19.2px */ }
-
p { font-size: 1.5rem; /* 16px * 1.5 = 24px */ }
-
-
应用场景: 广泛用于响应式布局,通过调整根元素的
font-size
(通常结合媒体查询),可以实现页面所有元素(使用rem
的)的等比例缩放,常用于模块化布局、元素尺寸、间距等。
-
总结:
-
em
: 基于父元素字体大小,具有累加性,适用于局部、相对调整。 -
rem
: 基于根元素字体大小,无累加性,适用于全局、统一缩放的响应式布局。
在现代Web开发中,rem
因其更易于控制和维护的特性,在响应式设计中被广泛推荐使用。
20. 什么是FOUC?如何避免FOUC?
FOUC,全称是 "Flash Of Unstyled Content",中文译为“无样式内容闪烁”。它指的是在页面加载过程中,由于某些原因,浏览器先显示了没有应用样式的页面内容,然后等CSS加载并解析完成后,再应用样式,导致页面内容在短时间内呈现出“闪烁”或“跳动”的现象。
产生FOUC的原因:
FOUC通常发生在:
-
使用
@import
方式导入CSS文件:
@import
规则会导致浏览器在解析HTML文档的DOM树时,先加载和渲染HTML内容,然后才会去下载和解析通过@import
引入的CSS文件。在这两个步骤之间,页面会短暂地显示无样式的原始HTML内容。
示例:<style type="text/css" media="all">@import url('demo.css');</style>
-
CSS文件放置位置不当: 如果将
<link>
标签放置在HTML文档的底部,或者JavaScript代码(特别是涉及到DOM操作的JS)阻碍了CSS的加载和渲染,也可能导致FOUC。 -
JavaScript动态加载CSS: 如果CSS文件是通过JavaScript异步加载的,那么在CSS加载完成之前,也会出现FOUC。
如何避免FOUC:
避免FOUC的关键在于确保CSS文件在HTML内容被渲染之前或同时被加载和解析。
-
避免使用
@import
导入CSS:-
这是最直接有效的方法。始终使用
<link>
标签在HTML文档的<head>
部分引入外部CSS文件。 -
<link>
标签会使浏览器在解析HTML时,同步下载CSS文件,并等待CSS加载解析完成后再渲染DOM,从而避免FOUC。 -
推荐做法:
<head><link rel="stylesheet" href="styles.css"> </head>
-
-
将所有
<link>
标签放在<head>
标签内:-
确保所有的CSS
<link>
标签都放在HTML文档的<head>
部分,并且放在任何可能阻止渲染的脚本(如外部JavaScript文件,除非它们有defer
或async
属性)之前。 -
这样可以保证浏览器在构建渲染树时能够获取到完整的样式信息。
-
-
使用
defer
或async
属性优化JavaScript加载:-
如果页面中有需要同步加载的JavaScript文件可能会阻塞CSS或DOM渲染,可以尝试为其添加
defer
或async
属性,使其异步加载,从而避免阻塞渲染流。
-
-
适当的CSS文件大小和优化:
-
减小CSS文件大小,优化CSS代码,减少HTTP请求,可以加快CSS的加载和解析速度,从而缩短FOUC出现的时间。
-
遵循这些实践,特别是使用<link>
标签在<head>
中引入CSS,是避免FOUC的黄金法则。
21. 请说说display: none
和visibility: hidden
的区别。
display: none
和visibility: hidden
都可以隐藏元素,但它们在对页面布局、性能以及可访问性方面存在显著的区别:
-
是否占据空间(Layout Impact):
-
display: none;
:-
元素会从文档流中完全移除,不占据任何空间。
-
就好像这个元素从来没有在页面上存在过一样,它周边的元素会立即合拢来填补它原本占据的空间。
-
示例: 类似于删除DOM节点的效果。
-
-
visibility: hidden;
:-
元素会被隐藏起来(不可见),但它仍然在文档流中,并占据其原有的空间。
-
它只是视觉上不可见,但它的“盒子”依然存在于布局中,不会影响周围元素的排列。
-
示例: 类似于透明度设置为0,但元素仍然在那里。
-
-
-
渲染性能(Performance):
-
display: none;
:-
改变此属性通常会导致回流(reflow)和重绘(repaint)。
-
因为元素从文档流中移除或加入,浏览器需要重新计算布局。
-
但由于元素不再参与渲染,后续的性能开销较小(因为它不再需要绘制)。
-
-
visibility: hidden;
:-
改变此属性通常只会导致重绘(repaint),而不会引起回流。
-
因为元素的空间保持不变,不需要重新计算布局。
-
对于频繁切换可见性的元素,
visibility: hidden
通常比display: none
性能更好,因为它避免了回流。
-
-
-
事件响应(Event Handling):
-
display: none;
:-
元素完全消失,不响应任何鼠标事件(如
click
、hover
)和键盘事件。 -
其子元素也同样不响应事件。
-
-
visibility: hidden;
:-
元素虽然不可见,但它仍然存在于DOM中,并且会响应鼠标事件(例如,如果你知道它的确切位置,仍然可以点击它)。
-
但通常情况下,为了用户体验,我们会通过JS阻止其响应事件,或者与
pointer-events: none;
结合使用。
-
-
-
可访问性(Accessibility,屏幕阅读器):
-
display: none;
:-
元素及其内容对屏幕阅读器来说是不可访问的。
-
屏幕阅读器会忽略这些元素。
-
-
visibility: hidden;
:-
元素及其内容仍然可以被屏幕阅读器访问到。
-
这对于某些需要隐藏视觉但保留语义和可访问性的场景很有用。
-
-
总结表格:
特性 | display: none; | visibility: hidden; |
---|---|---|
是否占据空间 | 不占据,完全从文档流中移除 | 占据空间,但内容不可见 |
性能 | 改变时触发回流和重绘,隐藏后开销小 | 改变时只触发重绘,隐藏后仍占用内存和渲染树空间 |
事件响应 | 不响应任何事件 | 响应事件(通常需要结合pointer-events: none ) |
可访问性 | 屏幕阅读器无法访问 | 屏幕阅读器可以访问 |
使用场景 | 动态创建/销毁、切换页面模块,元素彻底消失 | 元素需要暂时隐藏但又需要保留空间(如动画起始帧) |
CSS篇总结:
CSS 部分的面试题主要考察应试者对CSS 基础概念模型的理解,例如文档流、盒模型、浮动、定位、选择器权重、样式继承等。很多应试者认为CSS 很简单,没多少内容,面试就是面试 JavaScript 部分的内容,这些观点是错误的,面试的第一关往往会考察应试者对CSS 的掌握情况。因此,CSS 也常常是应试者掉入的第一个陷阱。