1px question
border-image
The picture needs to be prepared separately, and the rounded corners are not very easy to handle, but it can handle most scenes.
Judging different device pixel ratios based on media queries given different border-images:
.border_1px {
border-bottom: 1px solid #000;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border_1px {
border-bottom: none;
border-width: 0 0 1px 0;
border-image: url(../img/1pxline.png) 0020 stretch;
}
}
background-image
The picture needs to be prepared separately, and the rounded corners are not very easy to handle, but it can handle most scenes.
Similar to border-image, prepare a qualified border background image and simulate it on the background.
.border_1px {
border-bottom: 1px solid #000;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border_1px {
background: url(../img/1pxline.png) repeat-x left bottom;
background-size: 100% 1px;
}
}
svg
With PostCSS's postcss-write-svg we can directly use border-image and background-image to create a 1px border of svg:
@svg border_1px {
height: 2px;
@rect {
fill: var(--color, black);
width: 100%;
height: 50%;
}
}
.example {
border: 1px solid transparent;
border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch;
}
Pseudo class + transform
Based on the media query, it is judged that different device pixel ratios are used to scale the lines:
.border_1px:before {
content: '';
position: absolute;
top: 0;
height: 1px;
width: 100%;
background-color: #000;
transform-origin: 50% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border_1px:before {
transform: scaleY(0.5);
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
.border_1px:before {
transform: scaleY(0.33);
}
}
Pseudo class + transform (upgraded version)
principle:
- Mainly by adding to the target element
position:relative
; - Then use its pseudo class
:after
or:before
draw an element with 2 times or 3 times the width and height; - Then draw a 1px border for the pseudo-class element;
- By
media query
deciding to scale pseudo-class elements to 1/2 or 1/3; - Add pseudo-class elements
pointer-events: none;
, so that pseudo-class elements can be clicked through, that is, can be seen, but do not trigger any default events (click, etc.);
encapsulation
After scss encapsulation:
@mixin thinBorder($directionMaps: bottom, $color: #ccc, $radius:(0, 0, 0, 0), $position: after)
$directionMaps
: It is a list type that can be passed in multiple directions, that is, multiple defense borders can be generated. The default value is bottom, and you can pass in (top, left, bottom, right) 4 directions according to your needs;$color
: Border color, default#ccc
;$radius
: Corner radius, default 0;$position
It is an advanced setting, and generally does not need to be changed. Since the realization of the thin border uses the pseudo-class of css, in order to avoid possible style conflicts, we can specify whether to use it:after
or:before
defaultafter
;
@mixin thinBorder($directionMaps: bottom, $color: #ccc, $radius:(0, 0, 0, 0), $position: after) {
// 是否只有一个方向
$isOnlyOneDir: string==type-of($directionMaps);
@if ($isOnlyOneDir) {
$directionMaps: ($directionMaps);
}
@each $directionMap in $directionMaps {
border-#{$directionMap}: 1px solid $color;
}
// 判断圆角是list还是number
@if(list==type-of($radius)) {
border-radius: nth($radius, 1) nth($radius, 2) nth($radius, 3) nth($radius, 4);
}
@else {
border-radius: $radius;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
& {
position: relative;
// 删除1像素密度比下的边框
@each $directionMap in $directionMaps {
border-#{$directionMap}: none;
}
}
&:#{$position} {
content: "";
position: absolute;
top: 0;
left: 0;
display: block;
width: 200%;
height: 200%;
transform: scale(0.5);
box-sizing: border-box;
padding: 1px;
transform-origin: 0 0;
pointer-events: none;
border: 0 solid $color;
@each $directionMap in $directionMaps {
border-#{$directionMap}-width: 1px;
}
// 判断圆角是list还是number
@if(list==type-of($radius)) {
border-radius: nth($radius, 1)*2 nth($radius, 2)*2 nth($radius, 3)*2 nth($radius, 4)*2;
}
@else {
border-radius: $radius*2;
}
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
&:#{$position} {
// 判断圆角是list还是number
@if(list==type-of($radius)) {
border-radius: nth($radius, 1)*3 nth($radius, 2)*3 nth($radius, 3)*3 nth($radius, 4)*3;
}
@else {
border-radius: $radius*3;
}
width: 300%;
height: 300%;
transform: scale(0.3333);
}
}
}
use
- single border
@each $dir in (top,right,bottom,left) { .border-#{$dir}-#{1}px { @include thinBorder( $dir); } }
- Multi-Side Border
.border-top-left-red-1px{ @include thinBorder((top,left), red); }
- rounded border
.border-top-left-red-1px{ @include thinBorder(top, red, 100px); }
- Use: before to generate borders
.border-top-before{ @include thinBorder(top, red, 0, before); }