你能想到,只用CSS就可以动态检测屏幕视口尺寸吗?

937 阅读3分钟

背景

先看一个问题:如何动态获取屏幕视口尺寸的大小,显示在页面上。

效果如下:

property-ezgif.com-video-to-gif-converter.gif

1. 使用js方式

正常我们的做法是使用js处理,这很简单。

如下所示:

window.addEventListener("resize", (e) => {
    console.log('窗口宽度:', e.target.innerWidth, '窗口高度:', e.target.innerHeight);
});

如果只是这样,那就没有意思了。

下面介绍一种方式:使用css就可以动态检测屏幕视口尺寸。

2. 使用css方式

这里我们废话不多说,直接上代码,具体如下:


/* 默认转换成px */
  @property --vw {
    syntax: "<length>";
    inherits: true;
    initial-value: 100vw;
  }
  @property --vh {
    syntax: "<length>";
    inherits: true;
    initial-value: 100vh;
  }
  :root {
    --w: tan(atan2(var(--vw), 1px));
    --h: tan(atan2(var(--vh), 1px));
  }
  body::before {
    content: counter(w) "x" counter(h);
    counter-reset: w var(--w) h var(--h);
    font-size: 150px;
    font-weight: 900;
    position: fixed;
    inset: 0;
    width: fit-content;
    height: fit-content;
    margin: auto;
  }

暂一看,一头雾水。这里我们先说一下具体的实现思路:

  1. 利用CSS的@property规则来定义自定义属性(CSS变量),通过这些变量自动计算得到视口宽度和高度(vwvh)的值,注意这里得到的单位是px
  2. 使用三角函数tan和反三角函数atan2进行计算去除px单位,得到对应的值
  3. 通过couter-resetCSS 计数器,将其初始化,在content中使用counter进行显示计数器的值。

每一步的具体说明如下:

2.1 自定义属性定义

@property允许开发者显示的定义CSS属性,这些属性允许进行类型检查,以及设置默认值,定义之后的属性,可以直接在css中使用,也可以在JavaScript中使用。

具体语法:

// 自定义属性的名称,必须以`--`开头
@property --name {
    // 自定义属性的类型
    syntax: <type> | <type> [ <type> ]*; 
    // 是否继承父元素的属性值
    inherits: true | false;
    // 自定义属性的默认值
    initial-value: <value>;
}

通过上述说明我们可以定义出视口宽高的自定义属性 :

@property --vw {
  syntax: "<length>";
  inherits: true;
  initial-value: 100vw;
}
@property --vh {
  syntax: "<length>";
  inherits: true;
  initial-value: 100vh;
}

2.2 :root中使用tan和atan2计算自定义属性

  • atan2
    • atan2()  为三角函数,返回介于 -infinity 和 infinity 之间的两值的反正切值。此函数接受两个参数,返回表示介于 -180deg 和 180deg 之间的 <angle> 的弧度数。
  • tan
    • tan()  为三角函数,返回某数的正切值,此值介于 −infinity 和 infinity 之间。此函数含有单个计算式,此式须将参数结果按弧度数解析为 <number> 或 <angle>
:root {
  --w: tan(atan2(var(--vw), 1px));
  --h: tan(atan2(var(--vh), 1px));
}

先看一张图:

image.png

先使用atan2计算--vw值与1像素的比值的反正切值(即角度α),使用tan再对这个角度取正切,得到一个数值,表示比例值,因为是对1px的比例,所以得到的数值就是vh的高度值。

通过:root变量--w--h进行自定义属性,提供给后面使用。

3. 使用counter-reset和counter进行显示

  • counter-reset
    • CSS 属性用于创建具名 CSS 计数器,并将其初始化为指定值。
  • counter
    • content CSS 属性用于在元素的 ::before 和 ::after 伪元素中插入内容,其中内容有很多种,包括计数器。
body::before {
  content: counter(w) "x" counter(h);
  counter-reset: w var(--w) h var(--h);
  font-size: 150px;
  font-weight: 900;
  position: fixed;
  inset: 0;
  width: fit-content;
  height: fit-content;
  margin: auto;
}

使用counter-reset: w var(--w) h var(--h);:重置wh计数器的值为--w--hcontent: counter(w) "x" counter(h);:显示wh的计数值。

总结

最后总结一下:这段css代码实现通过自定义属性和一些三角函数运算(atan2tan)来计算视口宽度和高度的值,并将这些计算结果使用计数器方式显示出来。通过css进行实现会让人眼前一亮的感觉,算是一种额外的思路。

如有错误,请指正O^O!