这些年踩过无数坑后,我慢慢摸索出了一套适配方法。不是什么高深理论,就是实打实的经验总结。
先从最基础的视口说起
早期我总在HTML里写`width=devicewidth`,但经常遇到页面被缩放的问题。后来才搞明白,完整写法应该是:
```html
```
加上`initialscale=1.0`确保初始缩放为1,禁止用户缩放能避免很多奇怪的问题。不过现在为了无障碍考虑,我一般会把`userscalable=no`去掉,毕竟有些用户需要放大才能看清内容。
面对不同屏幕尺寸,我选择了弹性布局
刚开始我用固定像素写样式,结果可想而知。后来改用Flexbox,才发现这才是响应式设计的灵魂。比如这个导航栏布局:
```css
.nav {
display: flex;
justifycontent: spacebetween;
alignitems: center;
}
```
简单几行代码,无论屏幕宽度怎么变,元素都能自动调整间距和对齐。特别是处理水平排列的菜单时,Flexbox比浮动省心太多了。
对于更复杂的二维布局,CSS Grid是另一个利器。我记得有次要做产品展示区,每行显示3个产品,在小屏幕上变成2个,在超小屏幕上变成1个:
```css
.products {
display: grid;
gridtemplatecolumns: repeat(3, 1fr);
gap: 20px;
}
@media (maxwidth: 768px) {
.products {
gridtemplatecolumns: repeat(2, 1fr);
}
}
@media (maxwidth: 480px) {
.products {
gridtemplatecolumns: 1fr;
}
}
```
这种写法清晰直观,再也不用像以前那样写一堆复杂的媒体查询了。
单位选择上,我找到了最佳组合
像素单位让我吃了太多亏,后来我学会了根据场景使用不同单位:
对于字体大小,我用rem,通过设置`html { fontsize: 16px }`,然后所有字体用比如`1.5rem`这样的相对单位
对于边距、宽度,我喜欢用百分比或者vw/vh
对于需要精确控制的小间距,我仍然会用px
特别是vh单位,在处理全屏布局时特别有用。不过要注意移动浏览器地址栏的问题,有时候100vh会超出屏幕,这时候可以用webkitfillavailable或者JavaScript动态计算。
图片适配是个技术活
曾经有用户投诉流量消耗太快,排查后发现是我们在小屏手机上加载了2000px宽的大图。后来我学会了srcset:
```html
srcset="image400.jpg 400w, image800.jpg 800w, image1200.jpg 1200w"
sizes="(maxwidth: 480px) 100vw, (maxwidth: 768px) 50vw, 33vw"
alt="示例图片"
>
```
这样浏览器会根据设备宽度自动选择合适的图片,既节省流量又加快加载速度。
对于背景图片,我通常这样处理:
```css
.hero {
backgroundimage: url('imagesmall.jpg');
}
@media (minresolution: 2dppx) {
.hero {
backgroundimage: url('imagelarge.jpg');
}
}
```
为高分屏提供2倍图,普通屏幕用1倍图。
深色模式让我折腾了好一阵
现在系统都支持深色模式,刚开始我直接反转颜色,结果惨不忍睹。后来学聪明了,在CSS变量中定义颜色:
```css
:root {
textcolor: 333;
bgcolor: fff;
}
@media (preferscolorscheme: dark) {
:root {
textcolor: eee;
bgcolor: 1a1a1a;
}
}
body {
color: var(textcolor);
background: var(bgcolor);
}
```
这样只需要维护两套颜色变量,所有元素都会自动适应。
刘海屏和安全区域是新时代的挑战
iPhone X刚出来时,底部的Home Indicator经常挡住内容。后来发现可以用env()函数:
```css
body {
paddingbottom: env(safeareainsetbottom);
}
```
同样要处理顶部的刘海区域:
```css
.header {
paddingtop: env(safeareainsettop);
}
```
在meta viewport里还要加上`viewportfit=cover`,这样才能正确识别安全区域。
1像素边框的困扰
在Retina屏幕上,1px边框看起来往往太粗。我试过用transform缩放,但太麻烦。现在直接用0.5px:
```css
.border {
border: 0.5px solid ddd;
}
```
大多数现代浏览器都支持了,不支持的会回退到1px,影响不大。
表单输入的坑特别多
不同系统对表单的渲染差异很大,特别是iOS上的输入框经常有圆角、阴影。我一般会统一样式:
```css
input, textarea {
appearance: none;
borderradius: 0;
}
```
还要注意焦点状态,我通常会自定义:
```css
input:focus {
outline: none;
boxshadow: 0 0 0 2px blue;
}
```
移动端交互要考虑触摸
鼠标hover效果在触摸屏上无效,所以我都会提供替代方案:
```css
.button {
/ 基础样式 /
}
@media (hover: hover) {
.button:hover {
/ 只有支持hover的设备才显示悬停效果 /
}
}
.button:active {
/ 所有设备都有的激活状态 /
}
```
性能优化不能忘
移动端网络条件差,我学会了懒加载:
```html

```
还有CSS和JS的按需加载,用媒体查询分割CSS:
```html
```
测试是最后的关键
我现在养成了习惯,每写完一个功能就在多个真机上测试。云测试平台帮了大忙,不用买那么多真机。特别是要测试横竖屏切换、键盘弹出、网络切换等场景。
记得有次用户反馈说在某个国产手机上页面显示异常,排查后发现是它的浏览器内核太老,不支持某些CSS特性。从此我养成了写回退样式的习惯:
```css
.element {
/ 老浏览器能理解的样式 /
display: block;
/ 新浏览器会覆盖的样式 /
display: grid;
}
```
这段适配之路走了这么多年,从最初的焦虑到现在的从容,最大的体会就是:移动端适配没有银弹,需要的是对不同设备特性的理解,加上细致的测试和不断的优化。每解决一个兼容性问题,就离更好的用户体验近了一步。
现在的我,看到产品在各种设备上完美展示时,依然会像当年一样开心。这份成就感,大概就是我们坚持做技术的初心吧。
未经允许不得转载:人美经典文章 » 内容均为网友投稿,不排除杜撰可能,仅可一观。
人美经典文章
热门排行
阅读 (113)
1恋爱时的细心照顾,婚后的粗心忽略阅读 (105)
2想和他一起去海边散步看星星阅读 (100)
3明知没有结果 可心疼还在继续阅读 (98)
4曾共看的日落,成单人余晖阅读 (95)
5他曾说会包容我,后来对我处处指责