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

When using Material UI, it is not possible to apply the text-overflow: ellipsis and overflow: hidden properties to multiple

I am new to material UI and here is the current state of my website: view reality of current website This is what I am expecting it to be: what I envision it becoming From the images above, you can see that I want the text inside the circle to be shorten ...

mention the element to display on the pagination

I find the logic here quite puzzling. This particular code block seems to be related to pagination, as it involves a function that is triggered upon clicking. componentDidUpdate() { const { location } = this.context; const { query } = this; if ...

How can I prevent the browser's back button from functioning on an AngularJS webpage?

Is there a way to disable the browser's back button and refresh button in Angular? For example, in my source code: Page Source: "use strict"; .controller("wizardSecondController", function($scope, $state, $stateParams, wizardManager) { $scope.$on ...

Invalid sequencing of Nest.js async onModuleInit causing issues

I am dealing with a scenario where ServiceA relies on RedisService. In order for ServiceA to be fully operational, it must wait for RedisService to complete its initialization process (specifically, for RedisService.onModuleInit to be called and awaited). ...

Dividing a string in JavaScript to generate fresh arrays

I am currently dealing with the following string: "ITEM1","ITEM2","ITEM3","ITEM4","ITEM5","ITEM6","ITEM7"~100000000,1000048,0010041,1,1,1,1~100000001,1000050,,2,0,2,1~100000002,1068832,0 ...

How to retrieve client's hostname using Node and Express

How can the client's hostname be retrieved in a Node / Express server? Is there a method similar to req.connection.remoteAddress that can be used to obtain the client's hostname? ...

Unable to invoke the 'apply' method on an undefined object when configuring directions for the jQuery Google Maps plugin

I've gone through the steps in a tutorial to create a jquery mobile google map canvas here, and have attempted to set it up. However, I keep encountering this error in my JavaScript console: Uncaught TypeError: Cannot call method 'apply' ...

Tips for utilizing the jquery columnize plugin in conjunction with AngularJs

I am looking to utilize the columnize plugin from jQuery to create columns in my AngularJS application. Initially, I attempted the following straightforward approach: .directive('columnize', function() { return { restrict: 'A&ap ...

Guide to vertically aligning text in an overlay using CSS within Angular 2

I currently have an overlay on my page that displays a spinner (an Angular material component) and accompanying text. This overlay covers the entire page and prevents clicking on elements below it. The spinner is positioned in the center of the page, and ...

preventing a button from triggering the same event repeatedly

Currently, I am using a script that adds a new row after the tr where my button is located. Unfortunately, I do not want the same button to generate more than one tr. Here is the script in question: <script> $(function() { var done; $(' ...

Explore the possibilities of using a unique custom theme with next.js, less, and ant design

Trying to customize the default theme in antdesign has been a challenge for me. I've switched from sass to less, but there seems to be something that just won't work. I've exhaustively searched online for solutions - from official nextjs ex ...

VueJs Axios - Managing Request Headers

Edit: Is it possible that this is a CORS issue, considering I am on localhost... When using Javascript, I have the ability to define request headers and handle responses like this: $(function() { var params = { // Request parameters } ...

Can the PHP stylesheet import be configured to exclude a specific string?

Can I import a PHP stylesheet named style.php into my HTML document? Is there a way to delete certain strings from style.php, such as <style> tags, before importing it using traditional methods like <link>? ...

Trouble with z-index functionality in jQuery datatable

I'm struggling to get the Action Box displayed as an upper layer. I've already tried using z-index but it doesn't seem to make any difference. https://i.stack.imgur.com/rJ1vL.png $(document).ready(function () { ...

The issue of banding caused by Bloom and Antialiasing in Three.js rendering

I'm attempting to incorporate a glowing effect into my scene. To achieve this, I understand that using a bloom filter with the EffectComposer is the ideal approach. However, I've encountered an issue where utilizing the EffectComposer compromises ...

Ways to switch out error message for an error landing page

I am currently displaying error text when something goes wrong, but I would like to enhance the user experience by redirecting to a well-designed error page instead. Can anyone provide guidance on how to achieve this? Below is my existing code for display ...

Creating a Javascript function to perform a specific action based on the selected

I am facing some challenges with my webshop project and I would appreciate any help. The main issue I'm dealing with is setting up a select box that allows customers to choose different colors of a product. When a color is selected from the dropdown, ...

Issue with background image resizing when touched on mobile Chrome due to background-size property set to cover

My current challenge involves setting a background image for a mobile page using a new image specifically designed for mobile devices. The image is set with the property background-size: cover, and it works perfectly on all platforms except for mobile Chro ...

NextJs only displays loading animation once

Currently, I am developing an app using Next.js and I am facing a challenge with implementing a loading animation. The animation I am attempting to incorporate consists of three bouncing balls which display correctly. When I launch the Next.js app with n ...

"Guide to terminating an AWS Batch job that is in a RUNNABLE state using the JavaScript SDK

I need assistance with canceling a job stuck in runnable status on AWS Batch using the JavaScript SDK. Which API option should I choose? 1. The TerminateJobCommand documentation states that it terminates jobs in the STARTING or RUNNING state, causing them ...