增量 CSS 媒体查询

Incremental CSS Media Queries

考虑使用 media 查询和 transform:

随着高度减小调整页面大小的样式表
@media (max-height: 620px) {
    body {
    transform: scale(0.95);
    }
}
@media (max-height: 590px) {
    body {
    transform: scale(0.90);
    }
}
@media (max-height: 560px) {
    body {
    transform: scale(0.85);
    }
}
// and so on ...

页面 "zooms out" 随着 window 高度的减小,允许在较小的屏幕上显示全部内容。 如果我想支持小于 560px 高度的屏幕,我需要添加更多 media 查询。

请注意,对于每个 30px 的高度损失,我们在输入中调用 0.05 的比例尺。

问题:有没有办法只使用css来定义增量媒体查询?

跟进: 如果没有纯粹的 css 解决方案,在 vanilla JS 中实现这种效果的最简单方法是什么?

编辑: 感谢大家针对此问题发布不同的解决方案。我感谢您的帮助。您的回答帮助我学习了如何改进我的代码。

单独使用 CSS 是不可能的。您可以使用 JS 通过添加 window.onresize 函数来监视 documentbody 的大小调整和缩放。此解决方案还可以动态扩展,因此您无需担心断点或@media 查询。

function updateScale() {
  let viewScale = window.innerHeight / document.documentElement.scrollHeight;
  document.body.style = 'transform:scale(' + viewScale + ')';
  document.documentElement.scrollHeight = window.innerHeight;
}

window.onresize = function() {
  updateScale();
}
updateScale();
body {
  transform-origin: 0 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

#block {
  background-color: black;
  width: 300px;
  height: 4000px;
}
<div id='block'></div>

在这种情况下,您可能必须使用 vanilla JavaScript

因此,每个 30px0.05,或者每个 6px650px 向下是 0.01

这意味着 600px 的数量是 1 并且每个 pixel0.01/6.

考虑到所有这些信息,我们可以使用 resize 事件来计算:

window.addEventListener('resize', changeTransform); // when resize, call changeTransform

var bodyEl = document.querySelector('body');

function changeTransform() {

  var scale = 1; // default scale
  if (window.innerHeight < 650) { // if window height < 650px, do magic
    scale = -0.83 + (0.05/30)*window.innerHeight;
  }
  bodyEl.style.transform = "scale(" + scale + ")"; // apply scale (1 or the calculated one)

}

希望对您有所帮助。

@NathanFries 是正确的,这不是原生 CSS.

可以做到的

CSS 包括 viewport units 用于基于百分比的宽度和高度值,但您不能将其传递给 scale() 函数。

然后您需要将其绑定到某个 resize 事件侦听器。

这里是一个简单的例子,可能会完成你想要做的事情:

// @see https://github.com/WICG/EventListenerOptions/blob/9dcca95/explainer.md#feature-detection
// @example `elem.addEventListener('touchstart', fn, supportsPassive ? { passive: true } : false);`
var checkSupportPassiveEvents = function() {
    var supportsPassive = false;
    try {
        var opts = Object.defineProperty({}, 'passive', {
            get: function() {
                supportsPassive = true;
            },
        });
        window.addEventListener('testPassive', null, opts);
        window.removeEventListener('testPassive', null, opts);
    } catch (e) {}

    return supportsPassive;
};

var supportsPassive = checkSupportPassiveEvents();

var mapRange = function(fn, inStart, inEnd, outStart, outEnd) {
    if (outStart === void 0) {
        outStart = inStart;
        outEnd = inEnd;
        inStart = 0;
        inEnd = 1;
    }

    var inRange = inEnd - inStart,
        outRange = outEnd - outStart;

    return function(val) {
        var original = fn((val - inStart) / inRange);
        return outStart + outRange * original;
    };
};

var linear = function(x) {
    return x;
};

var minHeight = 320;
var maxHeight = 620;
var minScale = 0.45;
var maxScale = 1;
var screenHeightToScaleFactorInner = mapRange(linear, minHeight, maxHeight, minScale, maxScale);

var screenHeightToScaleFactor = function(height) {
    if (height <= minHeight) {
        return minScale;
    } else if (height > maxHeight) {
        return maxScale;
    } else {
        return screenHeightToScaleFactorInner(height);
    }
};

window.addEventListener(
    'resize',
    function(e) {
        var height = this.innerHeight;

        this.document.body.style.transform = 'scale(' + screenHeightToScaleFactor(height) + ')';
    },
    supportsPassive ? { passive: true } : false
);

对于 CSS 解决方案,您可以考虑使用 vhvw 单位,但它不可能使用比例,因为它需要一个无单位值。

另一种方法是使用 translateZ() 和一些透视来模拟比例动画。

这是一个基本示例。结果不准确,因为我只是想演示这个技巧。 运行 片段整页并调整 window 高度,您将看到元素缩放。

.box {
  width:100px;
  height:100px;
  background:red;
  transform:perspective(180px) translateZ(15vh);
  transform-origin:top left;
}
<div class="box">
some text here
</div>

您只需要为不同的值找到正确的计算方法。