How to Get The Scale Percentage of an Image When Using Background-Size:Cover

How to get the scale percentage of an image when using background-size:cover?

If we suppose your image has a dimension of WxH and the screen size is AxB then it should be the biggest value between A/W and B/H.

Some examples:

.box {  width:400px;  height:200px;  background:url(https://picsum.photos/300/300?image=0) center/cover;}/*we will have 1.333 = 400/300 and 0.6667 = 200/300*/img { transform:scale(1.3333); transform-origin:top left;}
<div class="box">
</div><img src="https://picsum.photos/300/300?image=0">

How is background-size percentage calculated?

As per the W3C Specs:

A percentage is relative to the background positioning area.

and background positioning area is one of either border-box or padding-box or content-box based on the background-origin property. Here you haven't specified any value explicitly for this and so its default value of padding-box is used. This element has no padding and so it's equal to content-box.


Your image is 126 x 112 px but width and height of the element is 56 x 56px, so a background-size: 100% (which is inferred as100% auto) would mean the image is scaled down till it has a width of 56px. Now to get to 56px, the width is scaled down by 44.44% of the image's original size. So, to preserve aspect ratio (as one value is auto), the height of the image is also scaled down to 44.44%, which is, 49.78px (or 50px approximately). As you can see the calculated background image's dimensions are 56px x 50px (and not 56px x 56px) and so it doesn't cover the box entirely. You can see this clearly in the below snippet.

.test {  background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;  width: 56px;  height: 56px;  border: 1px solid red;  background-size: 56px 50px; /* see how this is same as 100% or 100% auto */}
.test.t2 { width: 56px; height: 56px; background-size: 100%;}
.test.t3 { width: 56px; height: 56px; background-size: 100% auto;}
<div class="test"></div><div class="test t2"></div><div class="test t3"></div>

css3 background-size cover to percentage animation zoom

One posibility is to have the background set in a pseudo element, and then do the zoom in the base element. (thru transform property, for instance)

.test { 
width: 300px;
height: 300px;
position: relative;
left: 30px;
top: 30px;
transition: all 1s;
}

.test:hover {
-webkit-transform: scale(1.05, 1.05);
transform: scale(1.05, 1.05);
}

.test:after {
content: '';
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
background: url("http://lorempixel.com/600/400");
background-size: cover;
}
<div class="test">
</div>

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.

jQuery - background-size: cover + some percentage

A pseudo element would be prefect for this, so you can keep the existing markup.

Combine it with transform and you get this

div.image {  height: 300px;  width: 50%;  display: table-cell;  vertical-align: middle;  padding: 24px;  box-sizing: border-box;  overflow: hidden;  position: relative;}div.image::before {  content: '';  position: absolute;  left: 0; top: 0;  height: 100%;  width: 100%;  background-image: inherit;  background-size: cover;  background-position: center;  background-repeat: no-repeat;  transition: transform 0.2s;}
div.image:hover::before { transform: scale(1.25); /* 25% increase */}div.text { position: relative; /* so text stay ontop of image */}
<div class="image" style="background-image: url(http://lorempixel.com/200/200/nature/1/)">  <div class="text">    <p class="title">TITLE</p>    <p class="subtitle">SUBTITLE</p>  </div></div>

How to scale a background image to cover, times an extra scaling factor?

I have created a Fiddle for you to check out. I believe I understood the question correctly but please let me know if I am off base.

I wrapped the div that has the background-image in another div like so:

<div class="hero-container">
<div class="row" id="hero"></div>
</div>

and applied the styles like so:

.hero-container {
overflow: hidden;
width: 100%;
height: 100vh;
}
#hero {
background: url('https://i.ytimg.com/vi/ReF6iQ7M5_A/maxresdefault.jpg') no-repeat center center scroll;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
position: relative;
width: 100%;
height: 110vh;
margin-bottom: 0px;
right: 0;
}

Play around with the fiddle by changing the height: 110vh and let me know if this is what you were looking for, or if I am at least on the right track.

Hope this helps!

EDIT*: I removed the transition and the padding as these are not necessary.

If you would like to do this with a container that has a fixed height you can change the .hero-container height to 500px or something and then just use 110% instead of 110vh in the height for the #hero div.

What's the math behind CSS's background-size:cover

Here's a logic behind cover calculations.

You have four base values :

imgWidth // your original img width
imgHeight

containerWidth // your container width (here 698px)
containerHeight

Two ratios derived from these values :

imgRatio = (imgHeight / imgWidth)       // original img ratio
containerRatio = (containerHeight / containerWidth) // container ratio

You want to find two new values :

finalWidth // the scaled img width
finalHeight

So :

if (containerRatio > imgRatio) 
{
finalHeight = containerHeight
finalWidth = (containerHeight / imgRatio)
}
else
{
finalWidth = containerWidth
finalHeight = (containerWidth / imgRatio)
}

... and you have the equivalent of a background-size : cover.

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.



Related Topics



Leave a reply



Submit