Obtaining the calculated background style on Firefox

Back when my userscript was only functional on Chrome, I had a setup where I could copy the entire background (which could be anything from an image to a color) from one element to another. This is how it looked:

$(target).css('background', $(source).css('background'));

This method worked flawlessly on Chrome in all scenarios because Chrome would consider all background-related styles when computing the background property. However, now that I am expanding compatibility to Firefox, this approach no longer functions as expected; Firefox does not seem to compute background based on other background-related styles.

Let's examine the following example:

let test = $('#test');
let style = test[0].style;
let comp = window.getComputedStyle(test[0]);
let output = '';

output += `> ${test.css('background')}\n`;
output += `> ${style.getPropertyValue('background')}\n`;
output += `> ${comp.getPropertyValue('background')}\n`;
output += 'all background styles:\n';

for (key in comp)
  if (key.startsWith('background'))
    output += `${key} = ${comp.getPropertyValue(key)}\n`;
    
$('#output').val(output);
#test {
  background-image: url(https://cdn.sstatic.net/img/share-sprite-new.svg);
  background-position-x: 10px;
  background-position-y: -20px;
  background-color: black;
  width: 150px;
  height: 34px;
}

#output {
  width: 80ex;
  height: 30ex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test"></div>
<textarea id="output"></textarea>

Running this code on Chrome version 58 for Windows produces the following output:

> rgb(0, 0, 0) url("https://cdn.sstatic.net/img/share-sprite-new.svg") repeat scroll 10px -20px / auto padding-box border-box
> 
> rgb(0, 0, 0) url("https://cdn.sstatic.net/img/share-sprite-new.svg") repeat scroll 10px -20px / auto padding-box border-box
all background styles:
background = rgb(0, 0, 0) url("https://cdn.sstatic.net/img/share-sprite-new.svg") repeat scroll 10px -20px / auto padding-box border-box
backgroundAttachment = 
backgroundBlendMode = 
backgroundClip = 
backgroundColor = 
backgroundImage = 
backgroundOrigin = 
backgroundPosition = 
backgroundPositionX = 
backgroundPositionY = 
backgroundRepeat = 
backgroundRepeatX = 
backgroundRepeatY = 
backgroundSize = 

However, running the same code on Firefox version 53 for Windows results in:

> 
> 
> 
all background styles:
background = 
backgroundAttachment = 
background-attachment = scroll
backgroundBlendMode = 
background-blend-mode = normal
backgroundClip = 
background-clip = border-box
backgroundColor = 
background-color = rgb(0, 0, 0)
backgroundImage = 
background-image = url("https://cdn.sstatic.net/img/share-sprite-new.svg")
backgroundOrigin = 
background-origin = padding-box
backgroundPosition = 
background-position = 10px -20px
backgroundPositionX = 
background-position-x = 10px
backgroundPositionY = 
background-position-y = -20px
backgroundRepeat = 
background-repeat = repeat
backgroundSize = 
background-size = auto auto

Two main differences stand out:

  1. Firefox returns an empty string for computed background (still somehow manages to calculate background-position from its components), whereas Chrome constructs it from all other background properties, and
  2. Firefox includes background- variations of each item in the computed style with their specific values, while Chrome does not show individual values.

My query is: Is there a simple yet effective way to obtain the complete computed background of an element that works seamlessly across both Chrome and Firefox (or simply to replicate the background of one element onto another, which is my ultimate goal)? The straightforward Chrome method has become entangled due to Firefox's intricacies. jQuery can be utilized if necessary.

Answer №1

It appears that the issue here revolves around the functioning of the following code snippets:

window.getComputedStyle(...).getPropertyValue('background-image')

versus

window.getComputedStyle(...).getPropertyValue('backgroundImage')

The former, using dashes in the CSS property name, seems to work as expected while the latter, utilizing camel case in JavaScript naming convention, does not yield the desired result. This discrepancy is justified by the fact that getPropertyValue()

returns a DOMString containing the value of a specified CSS property.

Interestingly, the dashed version of the property name only seems to be returned in Firefox, thus explaining why Chrome displays only the computed shorthand value.

In my experience, I have typically accessed such values using a different method, like:

window.getComputedStyle(...)['backgroundImage']

This approach appears to work consistently across both browsers, although variations in output can still be observed due to differences in how each browser presents computed values.

The code snippet below demonstrates the output differences between Firefox and Chrome, showcasing both dasherized and camelized variants:

getPropertyName(...) to access notation brackets like [...])

// Inserted JavaScript code goes here
/* Inserted CSS code goes here */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test"></div>
<textarea id="output"></textarea>

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

Combine the promises from multiple Promise.all calls by chaining them together using the array returned from

I've embarked on creating my very own blogging platform using node. The code I currently have in place performs the following tasks: It scans through various folders to read `.md` files, where each folder corresponds to a top-level category. The dat ...

Before I press enter, what kind of function is evaluated by the Node.JS REPL?

It's interesting how in the Node.JS REPL, the result of the current expression sometimes gets evaluated before hitting enter, which raises questions. I find it puzzling: How does Node.JS determine if I intended to evaluate it or not? Simple calculati ...

The JQuery mobile navigation menu effortlessly appears on your screen

I am experiencing an issue with a JQuery mobile navigation that is designed for screens @979 pixels wide. The problem arises when the screen is resized to 979px - the menu pops up fully extended and covers the content of the web page. I suspect that this ...

Button with a Jquery icon design

Hello, I am currently working on implementing an icon button that can collapse and expand text. Although I have successfully implemented the logic for collapsing/expanding, I am facing difficulties in creating the actual icon button. The theme I am require ...

execute various scripts in content_scripts depending on the "matches" provided

I am new to JavaScript and currently working on customizing the script from the MDN tutorial, Your First WebExtension My goal is to draw either a red or blue box around a webpage based on whether it is http:// or https://. But I have encountered a proble ...

What is the correct way to integrate $.deferred with non-observable functions?

Imagine you have two functions filled with random code and the time they take to complete is unknown, depending on the user's system speed. In this scenario, using setTimeout to fire function2 only after function1 finishes is not practical. How can j ...

Troubleshooting: Jquery ajax request not functioning on Android emulator

Attempting to call a webservice using jQuery ajax. Utilizing jsonp as a datatype to address cross domain issues. All browsers are functioning properly. Tested on different domains and receiving valid responses. However, encountering failures when trying t ...

Setting the height of an element based on the height of its background image

Hey there! I'm currently working with this component in my app, and right now, the height of the ButtonBase element is fixed. I fetch an image from the backend and use it as a backgroundImage for the ImageImagine component. I want to dynamically adjus ...

Guide to adding an image with feathers.js and multer:

I am currently working on integrating feathers.js with React for my project and I am facing an issue with uploading images. I have tried using multer and busboy for handling the upload, but I am unable to successfully upload the image or access it through ...

A dynamic jQuery plugin that replicates the smooth page sliding animation found in iPhone apps

Currently, I am in search of a jQuery plugin that has the capability to navigate users to different pages on a website with a sleek sliding animation, similar to what we see in some widely used iPhone apps. Despite my best efforts to create this functional ...

Confirming the structure of a URL using JavaScript/jQuery

I have a text field where users input URLs. I need to validate the format of the URL using regular expressions. Specifically, I am looking for invalid URLs such as: http://www.google.com//test/index.html //Invalid due to double slash after hostname http: ...

What is the best way to transfer information to a different NextJS page?

I want to implement a search input field. The idea is to allow the user to type something into the search bar and then send that input to another page where an API request will be made with the search content. Essentially, when the user types "something" ...

Tips for adding a CSS marker to the Videogular timeline at a designated time

My HTML player application allows users to search for a term and then displays the results along with the time when those words appear. By clicking on a specific sentence, the HTML player will start playing from that location. However, I would like to enha ...

Learning about the intricacies of backend Node.js through Angular using GET requests

I am having trouble retrieving the query parameters from a frontend GET request on the backend side. I have attempted to use url and query, but still need assistance fetching the query on the nodejs side. Can someone recommend a method that would allow me ...

Using Jquery to switch between different CSS styles

I'm currently working with a jQuery code that is functioning properly. $(window).load(function() { $('.menuBtn').click(function(e) { e.preventDefault(); (this.classList.contains('is-active') === true) ? this.c ...

Retrieving over 300,000 rows from elasticsearch and saving them as a .csv document

Hi there, I am currently working on a website in nodejs that utilizes an Elasticsearch database. One of my indexes, 'bigData*', contains 366,844 rows with each row consisting of 25 items, each being a different string of varying sizes (with a max ...

Guide on displaying an X mark on a checkbox in AngularJS when the ng-disabled value is set to true

Is there a way to display an X mark in red on checkboxes when the ng-disabled condition is evaluated as true? I am a beginner in Angular.js and would appreciate any assistance. Here is what I have attempted so far: if (module.Name === 'val1' || ...

Retrieve JSON data using AngularJS

Can someone guide me on how to make a GET request to my API endpoint and handle the JSON response in my code? Sample Controller.js Code: oknok.controller('listagemController', function ($scope, $http) { $scope.init = function () { ...

A guide to sorting an object with integer keys by its values using JavaScript

I am facing an issue with sorting a map by values instead of keys. No matter what I do, it always ends up getting sorted by the keys. On the server side, I have a map that is already sorted. When I send this map to JavaScript using JSON, it gets re-ordere ...

Achieving unique horizontal and vertical spacing in Material UI Grid

In my current Material UI setup, I have set spacing in the Grid Container to space Grid Items vertically. While this works well on larger screens, it causes awkward horizontal spacing between Grid Items on mobile devices. <Grid container spacing={24}> ...