背景
网站需要适配移动端,但是不能切换域名,只能在一个项目里适配,然后设计的移动端页面结构与PC端存在相当的差异,单纯通过CSS进行适配,过于麻烦且难以实现。
代码
- CSS使用vw、rem、sass/less实现等比例还原UI设计(类似小程序的rpx方案):
使页面结构在一定区间的分辨率内缩放与UI设计稿尽量一致。
// variables-desktop.scss
// 1440px为UI设计稿宽度
// 12px = 100vw / 1440px * 12;
$root-font-size: 0.83vw;
@function fs($font-size) {
@return calc($font-size / 12) + rem;
}
// variables-mobile.scss
// 750px为UI设计稿宽度
// 12px = 100vw / 750px * 12;
$root-font-size: 1.6vw;
@function fs($font-size) {
@return calc($font-size / 12) + rem;
}
// public.scss
@import './variables-desktop.scss';
html {
font-size: $root-font-size;
}
@import './mobile.scss';
// mobile.scss
@import './variables-mobile.scss';
@media (max-width: 750px) {
html {
font-size: $root-font-size;
}
}
// pages/Page/Desktop/index.module.scss
@import './variables-desktop.scss';
.box {
// width: 1440px;
width: fs(1440);
}
rpx2rem
// variables-mobile.scss
// 750px为UI设计稿宽度
// 12px = 100vw / 750px * 12;
$root-font-size: 1.6vw;
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str- slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function fs($font-size) {
$a: calc($font-size / 12) + '';
$b: str-replace($a,'rpx','');
$c: unquote($b);
@return $c + rem;
}
- 在复杂组件内使用JS判断
在PC/Mobile设计稿的结构差异过大的情况下使用,如页面组件 这里的例子是借用了ahooks的 useResponsive 封装了一个Context:
//context/ResponsiveProvider/useResponsive.ts
import { useEffect, useMemo, useState } from 'react';
import { configResponsive, useResponsive as useResponsiveBase } from 'ahooks';
configResponsive({
mobile: 0,
tablet: 751,
desktop: 1281,
});
export default function useResponsive() {
const responsive = useResponsiveBase();
const [device, setDevice] = useState('desktop');
useEffect(() => {
if (responsive?.desktop) {
setDevice('desktop');
} else if (responsive?.tablet) {
setDevice('tablet');
} else if (responsive?.mobile) {
setDevice('mobile');
}
}, [responsive]);
return useMemo(() => ({ device } as const), [device]);
}
// pages/Page/index.tsx
import React from 'react';
import { useResponsiveContext } from '@/context/ResponsiveProvider';
import type { Props } from './interface';
import Desktop from './Desktop';
import Mobile from './Mobile';
const Page = (props: Props) => {
const { device } = useResponsiveContext();
if (device === 'mobile') {
return <Mobile {...props} />;
}
return <Desktop {...props} />;
};
export type { Props };
export default Page;
- 在简单组件内使用CSS判断:
在PC/Mobile设计稿的结构类似的情况下使用,如Button组件
// public.scss
@import '@/styles/variables-desktop.scss';
.btn {
font-size: 14px;
}
@import './mobile.scss';
// mobile.scss
@import '@/styles/variables-mobile.scss';
@media (max-width: 750px) {
.btn {
font-size: 12px;
}
}