前言
之前我写过一篇开发笔记
图片比例缩放且不超出范围
里面使用了object-fit的contain,现在我来总结一下相关的理论。
object以及替换元素
object
object-fit和object-position里面都出现了object,这个object是什么呢?多方了解(MDN),其实这个object是指的替换元素(Replaced element)
MDN
object-fit
object-position
替换元素(Replaced element)
同样给个MDN Replaced element
替换元素(Replaced element)其内容不受CSS视觉格式化模型控制的元素,比如image,嵌入的文档(iframe之类)或者applet,叫做替换元素。比如,img元素的内容通常会被其src属性指定的图像替换掉。替换元素通常有其固有的尺寸:一个固有的宽度,一个固有的高度和一个固有的比率。比如一幅位图有固有用绝对单位指定的宽度和高度,从而也有固有的宽高比率。另一方面,其他文档也可能没有固有的尺寸,比如一个空白的html文档。
CSS渲染模型不考虑替换元素内容的渲染。这些替换元素的展现独立于CSS。object,video,textarea,input也是替换元素,audio和canvas在某些特定情形下为替换元素。使用CSS的content属性插入的对象是匿名替换元素。
object-fit和object-position出现的理由
一个东西总要有它的应用场景吧? 从个人而言我遇到过两种情况需要使用这个属性。
固定大小的容器保持图片比例
这个其实就是我之前博客里面写的图片比例缩放且不超出范围
下面是未做处理的情况。
由于这个卡片上面的图片是用户上传的,其宽高和比例不确定,而需求要求是图片必须按比例缩放,不能像上面的原始图一样直接拉伸。尽管我当时不是使用的object-fit来实现的,但它也适用于使用object-fit的情况。
富文本显示
之前显示富文本的时候由于忘记做处理,大图会直接溢出
然后我使用了object-fit: contain;(当然不止这一句)
不过这样之后有个问题,就是我以前那些小图也被扩大到最大了,这就尴尬了。
不过改成object-fit: scale-down 就没这个问题了。
//示意写法
img {
object-fit: scale-down;
height: 100%;
width: 100%;
}
不过这样还是有个缺点就是本来图片后面跟着文字的,直接挤到下一行去了,不过也是这样的我也不管了(逃)
object-fit
下面正式介绍两个属性了
首先是object-fit
可选的值有
/* Keyword values */
object-fit: fill;
object-fit: contain;
object-fit: cover;
object-fit: none;
object-fit: scale-down;
/* Global values */
object-fit: inherit;
object-fit: initial;
object-fit: unset;
解释如下
- fill: 默认值。替换内容拉伸填满整个content box, 不保证保持原有的比例。
- contain: 保持原有尺寸比例。保证替换内容尺寸一定可以在容器里面放得下。因此,此参数可能会在容器内留下空白。
- cover: 保持原有尺寸比例。保证替换内容尺寸一定大于容器尺寸,宽度和高度至少有一个和容器一致。因此,此参数可能会让替换内容(如图片)部分区域不可见。相当于是你有一个100100的容器,但放了个100200的图片,那么它会显示成200*200。
- none: 保持原有尺寸比例。同时保持替换内容原始尺寸大小。
- scale-down: 可以参考我上面说的第二个例子,就好像依次设置了none或contain, 最终呈现的是尺寸比较小的那个。
注意 img上都是{ width: 100%; height: 100%; }
为什么我设置了width和height但除了fill之外都无视了
img是个元素,且是个替换元素,这个通过上面的学习应该都知道;
一个图片,如果没有src,它依然是个替换元素,它在浏览器中的解析依然是正确的;
src
指向的图片属于替换内容,注意,这个替换内容和这个img替换元素是壳子与内容的关系,两者是独立的。在CSS2.1时代,壳子的实际尺寸(如果没有CSS或HTML设置),则是跟随内容的实际尺寸,因此,网页加载的时候,我们会看到图片占据的高度从0到图片实际高度跳动的过程;如果壳子,也就是img有尺寸限制,则替换内容fill拉伸适应于 img替换元素的设定尺寸。总而言之,壳子与内容的尺寸永远是一样的。于是,我们就会误认为图片就是那个图片,唯一的存在,导致我们理解object-fit的特性表现出现了障碍。在CSS3时代,object-fit的世界里,object-fit控制的永远是替换内容的尺寸表现,注意,是替换内容的尺寸表现,不是img替换元素。或者这么讲吧,我们对img设置:
.box > img { width: 100%; height: 100%; }
实际上是控制img这个元素的,这个壳子的尺寸是100%撑满容器。上面截图的5个示例的图片实际上都是100%拉伸与容器的;之所以实际的图片内容没有拉伸,是因为受object-fit控制,object-fit控制了src对应的替换内容的尺寸,或者包含,或者覆盖。
object-position
这个就简单多了
/* values */
object-position: 100px 50px;
/* Global values */
object-position: inherit;
object-position: initial;
object-position: unset;
position可以填很多比如left top right bottom还有百分比等等,用来控制替换元素位置的。
下次
明天做一下CSS视觉化模型的总结吧