1

This might have been asked before and I tried the answer given in this thread: How to get dimensions for a background image when background-size is set to contain?

But in this case, the background-size is set to cover, instead of contain.

The background size is originally 1920x1080. I have a div-element which basically always scales its width and height to 100%, meanwhile the background-image if the said div is set to cover.

1920 / 1080 gives us a ratio of about 1.7, so whenever the browser widow is scaled like so that the div's width/height ration is over or under 1.7 aka. not in the correct ratio - things break. So I need a way to calculate what is the size of the background image to correctly set things up.

Edit: Here is an example jsfiddle of the situation: https://jsfiddle.net/ahvonenj/35pbovmz/

If you resize the result area, you can see that the result area itself has some width and height, say 400x600. However, this 400 width and 600 height is incorrect for my calculations. I need to know what the size of the background image is. Notice how the background keeps its ratio by basically leaving some of the image out.

The result area width and height are only correct when the result area width/height is exactly the ratio of the background image, which is about 1.7 in this case.

Edit 2: This is now almost working: https://jsfiddle.net/ahvonenj/35pbovmz/

Swiffy
  • 4,401
  • 2
  • 23
  • 49
  • Do you need the div to stay in ratio, if so what's inside the div? Can we see some code – Pete Aug 15 '17 at 08:07
  • Would help a lot if you can provide a code example with the current "not-wanted"-state – Gerrit Halfmann Aug 15 '17 at 08:07
  • I edited my question with a jsfiddle example and an extra explanation as to what width and height values I need to get. – Swiffy Aug 15 '17 at 08:12
  • If your div is empty and you want to keep aspect ratio then you can use the [padding top trick](https://css-tricks.com/aspect-ratio-boxes/) - https://jsfiddle.net/35pbovmz/3/ – Pete Aug 15 '17 at 08:25

2 Answers2

1

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.

Swiffy
  • 4,401
  • 2
  • 23
  • 49
1

I was solving a very specific problem. I had a background image with background-size: cover and over that another element with clipping mask that was applying a filter: invert() effect.

Everything was responsive and I needed to maintain the position and size of the background on the .centered element in sync with the main background.

enter image description here

html {
  background: #000 url(bg.jpg) no-repeat center center fixed;
  background-size: cover;

  overflow: hidden;

  --w: 1920; // this is the size of my background
  --h: 1080;
}

.centered {
  background-image: url(bg.jpg);
  background-position: center center;
  background-size: calc(max(calc(100vh / var(--h)), calc(100vw / var(--w))) * var(--w));
  background-repeat: no-repeat;

  background-clip: text;
  color: transparent;
  filter: invert(100%)
}

Basically, what this does

max(calc(100vh / var(--h)), calc(100vw / var(--w)))

is that it calculates the size ratio of the cover image above its native size:

calc(100vh / var(--h)) calculates how much is the viewport higher (eg. 0.8)
calc(100vw / var(--w)) calculates how much is the viewport wider (eg. 1.2)

Then, whichever of those values is larger, this is how much larger the image MUST be to cover whole viewport.

After that, you simply take the ratio, multiply by width and you get the current "real" size. You can also get "real" height by multiplying it with the ratio.

Qwerty
  • 29,062
  • 22
  • 108
  • 136
  • more advanced live example https://stackoverflow.com/questions/10285134/whats-the-math-behind-csss-background-sizecover/66660844#66660844 – Qwerty Nov 04 '21 at 22:02