css变量,1px问题,px怎么变成vw

334 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

大家好,我是大帅子,今天我们直接给大家介绍css变量,1px问题,px怎么变成vw, 众所周知移动端现在已经横行霸道,那么我们今天就讲一下移动端的问题,今天都是基础的,也就当给大家复习一下啦,下面我们直接开始吧


1. css变量

当我们css中出出现好多重复的颜色字体大小的时候,我们就可以用到以下的办法了, 分为局部变量全局变量

1. 局部变量

.box1 {
    /* 只能在当前的变量里面使用 */
    --my-height : 100px;
    height : var(--my-height)
}

2. 全局变量

/* 全局变量 */
.root {
    --my-color : yellow;
}

.box1 {
    background : var(--my-color);
}

.box2 {
    background : var(--my-color);
}

2. 1px 的问题

这个问题也是我们写移动端经常碰到的问题,下面直接给大家两种解决方案

1. 伪元素transform缩放

<!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">
    <title>1px 问题</title>
    <style>
        body {margin:0;padding:19px}
        div { padding:1em;margin:1em;}
        .box1{border-top: 1px solid #000;}
        .box2{position: relative;border-bottom:1px solid #000;}
        .box2::after{
            content:'';
            position: absolute;
            left:0;top:0;width: 100%;
            height: 1px; 
            background-color: #000;
            transform: scaleY(0.5);
        }
    </style>
</head>
<body>
    <div class="box1">
        1px的上边框
    </div>

    <div class="box2">
        0.5px的上边框
    </div>
</body>
</html>

2. scss 处理方案

创建公共样式

实现参考 antd-mobile

创建公共样式文件:hairline.scss。用它来实现1px效果

// 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文件中:

  1. 导入。导入上面封装的hairline.scss

  2. 使用:给某个选择器添加1px边框

    选择器 {
      @include hairline(参数,xxxx)
    }
    

示例

@import '~@scss/hairline.scss';
​
.box1 {
  margin: 10px 0;
  position:relative;
  @include hairline(bottom, #000); // 添加边框
  // 移除边框
  // @include hairline-remove(bottom); 
}

3.px=>vw

步骤

postcss-px-to-viewport 文档

  1. 安装 px 转 vw 的包:npm i -D postcss-px-to-viewport

    • 包的作用:将 px 转化为 vw```,所以有了该工具,只需要在代码中写 px` 即可
  2. craco.config.js 添加相应配置

  3. 重启项目,让配置生效

核心代码

craco.config.js

const pxToViewport = require('postcss-px-to-viewport')
const vw = pxToViewport({
  // 视口宽度,一般就是 375( 设计稿一般采用二倍稿,宽度为 375 )
  viewportWidth: 375
})
​
module.exports = {
  // 此处省略 webpack 配置
  webpack: {},
​
  // 这里补充style配置
  style: {
    postcss: {
      plugins: [vw]
    },
    // postcss8的新写法
    postcss: {
      mode: 'extends',
      loaderOptions: {
        postcssOptions: {
          ident: 'postcss',
          plugins:[vw]
        }
      }
    }
  }
}

好了,这边已经给大家介绍到这里,以上是我自己的理解,希望可以帮到大家, 欢迎留言我这边一定会第一时间给大家解答,喜欢的可以点赞收藏,
🐣---->🦅        还需努力!大家一起进步!!!