Can object-fit be preserved while applying a CSS transform?

Currently, I am developing a component that involves transitioning an image from a specific starting position and scale to an end position and scale in order to fill the screen. This transition is achieved through a CSS transform animation on translate and scale properties.

An issue that has arisen is that certain images being transitioned may have been altered by users of the component using the object-fit property. It seems that the CSS translate does not maintain the object-fit property during the transition.

To view a demonstration of this issue, please visit: https://codepen.io/cathyxz/pen/mXgEMB

While I could animate width and height instead, I prefer to stick with properties that browsers can animate efficiently for performance reasons. This means avoiding properties that affect layout, leaving us with only position, rotation, scale, and opacity as viable options for animation.

If you're interested in learning more about high-performance animations, check out: https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

I am seeking a solution to gradually animate the transition to "uncrop" images without stretching them. Any advice or suggestions would be greatly appreciated!

Answer №1

object-fit is implemented on the element prior to any transformation taking place.

Regardless of the effects of CSS styling on the object, transform steps in and applies the necessary changes. Interestingly, the element remains untouched in the DOM structure. This is why a repaint is not triggered by transform, making it efficient in terms of performance. The only thing that changes is its rendering (the composite layer) which is stretched 4 times along the X axis due to the transform. However, this does not alter the size of the element by fourfold, hence object-fit does not function as anticipated.


Is there a way to gradually uncrop the image? Yes, but not using transform. To achieve this in a cost-effective manner (without causing a repaint within subsequent flow), you will need:

  1. A parent placeholder (with position:relative) set to the height of the image, maintaining space in the document flow.
  2. The element being animated should have position:absolute. By doing so, even if you animate the width, layout won't be affected because the element is outside the document flow.

.transform-placeholder {
  height: 100px;
  position: relative;
}

.transform-placeholder .object-fit {
  width: 100px;
  height: 100px; 
  animation: object-fit 2.1s infinite;
  animation-timing-function: cubic-bezier(.4,0,.2,1);
  
}

@keyframes object-fit {
  0% {
    width: 100px;
  }
  50% {
    width: 400px;
  }
  100% {
    width: 100px;
  }
}
<div class="transform-placeholder">
  <div class="object-fit" style="background-image: url('https://picsum.photos/1600/400?image=857')">
  </div>
</div>

<h2>The animation above ensures no repaint occurs on any DOM elements outside of the animated div.</h2>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to enhance a tool-tip with images or legends?

Currently, I have implemented a tool-tip feature which works for a text box. However, the issue is that users are unaware of the presence of the tool-tip for the text box until they hover over it. My question is, how can I make it more obvious to users t ...

What is the best way to utilize regex for replacing a string within Node.js environment?

I'm struggling with updating the string in my code. Essentially, I have a .php file and I want to modify some constants using the replace package. The output of my current code is: // Current Output define('DB_NAME', 'foo'); // ...

Can state be controlled by both the parent and children within the same element?

I am facing a situation where I have a component that requires updating the value from its parent, but also needs to handle user input changes without having to pass them back to the parent. See this scenario in action with this example: https://codesandbo ...

The max-width CSS property is failing to function properly on a specific DIV element

I'm having trouble restricting the size of the user-selected image with CSS. Can someone point me in the right direction? Currently, when a user selects an image, it is displayed at full size which sometimes extends beyond the visible area of the web ...

Optimizing Angular's ng-repeat for efficient updates by restricting the watch functionality to the relevant iteration

My task involves creating a table where users can edit certain fields in each row, which will impact other fields within the same row. Due to this requirement, I cannot use bind-once for all the rendered data. To address this issue, I attempted using the ...

Eliminate the unnecessary code repetition in my functions using Typescript

I have 2 specific functions that manipulate arrays within an object. Instead of repeating the same code for each array, I am looking for a way to create reusable functions. Currently, my functions look like this: setLists(): void { if (this.product.ord ...

Are there other options besides Chrome Frame for enhancing Raphael performance on Internet Explorer?

Currently, I am using Raphael 2.1 to simultaneously draw 15 lines, each consisting of 50 two-pixel paths. The performance is optimal in Safari and Chrome, acceptable in Firefox, subpar in Opera, and struggles in IE9. Despite Microsoft's claim that SVG ...

Turn off automatic calling of Javascript function via the menu

Can anyone help me with calling a JS function from an action link? Here's my declaration: <li><a href="javascript:myFunc()"><span class="glyphicon glyphicon-ok"></span>&nbsp;Test</a></li> The issue is that the ...

Display a different div when hovering over an li element

Within my HTML, I have two div elements. The first div is filled with Menu items represented by li elements, while the second div contains submenus. My desired functionality involves displaying the submenu when hovering over a menu item's li element u ...

Creating a Stylish ExtJS Container with CSS: A Step-By-Step

I've been experimenting with the ExtJS properties cls, bodyCls, and componentCls but unfortunately, I'm not achieving the desired outcome. As an illustration: Ext.create('Ext.form.Panel', { renderTo: document.body, title: &apo ...

Error: Unable to locate the reference

Having trouble with my JavaScript code not recognizing the linked .js files I added. I initially linked them through CodePen, but manual references don't seem to be working. Attempted suggestions from this page Why does jQuery or a DOM method such as ...

Looking to retrieve the key value or iteration of a specific item within an Angular UI tree?

Here is a snippet of code showcasing how to use angular-ui-tree: <div ui-tree> <ol ui-tree-nodes="" ng-model="list"> <li ng-repeat="item in list" ui-tree-node> <div ui-tree-handle> {{item.title}} </div& ...

What is the best way to customize the cursor for each individual div?

Can you alter the cursor from a pointer to "not-allowed" within the div or GridList element in ReactJS or Material UI? ...

Implementing basic functionality with React Router

I am currently working on implementing React router and I have a main class named App where I need to call ExpenseApp. In order for ExpenseApp to function properly, it needs to receive some 'data'. Additionally, I want ExpenseApp to be the first ...

Replacing text within nested elements

I am facing an issue with replacing certain elements on my webpage. The element in question looks like this: <div id="product-123"> <h3>${Title}</h3> <div> ${Description} </div> <div> ${P ...

What could be causing my directive to not display my scope?

I am currently developing a directive that includes a custom controller, and I am testing the scope functionality. However, I am facing an issue where the ng-show directive is not functioning as expected when trying to test if the directive has a scope fro ...

The TypeScript function was anticipating one argument, however it received two instead

Can you help me fix the issue with my createUser() function? Why am I unable to pass parameters in Smoke.ts? Login.ts : interface User { url: string, email: string, } class Test{ async createUser(user: User) { await Page.setUrl(user.url); aw ...

How can I retrieve the value of a JavaScript variable using Ajax?

Hello everyone! I've been a long-time user of various programming forums, but this is my first time posting. Lately, I created a really simple browser-based game, and when I say simple, I mean it's incredibly basic. The whole game logic resides ...

CSS Only flyout navigation - reveal/hide with a tap or click

I want to make adjustments to a CSS-only menu that has a horizontal flyout effect triggered by hovering. I am looking to achieve the same effect on touch or tap - meaning, one tap to open the menu and another tap to close it. Is it possible to accomplish ...

Is it true that Redux Saga's select function returns mutable state?

Is the state returned by Redux Saga's select function mutable or immutable? To learn more, visit https://github.com/redux-saga/redux-saga ...