5

CSS content新的替换元素规范行为解读

 2 years ago
source link: https://www.zhangxinxu.com/wordpress/2021/10/css-content-url/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10143 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

CSS content占位图

一、普通元素能否变成替换元素

我们通常所说的替换元素指的是图片、视频等元素,对应的 HTML 标签是 <img><video>、而平常用来布局的 <div><p><span> 等元素都是非替换元素。

实际上,从2019年往后,上面这条规则已经变得不准确的,或者说是在约束条件下才能成立的规则。

换句话说,<div><span> 等元素在某些条件下也是可以转变成替换元素的,这个转变的条件就是 content 属性的 url() 函数语法。

二、content 与替换元素

所谓“替换元素”指的就是内容可替换,而 content 属性是可以直接替换 HTML 中的内容的,因此,可以让 content 属性生效的场景,我们都可以称为替换元素。

如果是在 ::before/::after 伪元素中生效,那么此时这个伪元素被称之为 “匿名替换元素”。

.some::before {
    content: url(1.jpg);    
}

在 CSS 语系中,没有明确的 HTML 标签的东西称之为“匿名”,例如下面这段 HTML:

<p>我是<span>鑫旭</span>

其中,“我是”的就是匿名内联盒子,而“鑫旭”是内联盒子,因为外部有明确的 <span> 标签。

在伪元素这里也是类似的,::before/::after 创建的内容外部是没有明确的标签的,因此,被称为 “匿名替换元素”。

既然 content 属性有“匿名替换元素”,那 content 属性有没有“替换元素”呢?两者的区别又是在哪里呢?

首先第一个问题的回答是 “有!”

content 新的规范特性

这个新的规范特性就是,即使不借助伪元素,content 属性也能对内容进行替换!

其历史发展进程是这样的:

  1. 没有任何浏览器支持在非伪元素中使用 content 属性;
  2. 大概17年还是18年的时候,Chrome 浏览器率先支持普通元素直接设置 content 属性;
  3. 19 年 content 规范进行了明确,Firefox 和 Safari 浏览器也跟进了支持。

因此,目前的状况是,所有现代浏览器均支持 content 属性替换内容,不过,仅支持 url() 资源替换,并不支持字符内容的替换。

举个例子,下面是个 logo 所在的 HTML:

<h1>鑫空间-鑫生活</h1>

在过去,我们的做法是设置字号为 0 或者文字透明,然后 logo 作为背景图显示,现在,可以直接使用 content 属性一次性解决:

h1 {
    content: url(logo.png);    
}
url()替换元素生效示意

此时无论是辅助设备识别还是搜索引擎,都能获得准确的文字内容,而对于正常用户,看到的还是 logo 图像,兼顾了视觉与功能。

此时的 <h1> 就是一个替换元素,本质上和 <img> 元素并无区别。

和匿名替换元素区别

由于匿名替换元素缺少明确的标签,因此,图像的外部尺寸是无法进行调整的,例如:

h1::before {
    width: 100px; height: 100px;
    content: url(logo.png);    
}

上面的 CSS 中的 width:100pxheight:100px; 都是无法改变 logo.png 这个图像的尺寸的,因为他是“匿名”的,这就好像一个没有蛋壳的鸡蛋,你无法通过改变蛋壳大小,从而影响内部蛋白和淡黄的形状和尺寸。

但是替换元素不同,由于有显式的标签元素,因此,可以作为替换元素的外部尺寸进行设置,例如:

h1 {
    width: 100px; height: 100px;
    content: url(logo.png);    
}

此时 logo.png 图像的尺寸就是 100px * 100px。

三、content 新特性解读

所有现代浏览器均支持在任意 HTML 元素中使用 content url() 函数语法,且一旦使用,该元素就会变成替换元素。

原因在于:

  1. 从行为上讲,原本的内容全部被替换成了图像,是典型的替换元素。
  2. 从样式表现上将,和 <img> 元素并无二样。

<img> 元素并无区别

例如,<img> 元素通过设置宽高可以拉伸图片的尺寸,在上面的例子中 <h1> 元素也有类型的行为。

又例如,<img> 元素通过设置 object-fit 属性控制图像的如何适应显示,<h1> 元素也有一样的行为,例如:

h1 {
    width: 100px; height: 100px;
    content: url(logo.png);
    object-fit: contain;
}

就是下图所示的效果,logo 图像在保持比例的同时,显示在了 100px * 100px 的区域内。

object-fit作用于非图像元素

四、反之也成立

所谓反之也成立,指的是,如果原本一个元素是替换元素,那么如果我们设置 content:'' 进行重置,则这个元素会被还原成非替换元素。

此时,我们就可以使用 ::before / ::after 伪元素实现一些功能。

例如,2020年最热门的“图片加载失败后CSS样式处理最佳实践”这篇文章提到的技术实现,就是利用这一特性:

<img src="zxx.png" alt="CSS新世界封面" onerror="this.classList.add('error');">
img.error {
  display: inline-block;
  transform: scale(1);
  content: '';
  color: transparent;
}
img.error::before {
  content: '';
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
  background: #f5f5f5 url(break.svg) no-repeat center / 50% 50%;
}
img.error::after {
  content: attr(alt);
  //... 略
}

此时,出错的图片不仅显示了裂开的图像,同时还显示了 alt 信息,让用户知道这张图片所代表的含义是什么。

图像失败和alt信息同时出现

五、实际开发中的应用

使用 content 属性显示图像在日常开发中并不常用,如果是普通的图像显示,你就使用 <img> 元素,如果是装饰性的图像显示,你就使用 background-image 属性。

只有什么时候需要使用 content 属性呢?

就是希望源代码层面还是原来的 HTML 内容结构,但是视觉表现上依然是图像。

比方说一开始提到的logo显示,又比如想要在不改变 HTML 结构的前提下,清空(或隐藏)一大段内容,则可以使用:

.container {
    content: url();    
}

不占据任何空间,同时依然可以响应点击行为,能够被屏幕阅读器等设备识别。

好,以上就是本文的全部内容,带大家了解了下 content 属性新的行为表现。

如果本文的内容对您的学习有所帮助,欢迎转发,欢迎分享。

2764.svg

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK