你不知道到的 CSS - 纯 CSS 获取浏览器宽度【CSS 新特性 property 与 数学函数 的实际应用】(含 JavaScript 复习)

1,523 阅读3分钟

前言

你的 点赞、收藏、关注 ,是我继续写下去的唯一动力 ~

先看效果:

css windonw.webp

众所周知,我们平时获取获取窗口的宽高都是 JavaScript 获取的,要不然直接通过 JavaScriptresize 监听页面宽高变化。

但现在不一样了!我们可以直接通过 CSS 获取 window 的尺寸,并且可以通过变量来进行使用。

在我第一眼看到这个消息的感觉是不可置信!但这是真的,下面我将带大家复习一下在 Vue、React、Svelte 以及原生 JavaScript 中如何获取 window 尺寸,然后带大家一览新的获取方案!

示例

点击马上掘金中间的左右箭头,可以查看高度的监听。

正文

本来是先写的传统方案获取尺寸,但想到大家可能都了解怎么实现,就放在了后面,大家有需要可以自己在后面复习一下。😊😊

CSS 获取窗口大小

属性定义

通过 CSS 新增的 @property ,可以让我们创建自定义属性,并给它定义其类型以及初始值(初始值在不经改变的情况下一直是该值)。
利用这个功能,我们可以创建一个宽高属性出来。

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

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

这其中:

  • syntax 是这个属性的单位,我们给它设置为 <length> ,以便于让浏览器理解这是一个长度单位
  • initial-value 是这个属性的初始值,如果不修改,它一直是 100vw
  • inherits 是这个属性是否可以被继承,设置 false | true 都不影响使用

计算为数字

现在我们有一个 CSS 能识别的 length ,但这个单位我们不认识,所以我们要通过 CSS 提供的数学函数计算出真正的数字长度,因此我们要使用 CSS 数学工具中的 atans2(y, x)tan()

  • atans(y, x) :返回点 (x, y) 到原点的角度(弧度单位)
  • tan() :返回给定角度的正切

通过上面这两个数学函数,计算 --w_raw--h-raw1px 之间角度的正切值,进而得到宽高的纯数字。

将数字展示到页面

通过 CSS 的计数器将数字展示到页面上。

这其中:

  • counter(w) :表示计数器 w 的值
  • counter-reset: w var(--w) :表示计数器 w 被重置为 --w 的值
body::before {
  content: counter(w) 'x' counter(h);
  counter-reset: h var(--h) w var(--w);
}

完整代码

@property --w_raw {
  syntax: '<length>';
  inherits: false;
  initial-value: 100vw;
}

@property --h_raw {
  syntax: '<length>';
  inherits: false;
  initial-value: 100vh;
}

:root {
  --w: tan(atan2(var(--w_raw), 1px));
  --h: tan(atan2(var(--h_raw), 1px));
}

body::before {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  content: counter(w) 'x' counter(h);
  counter-reset: h var(--h) w var(--w);
}

复习一下传统开发中的获取方案

JavaScript

在原生 JavaScript 中,我们通过 innerWidth 获取窗口宽度,然后通过监听 resize 变化重新赋值。

let windowWidth = window.innerWidth;

function handleResize = () => windowWidth = window.innerWidth

window.addEventListener('resize', handleResize)
window.addEventListener('resize', handleResize)

Vue

在 Vue3 中,我们可以通过自定义 Hook 的方式实现 resize

// useWindowWidth.js
import { ref, onMounted, onUnmounted } from 'vue';

export function useWindowWidth() {
  const windowWidth = ref(window.innerWidth);

  const handleResize = () => {
    windowWidth.value = window.innerWidth;
  };

  onMounted(() => {
    window.addEventListener('resize', handleResize);
  });

  onUnmounted(() => {
    window.removeEventListener('resize', handleResize);
  });

  return windowWidth;
}

由于 Vue2 不支持自定义 Hook ,我们则需通过 Mixin 的方式实现。

// windowMixin.js
export const windowMixin = {
  data() {
    return {
      windowWidth: window.innerWidth
    };
  },
  methods: {
    handleResize() {
      this.windowWidth = window.innerWidth;
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleResize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize);
  }
};

React

React 也是一个简单的 Hook

// useWindowWidth.js
import { useState, useEffect } from 'react';

export function useWindowWidth() {
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => {
      setWindowWidth(window.innerWidth);
    };

    // 初始化时调用一次
    handleResize();

    // 监听窗口大小变化
    window.addEventListener('resize', handleResize);

    // 清除监听器
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return windowWidth;
}

最后

通过上面文章,相信大家可以学会 CSS 如何实现监听 window 宽度,并且可以举一反三的利用该原理做更多的事情。✌️

同时我们还复习了多种语言中如何监听 window 宽度。

今天的分享就到这里了🙆 ~

你的 点赞、收藏、关注 ,是我继续写下去的唯一动力 ~