htmlcssresizeresponsivescale

Is there a CSS property that rescale any element like the object-fit: "contains" does on img?


Is there a CSS property that scale down an html element that has a fixed dimensions when the windows size is lower than the size of the content ?

In other words the content should scale down (and keep the same ratio) in order to fit in the new window size, like the property object-fit: "contain" does for replaced elements.

For now i wrote this JS code that does what i expect, but i was wondering if it can be done in html/css only ?

Also the caveats of this approach is that you may have to take in account the margins & paddings in the computation.

const CONTENT_WIDTH = 700;
const setContentScale = () => {
    const element = document.getElementById("container");
    if(element) {
        const newScale = Math.min(window.innerWidth/ CONTENT_WIDTH, 1);
        element.style.scale = newScale;
    }
}

setContentScale(); // <-- update scale on page load
window.onresize = () => setContentScale(); // <-- update scale when window is resized

UPDATE FOR THE USE CASE:

The content that is ment to be scaled down must be seen as a whole entity. Even if it is not an embeded object it can be seem like so.

The childrens of the element are math expression using the mathml tag. Also to content can be svg, but there will always be math expression inside it. After a lot o testing i came to the conclusion that the preview only makes sense if the original layout is preserved. For example "1 + 1" makes sense from the user perspective but not "1\n+\n1"


Solution

  • You can implement your JS logic using CSS but make sure to check browser support.

    Resize the below screen to see the result :

    @property --w {
      syntax: "<length>";
      inherits: true;
      initial-value: 90vw; /* the container width here (I am using the screen width for the demo */
    }
    
    .box {
      width: 600px; /* the element width */
      font-size: 20px;
      text-align: justify;
      border: 1px solid red;
      box-sizing: border-box;
      
      --s: tan(atan2(var(--w),1px)); /* uniteless value of the container width */
      scale: calc(var(--s)/600); /* container width dvided by element width */
      transform-origin: 0 0;
    }
    .box img {
      float: left;
      margin-right: 10px;
    }
    
    body {
      margin: 0;
    }
    <div class="box">
    <img src="https://picsum.photos/id/1/150/150"> 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vulputate a sem at eleifend. Nam ut hendrerit ipsum. Maecenas felis urna, suscipit a posuere ut, rutrum vitae magna. Vivamus sagittis nisl dolor, in aliquam ipsum rutrum vitae. Nam consequat faucibus neque, vel rhoncus tellus mattis et. ipsum. Maecenas felis urna, suscipit a posuere ut, rutrum vitae magna. Vivamus sagittis nisl dolor, in aliquam ipsum rutrum vitae. Nam consequat faucibus neque, vel rhoncus tellus mattis et. a posuere ut, rutrum vitae magna. Vivamus sagittis nisl dolor, in aliquam ipsum rutrum vitae. Nam consequat faucibus neque, vel rhoncus tellus mattis et. 
    </div>