为了提升业务人员操作管理后台的体验,花了点时间进行响应式的改造,紧急情况时,掏出手机就能工作。
  利用CSS3的媒体查询,就能根据不同屏幕的尺寸采用不同的样式来渲染,目前使用的移动端屏幕阈值为750px。
  为了便于管理,基于[Less](https://lesscss.org/)的语法,声明了一个常量,专门记录屏幕尺寸。
~~~css
@mobile-screen: ~"(max-width:750px)";
~~~
  我们当前使用的管理后台基于[UmiJS3.X](https://umijs.org/zh-CN)和[Ant Design 3.X](https://3x.ant.design/docs/react/introduce-cn)。
## 一、结构改造
  首先是管理后台整体结构的改造,包括左边的菜单栏,右边的快捷按钮,登录信息等。
:-: ![](https://img.kancloud.cn/01/2f/012fbae6d36f9b6de9aeab23d55f2793_3220x848.png =800x)
**1)菜单栏**
  左边的菜单在手机界面还是蛮占地方的,默认情况下需要将其隐藏,还有那张Logo图,也需要隐藏,最大限度的将区域留给菜单。
  在下面的代码中,当URL的路径发生变化时,判断屏幕尺寸,如果当前是显示状态,那么就更新成隐藏状态。
~~~
// 响应式处理
const mobileHandle = () => {
// 屏幕尺寸小于750的就认为是移动设备的屏幕
if (window.screen.width <= 750 && !siderFold) {
dispatch({
type: "app/switchSider"
});
}
};
// 当路径变化时,隐藏菜单栏
useEffect(() => {
mobileHandle();
}, [location.pathname]);
~~~
  在Chrome的控制台,切换成手机屏幕时,右半部分会出现挤压的问题。
:-: ![](https://img.kancloud.cn/59/e6/59e6c08766b44d25f160d82d84654825_750x1054.png =300x)
  可以将右半部分设置为绝对定位,脱离正常流,再向左偏移菜单栏的宽度就能避免内容被挤压。
~~~css
.main {
width: 100%;
position: absolute;
left: 250px;
}
~~~
**2)快捷按钮**
  快捷按钮有3个,PC界面这块的高度是固定的,并且是横向布局。移动端的屏幕比较窄,更适合纵向布局。
  并且为了节约空间,登录后的昵称,也隐藏了,免得破坏布局。
:-: ![](https://img.kancloud.cn/9e/96/9e9635ea8660249794c9b9f0ae78ebb3_740x264.png =400x)
**3)全局样式**
  这些按钮默认是没有上下间距的,需要手动添加,例如修改Ant Design 的下拉框、搜索框、日期选择框的下边距,存储在 global.css 文件中。
~~~css
.ant-select,
.ant-input-search,
.ant-calendar-picker {
margin-bottom: 5px;
}
~~~
  有一点需要注意,不能将上述这些样式写在 less 文件内,因为在JavaScript文件中引用(CSS in JS)时,默认会带各种随机后缀。
~~~css
@media @mobile-screen {
.ant-select, .ant-input-search {
margin-bottom: 5px;
}
}
/* 编译结果 */
@media (max-width: 750px) {
.ant-select___1JpXW,
.ant-input-search___WeNgK {
margin-bottom: 5px;
}
}
~~~
  全局声明需要权衡,当涉及的页面很多时,也许某条样式会破坏某处的结构。
## 二、页面改造
  在页面中使用了大量的组件,包括自定义和第三方的,默认情况下,都不支持响应式,需要进行手动改造。
**1)表格**
  管理后台包含很多表格,这些表格都会包含很多列,直接平铺会将页面撑开,出现左右滚动条。
  在观察Ant Design表格滚动的源码后,发现了一个 max-content 关键字,表示宽度就是内容的长度。
~~~css
.ant-table-body, /* 表格 */
.ant-tabs-tabpane { /* 标签栏切换内容 */
overflow-x: scroll;
width: 100%;
-webkit-overflow-scrolling: touch;
}
.ant-table-body table,
.ant-tabs-tabpane table {
width: max-content;
}
~~~
  在表格的父级元素中声明横向滚动,就能避免布局被破坏了。
:-: ![](https://img.kancloud.cn/67/f1/67f177a8ab8902ce71687a495215952a_724x612.png =400x)
**2)内联样式**
  在之前的页面开发中,很多组件的宽度都是以内联的方式声明的。当时的确很方便,但是现在改造给我制造了障碍。
  如果直接在CSS文件中声明,那么特殊性不会比内联的高,也就不会生效,所以得用另一种方式。
  后面就想用脚本来做样式的更新,脚本比较好写。但是需要考虑一种情况。
  那就是页面初始化时不存在的DOM元素,需要点击或其他交互后才能被添加进来。
  需要监听DOM的变化,自然就想到了[MutationObserver](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver),在下面的代码中会监听 body 元素的直系后代的DOM变化。
~~~
useEffect(() => {
const isMobile = window.screen.width <= 750;
// 选择器,数字框,文本框,卡片
const selector = ".ant-input-number[style],.ant-input[style],.ant-calendar-picker[style],.ant-card[style],.ant-input[style]";
if (!isMobile) return;
const callback = function (mutationsList, observer) {
// 为了响应式,将style中的宽度修改成 100%
const nodes = document.querySelectorAll(selector);
[...nodes].forEach((item) => {
if (item.style.width && item.style.width != "100%") {
item.style.width = "100%";
}
});
};
// 观察器的配置,直接子节点的更改
const config = { childList: true };
const observer = new MutationObserver(callback);
// 观察目标节点
observer.observe(document.body, config);
}, []);
~~~
**3)弹框**
  在PC界面中,弹框中的内容会比较多,高度也会被撑开。
  当在移动端显示时,会超过屏幕的底部,无法看到弹框中的内容。
  可以手动的声明弹框的高度,利用[calc()](https://developer.mozilla.org/zh-CN/docs/Web/CSS/calc)函数,以及vh单位,100vh就是视口高度的100%。
~~~css
height: calc(100vh - 100px)
~~~
*****
> 原文出处:
[博客园-CSS躬行记](https://www.cnblogs.com/strick/category/1667864.html)
[知乎专栏-CSS躬行记](https://zhuanlan.zhihu.com/pwcss)
已建立一个微信前端交流群,如要进群,请先加微信号freedom20180706或扫描下面的二维码,请求中需注明“看云加群”,在通过请求后就会把你拉进来。还搜集整理了一套[面试资料](https://github.com/pwstrick/daily),欢迎浏览。
![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200)
推荐一款前端监控脚本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不仅能监控前端的错误、通信、打印等行为,还能计算各类性能参数,包括 FMP、LCP、FP 等。
- ES6
- 1、let和const
- 2、扩展运算符和剩余参数
- 3、解构
- 4、模板字面量
- 5、对象字面量的扩展
- 6、Symbol
- 7、代码模块化
- 8、数字
- 9、字符串
- 10、正则表达式
- 11、对象
- 12、数组
- 13、类型化数组
- 14、函数
- 15、箭头函数和尾调用优化
- 16、Set
- 17、Map
- 18、迭代器
- 19、生成器
- 20、类
- 21、类的继承
- 22、Promise
- 23、Promise的静态方法和应用
- 24、代理和反射
- HTML
- 1、SVG
- 2、WebRTC基础实践
- 3、WebRTC视频通话
- 4、Web音视频基础
- CSS进阶
- 1、CSS基础拾遗
- 2、伪类和伪元素
- 3、CSS属性拾遗
- 4、浮动形状
- 5、渐变
- 6、滤镜
- 7、合成
- 8、裁剪和遮罩
- 9、网格布局
- 10、CSS方法论
- 11、管理后台响应式改造
- React
- 1、函数式编程
- 2、JSX
- 3、组件
- 4、生命周期
- 5、React和DOM
- 6、事件
- 7、表单
- 8、样式
- 9、组件通信
- 10、高阶组件
- 11、Redux基础
- 12、Redux中间件
- 13、React Router
- 14、测试框架
- 15、React Hooks
- 16、React源码分析
- 利器
- 1、npm
- 2、Babel
- 3、webpack基础
- 4、webpack进阶
- 5、Git
- 6、Fiddler
- 7、自制脚手架
- 8、VSCode插件研发
- 9、WebView中的页面调试方法
- Vue.js
- 1、数据绑定
- 2、指令
- 3、样式和表单
- 4、组件
- 5、组件通信
- 6、内容分发
- 7、渲染函数和JSX
- 8、Vue Router
- 9、Vuex
- TypeScript
- 1、数据类型
- 2、接口
- 3、类
- 4、泛型
- 5、类型兼容性
- 6、高级类型
- 7、命名空间
- 8、装饰器
- Node.js
- 1、Buffer、流和EventEmitter
- 2、文件系统和网络
- 3、命令行工具
- 4、自建前端监控系统
- 5、定时任务的调试
- 6、自制短链系统
- 7、定时任务的进化史
- 8、通用接口
- 9、微前端实践
- 10、接口日志查询
- 11、E2E测试
- 12、BFF
- 13、MySQL归档
- 14、压力测试
- 15、活动规则引擎
- 16、活动配置化
- 17、UmiJS版本升级
- 18、半吊子的可视化搭建系统
- 19、KOA源码分析(上)
- 20、KOA源码分析(下)
- 21、花10分钟入门Node.js
- 22、Node环境升级日志
- 23、Worker threads
- 24、低代码
- 25、Web自动化测试
- 26、接口拦截和页面回放实验
- 27、接口管理
- 28、Cypress自动化测试实践
- 29、基于Electron的开播助手
- Node.js精进
- 1、模块化
- 2、异步编程
- 3、流
- 4、事件触发器
- 5、HTTP
- 6、文件
- 7、日志
- 8、错误处理
- 9、性能监控(上)
- 10、性能监控(下)
- 11、Socket.IO
- 12、ElasticSearch
- 监控系统
- 1、SDK
- 2、存储和分析
- 3、性能监控
- 4、内存泄漏
- 5、小程序
- 6、较长的白屏时间
- 7、页面奔溃
- 8、shin-monitor源码分析
- 前端性能精进
- 1、优化方法论之测量
- 2、优化方法论之分析
- 3、浏览器之图像
- 4、浏览器之呈现
- 5、浏览器之JavaScript
- 6、网络
- 7、构建
- 前端体验优化
- 1、概述
- 2、基建
- 3、后端
- 4、数据
- 5、后台
- Web优化
- 1、CSS优化
- 2、JavaScript优化
- 3、图像和网络
- 4、用户体验和工具
- 5、网站优化
- 6、优化闭环实践
- 数据结构与算法
- 1、链表
- 2、栈、队列、散列表和位运算
- 3、二叉树
- 4、二分查找
- 5、回溯算法
- 6、贪心算法
- 7、分治算法
- 8、动态规划
- 程序员之路
- 大学
- 2011年
- 2012年
- 2013年
- 2014年
- 项目反思
- 前端基础学习分享
- 2015年
- 再一次项目反思
- 然并卵
- PC网站CSS分享
- 2016年
- 制造自己的榫卯
- PrimusUI
- 2017年
- 工匠精神
- 2018年
- 2019年
- 前端学习之路分享
- 2020年
- 2021年
- 2022年
- 2023年
- 日志
- 2020