Expanding background images smoothly during transition with varying image dimensions

I am looking for a way to have my background-image transition smoothly, even when it has a different aspect ratio predecessor. Below is an example demonstrating this stretching effect.

toggle = true

jQuery(document).ready(function() {
  jQuery(".button").on("click", function() {
    if (toggle) {
      jQuery(".test").css("background-image", "url('https://images.pexels.com/photos/4534200/pexels-photo-4534200.jpeg?cs=srgb&dl=pexels-arthouse-studio-4534200.jpg&fm=jpg')")
      toggle = false
    } else {
      jQuery(".test").css("background-image", "url('https://images.unsplash.com/photo-1547922374-968968e3f658?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=bosco-shots-SlR66yjPsoI-unsplash.jpg')")
      toggle = true
    }
  })
})
* {
  margin: 0;
  padding: 0;
}

.test {
  width: 100vw;
  height: 100vh;
  background-image: url('https://images.unsplash.com/photo-1547922374-968968e3f658?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=bosco-shots-SlR66yjPsoI-unsplash.jpg');
  transition: background-image 0.5s;
  -webkit-transition: background-image 0.5s;
  -o-transition: background-image 0.5s;
  -moz-transition: background-image 0.5s;
  -ms-transition: background-image 0.5s;
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
}

.button {
  padding: 2px;
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<div class="test">
  <input class="button" type="button" value="change">
</div>

If there is an option available that allows me to still use background-size: cover; and achieve a smooth background-image transition, I would greatly appreciate it.

Answer №1

Instead of switching the background image on and off, you can utilize multiple elements with different backgrounds and display the active element based on an index.

The remainder operator (%) for the (active) index ensures that we always have a valid index within the range of backgrounds available.

let active = 0; // Initial active element

jQuery(document).ready(function($) {
  $(".button").on("click", function() {
    // Update active index
    active = (active + 1) % $(".bg").length;
    
    // Display active background
    $(".bg").each(function(index) {
      if(index === active) {
        $(this).addClass("bg-active");
      }else{
        $(this).removeClass("bg-active");
      }
    });
  })
})
* {
  margin: 0;
  padding: 0;
}

.test {
  width: 100vw;
  height: 100vh;
  position: relative;
}

.test > * {
  position: relative; /* Ensure elements inside `.test` remain visible */
}

.bg {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  opacity: 0;
  transition: opacity 0.5s;
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
}

.bg-nature {
  background-image: url('https://images.pexels.com/photos/4534200/pexels-photo-4534200.jpeg?cs=srgb&dl=pexels-arthouse-studio-4534200.jpg&fm=jpg');
}

.bg-art {
  background-image: url('https://images.unsplash.com/photo-1547922374-968968e3f658?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=bosco-shots-SlR66yjPsoI-unsplash.jpg');
}

.bg-active {
  opacity: 1;
}

.button {
  padding: 2px;
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<div class="test">
  <div class="bg bg-nature bg-active"></div>
  <div class="bg bg-art"></div>

  <input class="button" type="button" value="change">
</div>

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

Setting the initial state for your ngrx store application is a crucial step in ensuring the

I'm completely new to ngrx and I'm currently exploring how to handle state management with it. In my application, each staff member (agent) is associated with a group of customers. I'm struggling to define the initial state for each agent ob ...

Nightwatch failing to locate element within iFrame

I'm currently facing a challenge when trying to access an element within an iframe. Despite successfully switching to the frame, Nightwatch keeps returning "element not found" whenever I attempt to verify its presence or visibility. Below is a snippe ...

Issue: The type 'void' cannot be assigned to the type 'ReactNode' in the array.map() function

Having trouble with my function call error within the practice setup in App.tsx. My expectation of array.map() being compatible with TypeScript seems to be incorrect. The generated HTMLElement from this map is not displaying on screen. Any suggestions on ...

Limiting image size in react-dropzone

I am currently utilizing react-dropzone for image uploads within my application. The functionality is working smoothly, including the validation for image size. However, I am facing an issue with checking the dimensions of the uploaded image. I am looking ...

In Vue, the CropperJs image initially appears small, but it returns to its original size after editing

I encountered a peculiar issue while working on a website for image cropping using Vue.js and CropperJs. On the homepage, users can select an image to crop and proceed to the next page where a component named ImageCropper.vue is displayed. Strangely, the c ...

When using a React Router path variable along with other paths, React may have difficulty distinguishing between them

Setting up react router in my project to differentiate between user username variables and other paths is proving challenging. For instance: baseUrl/admin baseUrl/daniel Currently, React is unable to distinguish between the two. My intention is to query ...

PHP: Syntax error: unexpected empty string (T_ENCAPSED_AND_WHITESPACE)

When trying to retrieve values from a SQL database and set them as unique options for Radio buttons, I am encountering an error. I believe the issue lies in how I am passing PHP code within the value parameter. Can someone please provide guidance on how to ...

Having trouble getting the CSS Transform property to be affected by ScrollTop

Hello everyone, I am attempting to create a ball that has a 50% radius and rolls left based on the user's scroll movements. So far, I have successfully made it move left in relation to ScrollTop, but unfortunately, I cannot get the transform property ...

Tips for positioning a Div element in the center of a page with a full-page background

I am trying to center align my div containing login information on the webpage. The static values seem to work fine, but I am looking for a way to position it dynamically. Additionally, the background is only covering a strip with the height of the div... ...

Learn how to dynamically modify the text and color of a column value within a <v-data-table> component in Vue.js 2.6.11 and Vuetify 2.2.11 based on a specific condition

In my current project where I am developing a web application using ASP.NET CORE for the backend and vue.js for the frontend, I encountered an issue with Vuetify's CRUD Datatable UI Component in a page named "Category". The problem arises when trying ...

Remove an element from an array in JavaScript when a condition is met in an if/then statement

I am currently working on a function that loops through elements in an array and removes values outside of a specific range. However, I have encountered an issue where using the pop method always removes the last element in the array rather than the intend ...

Step-by-step guide on creating a login functionality in Node using the Mean.io stack

I'm currently working on a web app using the MEAN.io stack. I have completed the frontend part with HTML, CSS, and AngularJS along with some logic. Now, I am looking to implement server-side login functionality, but I'm unsure where to begin sinc ...

Revamp the HTML table with JavaScript headers

I imported data from a CSV file into an HTML table and here is how it appears: <div id="myTable" style="-ms-overflow-x: auto;"> <table> <tbody> <tr class="rownum-0"> <td>Make</td> ...

Updating state in child components from a different child component in React

How can I update the state of one child component when a button is clicked in another child component, both sharing the same parent component? import React from "react": import A from "..."; import B from "..."; class App extends React.Component { r ...

Is it possible to use export default Enum in TypeScript?

I am facing an issue with exporting an enum object as default at the top level in my code. Here is what I tried: export default enum Hashes{ FOO = 'foo', BAR = 'bar', } However, this resulted in an error message: Module parse failed ...

Using the OR operator in a JSON server

One way to retrieve data from a json-server (simulated server) is by using the following call: http://localhost:3000/posts?title_like=head&comments_like=today When this call is made, records will be returned where the title is similar to "head" AND c ...

What is the best way to navigate through images only when hovering?

I have a website that showcases a collection of images in a creative mosaic layout. Upon page load, I assign an array of image links to each image div using data attributes. This means that every image in the mosaic has an associated array of image links. ...

Trouble with installing Enmap due to better-sqlite3 error

For a while now, I've been struggling to get enmap installed. Despite searching the web exhaustively, I haven't come across any solutions that work for me. Every time I try npm i enmap, I consistently encounter this frustrating error: One part o ...

Capture the item selected from the dropdown using ng-model to retrieve the name instead of the

I need help getting the name/text/html of the selected option in a dropdown using angular.js, rather than just its value. Currently, I have this setup which retrieves the value: Here is my HTML code snippet <select class="SelectCar" ng-model="Selected ...

I'm experiencing an issue with my API where it is returning invalid JSON data when I make a POST request using

I have a scenario where I am making a post request to my Next.js API for updating an address. The code snippet below shows the function that handles fetching: async function handleSubmit() { const data = { deliveryAddress, landmark, pincode, district, bl ...