引言
在项目中遇到1px问题,后搜寻很多解决办法但没有能统一解决整个vue项目边框的办法,一个一个边框写样式很麻烦,所以有了这篇总结。主要是将样式写在main.js全局引用的样式文件中,将样式class命名为.border等,在组件中需要边框的div直接为其加一个class=border即可
为什么会有1px像素问题
一般来说拿到的UI设计稿给出的是物理像素的设计,而css在设置时设置的是css像素,所以才会出现1px像素问题。比如在二倍屏中,长度上1个css像素=2个物理像素,UI给出1物理像素边框,在css中就得写成0.5px,但不支持小数的border,所以无法设置。如果在css中设置为1px,实际上就是2物理像素,比UI给出的边框粗
做如下设置
得到边框如下
明显比1px粗
如何解决
一般采用transform: scale(0.5) 方案
解决方法
为了方便,我会把1px像素的代码提出来写在vue项目下的asset里,在main.js中引入,在组件中想要边框的div为其加.border类
代码目录
index.scss中把需要的样式整合,border.scss用来解决1px像素问题,reset.scss用来reset(scss中引用用@import)
在main.js中引用index.js,就是整个项目都可用的样式了
比如在home.vue中想要给一个div设置1px像素边框,直接为其加border类
<template>
<div class="home">
<div class="test-part border">
</div>
</div>
</template>
得到结果如下
比之前细了,同时还有圆角
border.scss代码
.border{
position: relative;
}
.border::after {
content: '';
position: absolute;
left: 0;
top: 0;
border: 1px solid #000000;
border-radius: 26px;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
原理
现有一个绿色的div
.test-part2{
height: 43px;
width: 100px;
background-color: #42b983;
}
为其加一个:after伪类
.test-part2:after{
content: 'hello';
border: 1px solid #000000;
}
如下
看出来位置大小不太对,设置一下(子为绝对定位时,需要父有position, 所以设置为relative)
.test-part2{
height: 43px;
width: 100px;
background-color: #42b983;
position: relative;
}
.test-part2:after{
content: 'hello';
border: 1px solid #000000;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
结果如下
边框现在是粗的,因为是二倍屏,进行缩放,在.test-part2:after中加一行代码:transform: scale(.5),结果如下
长度宽度都进行缩放了,所以把之前设置的width和height改为200%
.test-part2{
height: 43px;
width: 100px;
background-color: #42b983;
position: relative;
}
.test-part2:after{
content: '';
border: 1px solid #000000;
position: absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
transform: scale(.5);
}
结果如下
位置不太对,因为缩放的原点没有设置,元素默认基点就是其中心位置,换句话说我们没有使用transform-origin改变元素基点位置的情况下,transform进行的rotate,translate,scale,skew,matrix等操作都是以元素自己中心位置进行变化的,具体见transform-origin。所以加一行 transform-origin: left top; 相当于transform-origin: 0 0
代码最后更改为
.test-part2{
height: 43px;
width: 100px;
background-color: #42b983;
position: relative;
}
.test-part2:after{
content: '';
border: 1px solid #000000;
position: absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
transform: scale(.5);
transform-origin: left top;
}
结果如下,就已经实现了,如果想加圆角,直接在伪类中加border-radius
为了方便使用,把这段代码提取出来到border.css中,如上‘代码目录’所示
优化
1.border-top等
有时候只需要一边border,所以对border.scss进行丰富了,添加了border-top, border-bottom, border-left, border-right的class
.border,
.border-top,
.border-bottom,
.border-left,
.border-right {
position: relative;
}
.border:after,
.border-top:after,
.border-bottom:after,
.border-left:after,
.border-right:after {
content: '';
position: absolute;
left: 0;
top: 0;
border-radius: 26px;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
.border:after {
border: 1px solid #000000;
}
.border-top:after {
border-top: 1px solid #000000;
}
.border-bottom:after {
border-top: 1px solid #000000;
}
.border-left:after {
border-top: 1px solid #000000;
}
.border-right:after {
border-top: 1px solid #000000;
}
用的时候直接给div加border-top的class,如下
<template>
<div class="home">
<div class="test-part border-top">
</div>
</div>
</template>
效果如下
2. 单独设置圆角或设置颜色
有时候边框需要圆角,不同组件边框颜色也不同,在组件中单独设置即可,圆角、颜色都在.border:after里设置
<template lang="pug">
div.home
div.test-part.border
</template>
<script>
export default {
name: 'home',
}
</script>
<style lang="scss">
.home {
.test-part{
height: 43px;
width: 100px;
}
.border:after {
border-radius: 20px;
border: 1px solid #42b983;
}
}
结果如下
3. 二倍屏、三倍屏
增加媒体查询,分类处理
.border,
.border-top,
.border-bottom,
.border-left,
.border-right {
position: relative;
}
.border:after,
.border-top:after,
.border-bottom:after,
.border-left:after,
.border-right:after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
.border:after {
border: 1px solid #000000;
}
.border-top:after {
border-top: 1px solid #000000;
}
.border-bottom:after {
border-top: 1px solid #000000;
}
.border-left:after {
border-top: 1px solid #000000;
}
.border-right:after {
border-top: 1px solid #000000;
}
/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.33);
transform: scaleY(0.33);
width: 300%;
height: 300%;
}
}