今天刷面试题的时候,偶然看到一道题,问可替换元素与非可替换元素的差异是什么?
看到题突然发现自己其实差远了,学了这么久前端,压根没听说过这个名词。
特地搜索学习,将相关知识总结分享出来。
可替换元素 (replaced element)
可替换元素,表示在 CSS 中,这些元素的展现效果不是由 CSS 来控制的。它们是一种外部对象,外观的渲染是独立于 CSS 的。
简单来说,它们的内容不受当前文档的样式的影响。CSS 可以影响可替换元素的位置,但不会影响到可替换元素自身的内容。某些可替换元素,例如 <iframe> 元素,可能具有自己的样式表,但它们不会继承父文档的样式。
CSS 能对可替换元素产生的唯一影响在于,部分属性支持控制元素内容在其框中的位置或定位方式。
典型的可替换元素有:
<iframe>内联框架元素<video>播放播放器元素<embed>外部内容嵌入元素<img>图片元素
有些元素仅在特定情况下被作为可替换元素处理,例如:
<option>菜单项元素<audio>音频播放器元素<canvas>画布元素<object>嵌入对象元素
类型为"image" 的 <input> 元素就像 <img> 一样会被替换,也属于可替换元素。但是其他类型的 <input> 元素,并不是可替换元素。
用 CSS content 属性插入的伪元素(例如 ::before 与 ::after)也是匿名的可替换元素。它们并不存在于 HTML 标记中,因此是“匿名的”。
非替换元素 (non-replaced elements)
和可替换元素对应,不是可替换元素的元素就是非可替换元素。
HTML 中的大多数元素都是不可替换元素,例如 <p> <h1> <div> 等等
差异
最主要的差异在上文中已经说过了,就是可替换元素的展现效果不是由 CSS 来控制的。
我们可以用一种更通俗易懂的方式来理解,所有可替换元素,其实都是两层 div,外层 div 表示它们在页面布局中的展示,内层 div 是可替换元素的内容(如视频、图片、网页等等)。我们的 CSS 属性,只可以修改外层的 div 的布局效果,而无法作用于内层 div。
举个例子,在我们使用 canvas 元素时,当我们要修改画布的宽高,一般会这样写
<canvas width="600" height="400" id="canvas"></canvas>
或者使用js
<script>
const canvas = document.querySelector('#canvas')
canvas.width = 600
canvas.height = 400
</script>
而不是修改 CSS
<style>
#canvas {
width: 600px;
height: 400px;
}
</style>
或这样
<script>
const canvas = document.querySelector('#canvas')
canvas.style.width = '600px'
canvas.style.height = '400px'
</script>
弄清楚这两种方案的异同,有助于我们理解可替换元素与CSS之间的关系。
为方便演示,我们在画布中绘制一些内容,并以使用 js 的实现方式来讲解,代码如下
<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>
<script>
const canvas1 = document.querySelector('#canvas1')
const ctx1 = canvas1.getContext('2d')
const canvas2 = document.querySelector('#canvas2')
const ctx2 = canvas2.getContext('2d')
canvas1.width = 600
canvas1.height = 400
canvas2.style.width = '600px'
canvas2.style.height = '400px'
const draw = (ctx, str) => {
ctx.fillStyle = 'pink'
ctx.fillRect(0, 0, canvas1.width, canvas1.height)
ctx.beginPath()
for (let i = 0; i < 10; i++) {
ctx.moveTo(i * 40, 0)
ctx.lineTo(i * 40, 400)
}
ctx.closePath()
ctx.stroke()
ctx.fillStyle = 'black'
ctx.font = '48px serif'
ctx.fillText(str, 50, 100)
}
draw(ctx1, '方案一')
draw(ctx2, '方案二')
</script>
从两种方案的效果图中可以明显看出区别,后者的线宽比前者粗,没有完整显示出 10 条线。
这两种方案,都修改了画布元素在布局上的宽高。但是,前者是修改 canvas 元素的属性,后者是修改容器的 CSS 属性,后者将画布的内容放大了 (浏览器中画布元素的默认宽高是 300 X 150)。
所以,设置可替换元素的 CSS 属性,只能影响其布局,而无法影响其内容。
一般想要修改可替换元素的属性时,会去修改可替换元素中包含的内容对象(内层 div)
独有属性
可替换元素还独有的2个 CSS 属性,用于指定 内层 div 在外层 div 中的位置或定位方式。
object-fit
此属性用于指定可替换元素的内容对象在元素盒区域中的填充方式。(类似于 background-size)
此属性默认为 fill,用法如下
<style>
canvas {
object-fit: contain;
}
</style>
object-position
此属性用于指定可替换元素的内容对象在元素盒区域中的位置。(类似于 background-position)
此属性默认为 50% 50%,用法如下
<style>
canvas {
object-position: 20px 40px;
outline: 1px solid black;
}
</style>
垂直对齐方式
CSS 中的vertical-align 属性,用于指定行内元素的垂直对齐方式。可替换元素 都是行内块元素,在浏览器中此属性的默认值与其余行内元素不同,这也是导致文字与图片对不齐问题的原因。
<style>
span {
outline: 1px solid red;
}
</style>
<span>文字更靠下一点</span>
<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>
结语
如果文中有错误或不严谨的地方,请务必给予指正,十分感谢。
如果喜欢或者有所启发,欢迎点赞关注,鼓励一下新人作者。
内容参考