1

I'm making a responsive design and I would like that displays larger than 1920p scale proportionally with the viewport width. That would be useful for any resolution above 1920p (e.g. 4k, 8k, 16k and others between).

To make that work (partially) I had to create media queries for each resolution, but the layout breaks at some dimensions when user is not using the full display width for the browser window.

What I currently have is:

@media (min-width: 2880px) {
  body {
    zoom: 1.5;
  }
}

@media (min-width: 3840px) {
  body {
    zoom: 2;
  }
}

And what I would like to do is something like this:

@media (min-width: 1920px) {
  body {
    zoom: calc(100vw / 1920);
  }
}

This would keep the layout static for any resolution above 1920p.

Unfortunately, the calc() function parses the resulting value as px and the browser is ignoring the value because zoom property only accepts number or percentage on its value.

For example in a 3840p resolution, I was expecting to have 2 but the actual output is 2px.

Is there a way to somehow convert this output into a raw number without units?


I've created a fiddle to exemplify the issue: https://jsfiddle.net/bfaria/41rqxbs0/

In this fiddle, you can resize the output viewport to see how the zoom behaves for resolutions above 625px. Please note that if you inspect the body element you are going to see that the zoom: calc(100% * calc(100vw / 625)); declaration has this warning: Invalid property value.

1 Answers1

5

New Answer:

According to MDN, CSS Zoom is:

Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

Therefore there will be issues. Zoom currently does not seem to accept calc values as options (exact reason is unclear, maybe multiple).

However, as stated on MDN:

transform: scale() should be used instead of this property, if possible. However, unlike CSS Transforms, zoom affects the layout size of the element.

So, you should be using transform: scale(); instead of zoom. But transform scale only accepts a unitless number; 1 = 100% zoom level.

What you're trying to achieve can't be done in CSS3 with the approach you're currently looking at.

Therefore you would need to auto generate numbers in LESS CSS (see link below) or to auto generate values in Javascript. Finally, and the most time consuming would be to set all the contents of your page to scale based on vw and vh - so every length measurement above 1920px is set as a viewport width or a viewport height value.

Options:

  • 1) Use CSS LESS (method 1 - numbers and percentage types)
  • 2) Use CSS LESS (method 2 - string interpolation)
  • 3) Use Transform: scale() Recommended and combine with other options here.
  • 4) Use Javascript to update values once the DOM is loaded.
  • 5) Set all values within your body to be percentage based above a certain media size, typically using the rem length value.

    • a) Set all length values in your page above a certain media size to using rem which will be dynamically adjusted.
    • b) Use calc on the html element to set the size of a single rem unit. This will scale the contents. (please read the link above for scaling font size to screen size)

      @media screen (min-width:1980px){
          :root { 
             font-size: calc( #{$min_font}px + (#{$max_font} - #{$min_font}) * ( (100vw - 1920px) / ( #{$max_width} - 1920) ));
            }
            .some-other-element {
                width: 4rem;
           }
        }
      

Original (incorrect answer)

You should specify the length value of each value used in the calc that is not a multiple or division number. Therefore the result of the calc will be, for example 0.22vw.

I understand calc as using the length unit provided by the variables within the calc operation, so simply multiplying the result by 1 x the required length unit should convert any unitless or incorrectly-set length unit to the required value unit type.

Zoom accepts percentages so you can force the resultant vw value of calc(100vw / 1920); as a percentage by doing:

zoom: calc(100% * calc(100vw / 1920)); 

Which will give you on a screen width 2500px:

100% * ( 2500px / 1920 ) = 130.2% Zoom value.

For your example of 2880px.

zoom: calc(100% * calc(2880px / 1920)); = 100% * 1.5 = 150% = 1.5

I do not know how you calculated that the zoom should be 2 for these figures?

Martin
  • 22,212
  • 11
  • 70
  • 132