可替换元素

可替换元素(英文: replaced element), 起初只是想了解什么是"可替换元素", 但是看了几个解释也理解不了, 所以接着又查了不少资料, 最终结果是本文有钻牛角尖的嫌疑.

先看MDN的解释:

CSS 里,可替换元素(replaced element)的展现不是由CSS来控制的。这些元素是一类外观渲染独立于CSS的外部对象。 典型的可替换元素有 <img><object><video> 和 表单元素,如<textarea><input> 。 某些元素只在一些特殊情况下表现为可替换元素,例如 <audio><canvas> 。 通过 CSS content 属性来插入的对象 被称作 匿名可替换元素(anonymous replaced elements

"这些元素是一类外观渲染独立于CSS的外部对象"是什么意思? 理解不了. 后面又找到 CSS2.1规范中的定义

An element whose content is outside the scope of the CSS formatting model, such as an image, embedded document, or applet. For example, the content of the HTML IMG element is often replaced by the image that its "src" attribute designates. Replaced elements often have intrinsic dimensions: an intrinsic width, an intrinsic height, and an intrinsic ratio. For example, a bitmap image has an intrinsic width and an intrinsic height specified in absolute units (from which the intrinsic ratio can obviously be determined). On the other hand, other documents may not have any intrinsic dimensions (for example, a blank HTML document).

User agents may consider a replaced element to not have any intrinsic dimensions if it is believed that those dimensions could leak sensitive information to a third party. For example, if an HTML document changed intrinsic size depending on the user's bank balance, then the UA might want to act as if that resource had no intrinsic dimensions.

The content of replaced elements is not considered in the CSS rendering model.

最有用的当属第一句和最后一句, 第一句的"outside the scope of the CSS formatting model"和上面的"外观渲染独立于CSS"解释相似, 那所谓的"CSS formatting model"是什么东西? 规范里面有两章描述这个 Visual formatting modelVisual formatting model details, 这就脱离了本文讨论的东西了(实际上是我看不懂...). 不过最后一句还是好懂的, CSS"不干预"可替换元素的内容, 那也就是说CSS里面设置的content对可替换元素无效. 在 stackoverflow 上也找到一个关于这个问题的回答 Is HTML label a replaced element?, 里面提到这么一种验证思路:

You cannot apply generated content to replaced elements. That is, you cannot apply the pseudo-element selectors :before or :after to them.

既然这样, 就写份 HTML 验证一下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Replaced Elements</title>
    <style>
        tbody td {
            padding: 10px 20px;
        }

        tbody > tr > td:nth-child(2) > *:before {
            content: "«";
            color: blue;
        }

        tbody > tr > td:nth-child(2) > *:after {
            content: "»";
            color: red;
        }
    </style>
</head>
<body>
<table border="1">
    <thead>
    <tr>
        <th>元素</th>
        <th>表现</th>
    </tr>
    </thead>

    <tbody>
    <tr>
        <td>label</td>
        <td><label for="">标签</label></td>
    </tr>

    <tr>
        <td>button</td>
        <td>
            <button>按钮</button>
        </td>
    </tr>

    <tr>
        <td>img</td>
        <td><img src="https://iph.href.lu/200x50?text=img" alt=""></td>
    </tr>

    <tr>
        <td>select</td>
        <td>
            <select name="" id="">
                <option value="1">选项 1</option>
                <option value="2">选项 2</option>
                <option value="3">选项 3</option>
            </select>
        </td>
    </tr>

    <tr>
        <td>meter</td>
        <td>
            <meter value="0.3"></meter>
        </td>
    </tr>

    <tr>
        <td>progress</td>
        <td>
            <progress value="0.3"></progress>
        </td>
    </tr>

    <tr>
        <td>textarea</td>
        <td><textarea name="" id="" cols="30" rows="3">文本</textarea></td>
    </tr>

    <tr>
        <td>input[type=text]</td>
        <td><input type="text" value="输入框"></td>
    </tr>

    <tr>
        <td>input[type=radio]</td>
        <td><input type="radio"></td>
    </tr>

    <tr>
        <td>input[type=checkbox]</td>
        <td><input type="checkbox"></td>
    </tr>

    <tr>
        <td>input[type=range]</td>
        <td><input type="range"></td>
    </tr>

    <tr>
        <td>input[type=file]</td>
        <td><input type="file"></td>
    </tr>

    <tr>
        <td>input[type=image]</td>
        <td><input type="image" src="https://iph.href.lu/200x50?text=input[type=image]"></td>
    </tr>

    <tr>
        <td>input[type=submit]</td>
        <td><input type="submit" value="提交"></td>
    </tr>

    <tr>
        <td>iframe</td>
        <td>
            <iframe src="http://www.baidu.com" frameborder="1"></iframe>
        </td>
    </tr>

    <tr>
        <td>object[type=image/png]</td>
        <td>
            <object data="httpshttps://iph.href.lu/200x50?text=object" type="image/png"></object>
        </td>
    </tr>

    <tr>
        <td>embed[type=image/png]</td>
        <td>
            <embed type="image/png" src="https://iph.href.lu/200x50?text=embed">
        </td>
    </tr>

    <tr>
        <td>hr</td>
        <td>
            <hr>
        </td>
    </tr>

    <tr>
        <td>br</td>
        <td>换行前<br>换行后</td>
    </tr>
    </tbody>
</table>
</body>
</html>

下面两张图是 Win7 分别在 Chrome68 和 Firefox62 的渲染效果.

chrome68Render
firefox62Render

两个浏览器渲染结果是不同的, 差异集中在 input 那块. 这里有一篇关于这个问题的讨论: CSS generated content on replaced elements, 文章中有几个开发者表达了自己的看法(主要是对 Chrome 的渲染结果), 有说是 bug 的, 也有说是 feature 的. 不过这貌似还是没解决问题.

后面又找到了 W3C 文档里面提供的浏览器对元素和控件的渲染参考, 里面有两个小节值得注意: 可替换元素非可替换元素, 按照里面的分类, 属于可替换元素的有: embed, iframe, video, img, input[type=image](即 Image Button), 特定情况下的 audio, canvas, object, 其他的都属于非可替换元素.

一路下来, 实际上也并没有找到一个规范或定义, 可以严格分类可替换元素和非可替换元素, 倘若一定要选出最靠谱, 那我认为是 W3C 给出的渲染参考里面的分类. 不过文章开头也说了, 本文有钻牛角尖的嫌疑, 实际上弄清楚哪些元素是可替换元素并不应该成为目的, 更多是为学习(写) CSS 服务的, 所以其实更应该花时间弄清楚 "CSS rendering model" .

参考链接:
HTML 5.3: 2 Common infrastructure#replaced-element

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 14,018评论 1 92
  • 夜沉的滴下几滴水 落在无眠人的心上 起身熄灭亮着的灯 把期盼紧紧抱在怀里 酿成酸味的酒 洒在自己的酒窝 路绵延在远...
    爱吃面包的树阅读 172评论 7 11
  • 过几天就是小鱼五周岁生日了,这几天特别的怀旧,脑海里不断想着他出生时的情景,居然有点模糊,甚...
    娜些事阅读 412评论 0 1
  • 夏天ALex的那一首歌 不再联系,在脑海里久久循环 我和你不再联系,不再打扰彼此的生活 请你不要介意,要怪就怪当初...
    木子虫阅读 252评论 0 0
  • 今年我28她27! 1、深思熟虑的开始了这一生最后的一场恋爱和余生的征程! 四个来月的男女关系!好坏参半、但也各自...
    陌上莨人阅读 400评论 0 3

友情链接更多精彩内容