适配原理
- 选择某个手机的尺寸大小作为基准,其他手机进行等比例缩放
- 一般选择
iPhone 6
(2倍屏幕),屏幕宽度为:375px
适配方式
- rem:需要手动修改
html
元素的font-size
;额外设置body
元素的字体大小为正常值 - vw: 1
vw
等于屏幕宽度的1%
vw/vh方案
- 安装 px 转 vw 的包:
yarn add -D postcss-px-to-viewport
- 包的作用:将
px
转化为vw
,所以有了该工具,只需要在代码中写px
即可
- 包的作用:将
- 在
craco.config.js
添加相应配置 - 重启项目,让配置生效
craco.config.js
中(这个文件一开始是用于能够在react中使用@路径)
const pxToViewport = require('postcss-px-to-viewport')
const vw = pxToViewport({
// 视口宽度,一般就是 375( 设计稿一般采用二倍稿,宽度为 375 )
viewportWidth: 375
})
module.exports = {
// 此处省略 webpack 配置
webpack: {},
// 这里补充style配置
style: {
postcss: {
plugins: [vw]
}
}
}
移动端 1px 像素处理
解决:移动端中像素比pc端中偏大的问题
- 设备像素比:dpr=window.devicePixelRatio,也就是设备的物理像素与逻辑像素的比值。
- 在
retina
屏的手机上,dpr
为2
或3
,css
里写的1px
宽度映射到物理像素上就有2px
或3px
宽度。 - 例如:
iPhone6
的dpr
为2
,物理像素是750
(x轴),它的逻辑像素为375
。也就是说,1个逻辑像素,在x
轴和y
轴方向,需要2个物理像素来显示,即:dpr=2时,表示1个CSS像素由4个物理像素点组成。
解决方案
实现原理:伪元素 + transform 缩放
伪元素::after
或::before
独立于当前元素,可以单独对其缩放而不影响元素本身的缩放
参考:https://blog.csdn.net/xgangzai/article/details/107118168
参考:https://blog.csdn.net/xgangzai/article/details/107118168
实现参考 antd-mobile
创建公共样式
创建公共样式hairline.scss
// src/assets/styles/hairline.scss
@mixin scale-hairline-common($color, $top, $right, $bottom, $left) {
content: '';
position: absolute;
display: block;
z-index: 1;
top: $top;
right: $right;
bottom: $bottom;
left: $left;
background-color: $color;
}
@mixin hairline($direction, $color: #000, $radius: 0) {
@if $direction == top {
border-top: 1px solid $color;
// min-resolution 用来检测设备的最小像素密度
@media (min-resolution: 2dppx) {
border-top: none;
&::before {
@include scale-hairline-common($color, 0, auto, auto, 0);
width: 100%;
height: 1px;
transform-origin: 50% 50%;
transform: scaleY(0.5);
@media (min-resolution: 3dppx) {
transform: scaleY(0.33);
}
}
}
} @else if $direction == right {
border-right: 1px solid $color;
@media (min-resolution: 2dppx) {
border-right: none;
&::after {
@include scale-hairline-common($color, 0, 0, auto, auto);
width: 1px;
height: 100%;
background: $color;
transform-origin: 100% 50%;
transform: scaleX(0.5);
@media (min-resolution: 3dppx) {
transform: scaleX(0.33);
}
}
}
} @else if $direction == bottom {
border-bottom: 1px solid $color;
@media (min-resolution: 2dppx) {
border-bottom: none;
&::after {
@include scale-hairline-common($color, auto, auto, 0, 0);
width: 100%;
height: 1px;
transform-origin: 50% 100%;
transform: scaleY(0.5);
@media (min-resolution: 3dppx) {
transform: scaleY(0.33);
}
}
}
} @else if $direction == left {
border-left: 1px solid $color;
@media (min-resolution: 2dppx) {
border-left: none;
&::before {
@include scale-hairline-common($color, 0, auto, auto, 0);
width: 1px;
height: 100%;
transform-origin: 100% 50%;
transform: scaleX(0.5);
@media (min-resolution: 3dppx) {
transform: scaleX(0.33);
}
}
}
} @else if $direction == all {
border: 1px solid $color;
border-radius: $radius;
@media (min-resolution: 2dppx) {
position: relative;
border: none;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 200%;
height: 200%;
border: 1px solid $color;
border-radius: $radius * 2;
transform-origin: 0 0;
transform: scale(0.5);
box-sizing: border-box;
pointer-events: none;
}
}
}
}
// 移除边框
@mixin hairline-remove($position: all) {
@if $position == left {
border-left: 0;
&::before {
display: none !important;
}
} @else if $position == right {
border-right: 0;
&::after {
display: none !important;
}
} @else if $position == top {
border-top: 0;
&::before {
display: none !important;
}
} @else if $position == bottom {
border-bottom: 0;
&::after {
display: none !important;
}
} @else if $position == all {
border: 0;
&::before {
display: none !important;
}
&::after {
display: none !important;
}
}
}
使用格式
在某个scss文件中:
- 导入。导入上面封装的hairlinescss
- 使用:给某个选择器添加1px边框
选择器{
@include hairline()
}
示例
@import '@scss/hairline.scss';
.box1 {
margin: 10px 0;
position:relative;
@include hairline(bottom, #000);
@include hairline-remove(bottom);
}