Get the Size of a CSS Background Image Using JavaScript?
Yes, and I'd do it like this...
window.onload = function () {
var imageSrc = document
.getElementById('hello')
.style.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2')
.split(',')[0];
// I just broke it up on newlines for readability
var image = new Image();
image.src = imageSrc;
image.onload = function () {
var width = image.width,
height = image.height;
alert('width =' + width + ', height = ' + height);
};
};
Some notes...
- We need to remove the
url()
part that JavaScript returns to get the proper image source. We need to split on,
in case the element has multiple background images. - We make a new
Image
object and set itssrc
to the new image. - We can then read the width & height.
jQuery would probably a lot less of a headache to get going.
Can I get background-image source's size by javascript?
If you want to get the actual width and height of a background image then you can follow these steps
Get the background image's URL like this (https://stackoverflow.com/a/45010803/1391805)
var css = document.getElementById("myElem").style.backgroundImage;
var img = css.replace(/(?:^url\(["']?|["']?\)$)/g, "");
Once you have the image URL do this
var newImg = new Image();
newImg.onload = function(e) {
console.log( this.naturalWidth ); // This is the width you are looking for
console.log( this.naturalHeight ); // .. similarly the height.
}
newImg.src = "img.jpg";
Given the fact that this loads an image first you may want to use this carefully, if this is something that does not apply for a lot of images on a single page then this may not be a performance degrade but if the scale is larger then you may consider something better than loading an image on the client side to fetch its actual dimension.
Getting dimensions of background-image
The issue is that some browsers add quotes to the CSS, and it was trying to load (in the fiddle's case) "http://fiddle.jshell.net/_display/%22http://placehold.it/200x300%22". I've updated your .replace() to look for " as well, and a fiddle is at http://jsfiddle.net/4uMEq/
$('#test').on('click', function () {
$(this).text(getDimensions($(this)));
});
var getDimensions = function (item) {
var img = new Image();
img.src = item.css('background-image').replace(/url\(|\)$|"/ig, '');
return img.width + ' ' + img.height;
};
Getting the height of a background image resized using background-size: contain
The key is to use the static image's dimensions, calculate the aspect ratio of the image, and then use the actual element's dimensions to figure out the computed dimensions of the resized image.
For instance, lets assume you had the following:
html, body { height:100%; }
body {
background-image: url('http://placehold.it/50x100');
background-repeat: no-repeat;
background-size: 100% auto;
}
The static image's dimensions are 50x100
, and it is sized to take up a width of 100%
of the body element. Therefore the body
element's width would be equal to the resized image's width. If you wanted to calculate the resized height of the image, you would just use the image's aspect ratio. In this case, the image's resized height would be 800px
, because (400*100)/50 = 800
EXAMPLE HERE
var img = new Image();
img.src = $('body').css('background-image').replace(/url\(|\)$/ig, "");
$(window).on("resize", function () {
$('body').height($('body').width() * img.height / img.width);
}).resize();
Pure JS approach: EXAMPLE HERE
var img = new Image();
img.src = window.getComputedStyle(document.body).getPropertyValue("background-image").replace(/url\(|\)$/ig, "");
function resize(){
var bgHeight = document.body.offsetWidth * img.height / img.width;
document.body.style.height = bgHeight + 'px';
}
window.onresize = resize; resize();
The pure JS method is going to be the fastest, as demonstrated by this jsPerf example.
How to get the current, real , background image size, when background-size is cover?
I found the solution by myself. Here is a nice jsfiddle visualization, where we calculate the container size and the actual background image size separately.
You can resize the image container (red border) by dragging it from the bottom right corner and see how the container size changes separately from the actual background size: https://jsfiddle.net/ahvonenj/o76k5jbx/
$(document).ready(function()
{
var fullhdWidth = 1920;
var fullhdHeight = 1080;
var fullhdRatio = fullhdWidth / fullhdHeight; // About 1.7
$('#wrapper').resize(function()
{
var containerWidth = $(this).width();
var containerHeight = $(this).height();
var containerRatio = containerWidth / containerHeight;
var realWidth = null;
var realHeight = null;
console.log(containerWidth, containerHeight, containerRatio);
if(containerRatio > fullhdRatio)
{
realWidth = containerWidth;
realHeight = containerWidth/fullhdRatio;
}
else
{
realWidth = containerHeight*fullhdRatio;
realHeight = containerHeight;
}
});
});
Note: I am using this small library to detect size changes on the container div element, as jQuery's resize handler can only be bound to window object.
Background Size: Contain, get Size after scale
CSS property background-size: contain;
scales the image to the largest so that both the height and width will fit inside, retaining the same aspect ratio of course.
Just like @Teemu said, A background image is a kinda pseudo element which you actually can't refer. But I can show you a workaround on how to get the real image size and compute the scaled background-image size.
It works like ratio and proportion where:
real_image_width is to real_image_height as resized_image_width is to resized_image_height
First we need to get the real size of the image:
var img = new Image;
img.src = $('#imageButton').css('background-image').replace(/url\(|\)$/ig, "");
var imgW = img.width;
var imgH = img.height;
Then, compare which dimension is the largest and calculate the proportion:
var newW, newH;
if(imgW > imgH){
newW = $('#imageButton').width(); //100;
newH = imgH / imgW * newW;
}else{
newH = $('#imageButton').height(); //100
newW = imgW / imgH * newH;
}
console.log(newW+':'+newH);
If the image is not yet loaded or cached it will return a size of 0, a good way to fix this is to get the size when the image is has been loaded using .load()
function.
Browsers also differ in sub-pixel rendering, I think you need to round off to nearest .5 decimal to get the exact safest value (43.7832 => 43.5). Using: (Math.round(value * 2) / 2).toFixed(1)
That's it! Here is the sample fiddle.
Related Topics
Get the Scale Value of an Element
Count Down Timer with Circular Progress Bar
How to Concatenate and Minify Multiple CSS and JavaScript Files with Grunt.Js (0.3.X)
How to Make Changeable Themes Using CSS and JavaScript
How to Dynamically Modify <Select> in Materialize CSS Framework
Generate Dynamic CSS Based on Variables Angular
Can Jquery Change CSS Style Definition? (Not Individual CSS of Each Element)
Toggle Visibility Property of Div
How to Check If an External (Cross-Domain) CSS File Is Loaded Using JavaScript
Google Seo and Hidden Elements
Changing Background Based on Time of Day (Using JavaScript)
Polymer Share Styles Across Elements
Serving Gzipped CSS and JavaScript from Amazon Cloudfront via S3
Screen Styling When Virtual Keyboard Is Active
Can You Have a JavaScript Hook Trigger After a Dom Element's Style Object Changes
How to Animate a Progressive Drawing of Svg Path