码云笔记提示:你现在浏览的网站是镜像网站

请访问原网站:www.mybj123.com
声明:码云笔记唯一指定网址为:mybj123 .com,其他网址均为冒充,望周知!!!前端技术交流群:565733884

深入剖析object-fit与object-position属性的用法

HTML/CSS 码云 22℃ 0评论

图片居中大家再熟悉不过了,老生常谈的问题,之前虽然有总结过N种方法解决居中问题,最近在学习中发现css3有两个更好的属性方法,即object-fit和object-position两个CSS属性,他们可以让我们操作img或video中的内容,类似于我们可以用background-position和background-size操作背景内容一样。

object-fit理解

object-fit只能用于『可替换元素』(replaced element)。所谓可替换元素,是指元素的内容和表现不是由CSS控制的,独立渲染的外部元素,比如:img、object、video和表单元素,如textarea、input,audio和canvas在一些特殊情况下,也可以作为可替换元素。

在使用object-fit时,一定要设定元素的size,也就是width和height

直入正题,object-fit有五个可选值,分别是:

object-fit: fill; 
object-fit: contain; 
object-fit: cover; 
object-fit: none; 
object-fit: scale-down; 

每个属性值的具体含义如下:

fill默认值。填充,可替换元素填满整个内容区域,可能会改变长宽比。

contain包含,保持长宽比,保证可替换元素完整显示,长宽比和内容区域的长宽比不一致时,内容区域会出现空白。

cover覆盖,保持长宽比,保证内容区域被填满,所以可替换元素可能会被切掉一部分,从而不能完整展示。

none顾名思义,就是什么都没有啦,当然不是什么都没有啦,而且千万不要以为和fill是一样的!实际效果是,保持可替换元素原尺寸和比例。

scale-down等比缩小。效果类似contain或none

每个属性值对应的效果图:

深入剖析object-fit与object-position属性的用法

大家可以对照示意感受下,什么是内容拉伸(fill),什么是内容全部都显示(contain),什么是容器没有留白(cover),什么是该多大就多大(none)。

scale-down由于具有动态特性,所以要专门展示下。实际的替换内容表现是none和contain最终尺寸小的那个属性值的表现。

例如,假设我们的容器可以resize拉伸,改变其尺寸,则当容器尺寸比256*191小的时候,也就是容器比替换内容(这里的图片)实际尺寸小的时候,效果跟contain一致,因为此时contain的实际展示尺寸比none小。如下截图示意:

假设我们的容器可以resize拉伸,改变其尺寸

但是,当容器尺寸拉伸到比图片实际尺寸还大的时候,则效果跟none一致,因为此时none的实际展示尺寸比contain小。如下截图:

容器尺寸拉伸到比图片实际尺寸还大的时候,则效果跟none一致

至此,我们大致了解了object-fit各个属性值的表现,你以为事情就结束了吗?不是,这只是个开始。

难道大家没有对图片的表现表示疑惑吗?

我明明图片设置了宽高都是100%,为何貌似实际效果除了(fill),似乎都无视了这些声明呢?图片的实际尺寸变小或变大了,而不是根据容器实际尺寸走呢?

.box>img{width:100%;height:100%;}

你有没有这样的疑惑?有木有!!

如果有,恭喜你,来对地方了,这表明你还没有对一些概念认识清楚。

img是个元素,且是个替换元素,这个通过上面的学习应该都知道;

一个图片,如果没有src,它依然是个替换元素,它在浏览器中的解析依然是正确的;

<img>

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-fit:contain会透明留白,是因为我们没有对壳子img设置背景色,假设我们给壳子img增加个红色背景,大家就会明白我说的意思了:

.box>img{width:100%;height:100%;background-color:#cd0000;}

效果如下截图,会发现,原来的透明留白现在是红色背景,说明了什么?说明img替换元素和src替换内容是两个独立体。img替换元素受到了CSS 100%拉伸控制(所以红色背景充满容器),src替换内容也受到了object-fit展示控制。大家各司其职,没有什么覆盖冲突!

IE浏览器并不支持object-fit

目前,IE浏览器并不支持object-fit:

浏览器支持情况

如何让object-fit兼容IE浏览器呢?

有个Github上有个polyfill,https://github.com/anselmh/object-fit大家有兴趣可以围观下。

object-position理解

object-position要比object-fit单纯的多,就是控制替换内容位置的。默认值是50%50%,也就是居中效果,所以,无论上一节object-fit值为那般,图片都是水平垂直居中的。因此,下次要实现尺寸大小不固定图片的垂直居中效果,可以试试object-fit.

与background-position类似,object-position的值类型为<position>类型值。也就是说,CSS3的相对坐标设定样式支持的。

例如替换内容一直定位在容器的右下角:

object-position: 100% 100%;

例如替换元素相对于右下角20px 10px地方定位:

object-position: right 20px bottom 10px;

上面的表现在FireFox 36浏览器下符合预期,Chrome没看明白:

object-position

因此,建议还是使用calc实现相对右下角定位:

object-position: calc(100% - 20px) calc(100% - 10px);

此时,Chrome浏览器的表现符合预期了:

Chrome浏览器的表现符合预期了

同样的,object-position也支持负值,特征表现与background-position一致。

object-position也支持负值

实例展示

通过上面所学的知识,我们利用object-position来实现一个任意数字翻转效果:

利用object-position来实现一个任意数字翻转效果

素材图片:

素材图片

CSS代码:

.num {
    width: 40px; height: 40px;
    object-fit: none;
    object-position: 0 0;
    -webkit-transition: object-position .25s;
    transition: object-position .25s;}.num0 {  }.num1 { object-position: 0 -40px; }.num2 { object-position: 0 -80px; }.num3 { object-position: 0 -120px; }.num4 { object-position: 0 -160px; }.num5 { object-position: 0 -200px; }.num6 { object-position: 0 -240px; }.num7 { object-position: 0 -280px; }.num8 { object-position: 0 -320px; }.num9 { object-position: 0 -360px; }

HTML代码:

<p><strong>显示的数字是(100~999):<input type="number" value="283" min="100" max="999"></strong></p><img src="icons-ol.png" class="num num2"><img src="icons-ol.png" class="num num8"><img src="icons-ol.png" class="num num3">

Javascript代码:

if (window.addEventListener) {
    var eleNums = document.querySelectorAll(".num");
    document.querySelector(".demo input").addEventListener("change", function() {
        var value = this.value.trim() * 1;
        if (!value || value < 100 || value > 999) { value = 283; }
        this.value = value;
        this.value.split("").forEach(function(num, index) {
            eleNums[index].className = "num num" + num;
        });
    });}

img sprites和background sprites就功能和能耗上而言,基本上是一致的。不过一个img图片,一个是img背景图片。前者兼容性有待提高。所以,目前来看,优势不明显。

以上就是码云笔记为大家带来的关于object-fit与object-position属性的用法,希望对前端开发的小伙伴有用,更多精彩敬请关注码云笔记。

转载请注明:码云笔记 » 深入剖析object-fit与object-position属性的用法

喜欢 (15)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)个小伙伴在吐槽
  1. 这两个属性不错,博主总结的也很详细,学习了 😳
    恩越2019-04-12 23:36 (6天前)回复