七夏 发表于 2024-11-5 22:46:09

解决PC端和移动端的CSS简单适配问题

## 不同端的适配

---

很多时候,我们开发的项目只在PC端运行,但是也会在手机移动端内访问,所以我们更多时候需要考虑网站在PC端和移动端是否适配问题,接下来就是我在学习中学到的适配技巧哦,快学起来!

### 问题场景

今天在做移动端demo的时候,发现了一个让人难以忍受的css适配问题,如果不做屏幕适配的话,代码量真的太大了,后来发现了一招,可以简单快速的解决这个问题。

我们接下来做一个小测试吧,能更好的理解怎么去做到适配的。

```
<div class="app">
        app
</div>

// css
.app {
    width: 200px;
    height: 200px;
    background-color: red;
}
```

很显然,我们会得到一个固定长宽的正方形在页面上。

![图片](https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/sz_mmbiz_jpg/IlE1Y2rl1uabHlbTM05XNl9NdxViaxAC6ZecDIJOaBfoicHUbAbtic8kvmdwgialic3mJamvZAza5eqE0ZjYumgicvzw/640?wx_fmt=other&from=appmsg&wxfrom=5&wx_lazy=1&wx_co=1&tp=webp)

但是如果我们换一个手机来打开这个网页呢?

![图片](https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/sz_mmbiz_jpg/IlE1Y2rl1uabHlbTM05XNl9NdxViaxAC6T0bQ8HQ6vbLH8ficJHUwIk6FbIt1D2juFYZxy4AkOUvZzg0BCHibFAmw/640?wx_fmt=other&from=appmsg&wxfrom=5&wx_lazy=1&wx_co=1&tp=webp)

这个正方形还是这么大,其实我们换个手机就是为了能够更好的看这个图形,可不能让上帝们花了钱,却没有好的体验不是。所以对于不同屏幕宽度的设备,也应有更适应的css对于来渲染对吧。

那么接下来我们用媒体查询来实现,不同宽度的屏幕对应不同的css样式吧。我们在style内加入如下代码:

```
@media (min-width: 400px){
   .app {
        width: 400px;
        height: 400px;
        background-color: green;
    }
}
```

![图片](https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/sz_mmbiz_jpg/IlE1Y2rl1uabHlbTM05XNl9NdxViaxAC6qrcBVnGsUGDPQ67Wwibtiaiao1cVW51rfqZlGQVq7ic2mIPGEDbIAcRLjw/640?wx_fmt=other&from=appmsg&wxfrom=5&wx_lazy=1&wx_co=1&tp=webp)

可以看到当更换更大的设备时,css发生了改变,`min-width: 400px`的意思就是屏幕宽度大于等于400px的时候,应用 `@media`的css样式,原先的css样式会被覆盖.

> *那么问题来了,如果我们有很多个媒体查询条件呢?是不是app的样式需要写很多份,当我们页面有很多很多个div盒子的时候,也是按照这样复制再修改,下班岂不是遥遥无期??估计也没人这么蠢,毕竟在坐的各位都是大佬。*

---

* 那么有没有什么一劳永逸的方法呢??答案是肯定的

---

我们知道,`px`是一个绝对单位,写死了就不会变,那我们有没有一个相对单位来给它进行长度和宽度的赋值呢?那就是 `rem`了没得说了。

`rem` 是 CSS 中的一个长度单位,全称为 "root em",它代表相对于 HTML 文档根元素(即 `<html>` 元素)的字体大小。`rem` 单位结合了绝对单位和相对单位的优点,提供了一种灵活的方式来设置字体大小和其他尺寸,同时保持整体设计的一致性和可扩展性。

**rem的特点**:其单位是 `相对于根元素`,通常是 `html`的字体大小,还有 `全局一致性`,由于 `rem` 是相对于根元素的,所以你只需要在一个地方(通常是全局样式表的开始处)设置根元素的字体大小,就可以影响到整个页面中所有使用 `rem` 的元素。

> 例如,如果你的 `<html>` 元素的字体大小是 16px,那么 `1rem` 就等于 16px。如果你将一个段落元素的字体大小设置为 `1.5rem`,那么它的字体大小就会是 24px。

```
.app {
    width: 10rem;
    height: 10rem;
    background-color: red;
}
@media (min-width: 400px){
    html{
        font-size: 20px;
    }
}
```

![图片](https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/sz_mmbiz_jpg/IlE1Y2rl1uabHlbTM05XNl9NdxViaxAC6YhiaAxSsa03C0TsVTryu7847icJ1y7BMMxwIUVWgrdgnrsHIsEIscsyA/640?wx_fmt=other&from=appmsg&wxfrom=5&wx_lazy=1&wx_co=1&tp=webp)

![图片](https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/sz_mmbiz_jpg/IlE1Y2rl1uabHlbTM05XNl9NdxViaxAC6vDiaLrddTab6O204XyVFNH5Ouf7VX0SiaUjAMmTYXy9PF6T507ic4iceUw/640?wx_fmt=other&from=appmsg&wxfrom=5&wx_lazy=1&wx_co=1&tp=webp)

这样我们就不用一直复制修改app的样式了,只需要修改根节点的字体大小就好了,而且当使用更大的设备时,需要更大的字体去显示,这也刚好适合我们的应用场景了。

### 优雅的适配封装

下面是封装的js适配代码:

```
(function(doc){
    let docEl = doc.documentElement;  // 获取根节点的html
    doc.addEventListener('DOMContentLoaded',recalc)
    function recalc(){
        let width = docEl.clientWidth;
        docEl.style.fontSize = 20 * (width / 320) + 'px';
    }
})(document)
```

1. 使用IIFE(立即执行函数表达式)来封装整个功能,确保变量不会污染全局作用域。
2. 获取文档的 `<html>`元素,存储在 `docEl`变量中。
3. 添加一个事件监听器,监听 `DOMContentLoaded`事件,当DOM加载完成时调用 `recalc`函数。
4. 在 `recalc`函数中:

   * 获取 `<html>`元素的可视宽度(不包括滚动条),存储在 `width`变量中。
   * 根据 `width`计算新的字体大小。这里使用了一个公式 `20 * (width / 320)`,意味着当宽度为320px时,根元素的字体大小为20px;宽度增加时,字体大小按比例增加。
   * 将计算出的字体大小设置为 `<html>`元素的 `style.fontSize`属性,单位为 `px`。
5. 最后,将 `document`对象作为参数传入IIFE,使内部函数可以访问到文档对象。

最后我们将这个做好的适配封装代码引入项目全局去使用就好了。
页: [1]
查看完整版本: 解决PC端和移动端的CSS简单适配问题