移动端1px边框解决方案
移动端 1px 边框问题通用解决方案:scss mixin 版本
注意:本方案采用伪元素 + transform
的解决方案,在设置边框的元素有交互动作时,请设置子元素定位以及 z-index
值。
border.scss
css
@mixin genBorderRaidus ($radius: null, $ratio: 1) {
@if ($radius != null) {
@if (type-of($radius) == list) {
border-radius: nth($radius, 1)*$ratio nth($radius, 2)*$ratio nth($radius, 3)*$ratio nth($radius, 4)*$ratio;
} @else {
border-radius: $radius*$ratio;
}
}
}
@mixin genBorderRules ($rule: width, $directions: null, $values: null) {
// 默认 border-style 为 solid
@if ($rule == style and $values == null) {
$values: solid;
}
@if ($values != null) {
// directions 为列表,分别设置 top/right/bottom/left 等位置的样式
@if (type-of($directions) == list) {
$dirMap: (
top: 1,
right: 2,
bottom: 3,
left: 4
);
@if (type-of($values) == list) {
@each $dir in $directions {
border-#{$dir}-#{$rule}: nth($values, map-get($dirMap, $dir));
}
} @else {
@each $dir in $directions {
border-#{$dir}-#{$rule}: $values;
}
}
}
// dierections 为 null,默认为全边框
@else if ($directions == null) {
@if (type-of($values) == list) {
border-#{$rule}: nth($values, 1) nth($values, 2) nth($values, 3) nth($values, 4);
} @else {
border-#{$rule}: $values;
}
}
// directions 其余情况为单边设置
@else {
@if (type-of($values) == list) {
border-#{$directions}-#{$rule}: nth($values, 1) nth($values, 2) nth($values, 3) nth($values, 4);
} @else {
border-#{$directions}-#{$rule}: $values;
}
}
}
}
@mixin genBorder (
$directions: null,
$style: solid,
$color: null,
$radius: null,
$position: after
) {
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
@include genBorderRules(width, $directions, 1px);
@include genBorderRules(style, $directions, $style);
@include genBorderRules(color, $directions, $color);
@include genBorderRaidus($radius, 1);
}
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
& {
position: relative;
// 移除 border 采用伪类实现
border: 0;
border-radius: 0;
}
&::#{$position} {
content: '';
display: block;
position: absolute;
left: 0;
top: 0;
width: 200%;
height: 200%;
transform-origin: 0 0;
transform: scale(0.5);
@include genBorderRules(width, $directions, 1px);
@include genBorderRules(style, $directions, $style);
@include genBorderRules(color, $directions, $color);
@include genBorderRaidus($radius, 2);
}
}
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
& {
position: relative;
// 移除 border 采用伪类实现
border: 0;
border-radius: 0;
}
&::#{$position} {
content: '';
display: block;
position: absolute;
left: 0;
top: 0;
width: 300%;
height: 300%;
transform-origin: 0 0;
transform: scale(0.33333);
@include genBorderRules(width, $directions, 1px);
@include genBorderRules(style, $directions, $style);
@include genBorderRules(color, $directions, $color);
@include genBorderRaidus($radius, 3);
}
}
}
测试代码
index.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<title>1px border</title>
<link rel="stylesheet" href="./index.scss" />
</head>
<body>
<div class="wrapper">
<div class="border"></div>
<div class="border-left"></div>
<div class="border-left-right"></div>
<div class="border-top-right"></div>
<div class="border-top-right-bottom"></div>
<div class="border-left-right-radius-10"></div>
<div class="border-tob-bottom-blue-radius-10"></div>
<div class="border-blue"></div>
<div class="border-dashed-red"></div>
<div class="border-red-radius-10"></div>
</div>
</body>
</html>
css
css
@import './border.scss';
.wrapper {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
width: 100%;
color: orange;
> * {
width: 50px;
height: 50px;
margin: 10px;
background-color: #f8f8f8;
}
.border {
@include genBorder();
}
.border-left {
@include genBorder(left);
}
.border-left-right {
@include genBorder((left,right));
}
.border-top-right {
@include genBorder((top,right));
}
.border-top-right-bottom {
@include genBorder((top,right,bottom))
}
.border-left-right-radius-10 {
@include genBorder((left,right), solid, null, 10px)
}
.border-tob-bottom-blue-radius-10 {
@include genBorder((top,bottom), solid, blue, 10px)
}
.border-blue {
@include genBorder(null, solid, blue);
}
.border-dashed-red {
@include genBorder(null, dashed, red);
}
.border-red-radius-10 {
@include genBorder(null, solid, red, 10px);
}
}