2

So, I have an art website, with each work getting its own page. The works are mostly photos, meaning they have higher resolutions than most screens are capable of displaying - so they need to be resized down to scale, obviously.

To make works easier to look through, I display them such that they take up most of the screen (minus 100px in either dimension), scaling to fill whichever dimension is more limiting:

  • Work X is square-shaped, and on the average monitor it gets resized so that its height fills the entire vertical space, and its width scales accordingly - preserving the aspect ratio
  • Work Y is tapestry-shaped, and gets resized so that its width fills the entire horizontal space, and its vertical space gets resized to match that aspect ratio.

I'm currently using a straightforward Javascript script for this, calling a function on the img tag's onload (as well as whenever the window is resized) to calculate the desired width/height of the image and apply that. The problem with using Javascript for this is that there's a delay between when the image begins to load and when it resizes, which makes the page look really ugly for a while, especially when viewing the site on a poor internet connection.

Leading to my question: is there a way to resize images to a certain percentage of screen size, while preserving aspect ratio, in pure CSS?

This answer provides another Javascript solution, but I'd prefer to find a way to do this in pure CSS if possible.


My current script is this:

function setGoodHeight (element) {
    if( on mobile ) {
        ...
    }
    else {
        height_buffer = 100
        width_buffer = 100
        height_diff_pct = element.naturalHeight / window.innerHeight
        width_diff_pct = element.naturalWidth / window.innerWidth
        if(height_diff_pct > width_diff_pct) {
            var h = element.naturalHeight;
            var w = element.naturalWidth;
            element.height = window.innerHeight - height_buffer;
            element.width = w * element.height / h;
        }
        else {
            var h = element.naturalHeight;
            var w = element.naturalWidth;
            element.width = window.innerWidth - width_buffer;
            element.height = h * element.width / w;
        }
        if(element.width < 540) {
            element.parentNode.setAttribute("style","width:" + 540 + "px");
        }
        else {
            element.parentNode.setAttribute("style","width:" + (element.width + 40) + "px");
        }
    }
}
6
  • did you try to get the screem size, then set the photo to that size? Commented May 8, 2019 at 16:28
  • Yeah, essentially my script gets window.innerWidth and window.innerHeight, computes ratio between image width/height with window width/hight and takes whichever ratio is smaller, then adjusts the entire image to that. Commented May 8, 2019 at 16:37
  • Have you tried using the vw and vh units in CSS? 100vw = 100% of browser viewport width. Using height: auto; also preserves the aspect ratio. Commented May 8, 2019 at 16:42
  • Post the HTML and code you currently have. Commented May 8, 2019 at 16:54
  • I have posted the javascript code. The HTML is literally just an img tag, in this case. Commented May 8, 2019 at 16:57

4 Answers 4

3

Using the vw and vh units in CSS allow you to size things based on the browser viewport rather than parent elements.

If you set the max-width and max-height for the image it should constrain the image to be no bigger than the browser viewport size for any browser size.

#image-id {
    max-width: 80vw;
    max-height: 80vh;
}
Sign up to request clarification or add additional context in comments.

Comments

1

Tell your images to be at most 100% width of the container they are in, and height set to auto will maintain aspect ratio.

.my-image-class {
  max-width: 100%;
  height: auto;
}

2 Comments

By my understanding, if the container was the width of the screen here, then an image could be resized to be larger than the screen - whereas I would want it to scale based on height if that was the case
@GreenCloakGuy There is no HTML markup provided. The immediate container around the images should be set to the desired width. The code I provided is simple and effective to have the images conform.
0

How about using background-size: cover; for this? Every image can be the background of a div, which in turn has the following properties set.

  1. height
  2. width
  3. background-size: cover;
  4. background: url('img.png') center center no-repeat;

2 Comments

Is there a way to provide the url at runtime through the html? I have a templated .html page (so I fill the image source in when I serve the page) but a static css document, and filling this all in in the style attribute didn't work.
Also when I tested this it didn't seem to do what I wanted. Horizontal scaling worked but vertical scaling didn't, and also the image didn't scale, it just got cut off.
0

JavaScript is the best answer but if you really want to only use css you can use percentages rather then px these will scale to a given container.

.img {
max-width:100%;  
max-height:100%;

}

here is a similar question and answer: StackPost

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.