常用的CSS样式

447 阅读8分钟

1. CSS修改滚动条样式:scrollbar

/* 修改滚动条样式 */  
/* 设置滚动条 */  
::-webkit-scrollbar {  
    width: 10px;  
    height: 10px;  
    background-color: #f5f5f5;  
    border-radius: 5px;  
}  
  
/* 设置滚动条滑块 */  
::-webkit-scrollbar-thumb {  
    background-color: #ccc;  
    border-radius: 5px;  
}  
  
/* 设置滚动条滑块在悬停状态下的背景色和圆角 */  
::-webkit-scrollbar-thumb:hover {  
    background-color: #999;  
    border-radius: 5px;  
}  
  
/* 设置滚动条轨道的背景色和圆角 */  
::-webkit-scrollbar-track {  
    background-color: #f5f5f5;  
    border-radius: 5px;  
}  
  
/* 设置滚动条轨道在悬停状态下的背景色和圆角 */  
::-webkit-scrollbar-track:hover {  
    background-color: #ccc;  
}  
  
::-webkit-scrollbar-corner{  
    background-color: cyan;  
}  
  
::-webkit-scrollbar-track-piece{  
    background-color: green;  
}  
  
::-webkit-resizer{  
    background-color: rgb(242, 5, 151);  
}  
::-webkit-scrollbar-button{  
    background-color: pink;  
    border-radius: 20px;  
    width: 20px;  
}
  • ::-webkit-scrollbar :可以设置滚动条的大小、颜色、圆角
  • ::-webkit-scrollbar-thumb:设置滚动条的滑块
  • ::-webkit-scrollbar-track:设置滚动条轨道(滑块可滑动区域)
  • ::-webkit-scrollbar-track-piece:设置没有滑块的轨道部分
  • ::-webkit-scrollbar-corner:设置水平和垂直滚动条交叉部分的背景色。
  • ::-webkit-resizer:当元素设置为可拖动时(resize: horizontal | vertical | both),元素底角会出现可调整元素大小的滑块。
  • ::webkit-scrollbar-button:设置滚动条两端的上下(左右)滚动按钮(上下、左右箭头)。

2. 单行文本溢出省略

.single {  
    display:inline-block; // 需要设置溢出设置需要是块状元素  
    width:150px; //设置宽度  
    overflow: hidden;//溢出隐藏,一定要设置,不设置会超出显示  
    white-space: nowrap; // 强制一行显示  
    text-overflow: ellipsis;// 显示。。。省略号  
}

3. 使用SCSS实现切换主题色

js实现切换主题色

/** 设置主题 */
changeTheme(data) {
    // 给根节点设置data-theme属性,切换主题色就是修改data-theme的值,这里data=dark/light
    window.document.documentElement.setAttribute('data-theme', data); 
}

SCSS配置多种主题色

[data-theme='light'] & {    
    // 判断html的data-theme的属性值
    bgColor1: #ffffff,     
    bgColor2: #333333,     
    fontColor1: rgba(0000.5),     
    fontColor2: #333333,     
    border1: 1px solid #e5e5e5,     
    border2: 1px solid #ffffff,     
    opacity1: 0.7
}

[data-theme='dark'] & {    
    // 判断html的data-theme的属性值
    bgColor1: #1a1a1a,     
    bgColor2: #000000,     
    fontColor1: rgba(2552552550.8),     
    fontColor2: #999999,     
    border1: none,     
    border2: 1px solid #000000,     
    opacity1: 1
}

4. 可视化大屏vw vh适配方案

实现思路

按照设计稿的尺寸,将px按比例计算转为vwvh,转换公式如下

假设设计稿尺寸为 1920*1080(做之前一定问清楚 ui 设计稿的尺寸)
即:网页宽度=1920px网页高度=1080px
我们都知道网页宽度=100vw网页宽度=100vh
所以,在 1920px*1080px 的屏幕分辨率下
1920px = 100vw
1080px = 100vh
这样一来,以一个宽 300px 和 200px 的 div 来说,其所占的宽高,以 vw 和 vh 为单位,计算方式如下:
vwDiv = (300px / 1920px ) * 100vwvhDiv = (200px / 1080px ) * 100vh
所以,就在 1920*1080 的屏幕分辨率下,计算出了单个 div 的宽高
当屏幕放大或者缩小时,div 还是以 vw 和 vh 作为宽高的,就会自动适应不同分辨率的屏幕

css 方案 - sass

util.scss

// 使用 scss 的 math 函数,https://sass-lang.com/documentation/breaking-changes/slash-div@use "sass:math";
// 默认设计稿的宽度$designWidth: 1920;// 默认设计稿的高度$designHeight: 1080;
// px 转为 vw 的函数@function vw($px) {  @return math.div($px, $designWidth) * 100vw;}
// px 转为 vh 的函数@function vh($px) {  @return math.div($px, $designHeight) * 100vh;}

路径配置
只需在vue.config.js里配置一下utils.scss的路径,就可以全局使用了

vue.config.js

const path = require("path");
function resolve(dir) {  return path.join(__dirname, dir);}
module.exports = {  publicPath: "",  configureWebpack: {    name: "app name",    resolve: {      alias: {        "@": resolve("src"),      },    },  },  css: {    // 全局配置 utils.scs,详细配置参考 vue-cli 官网    loaderOptions: {      sass: {        prependData: `@import "@/styles/utils.scss";`,      },    },  },};

在 .vue 中使用

<template>    <div class="box">          </div></template>
<script>export default{    name: "Box",}</script>
<style lang="scss" scoped="scoped">/*  直接使用 vw 和 vh 函数,将像素值传进去,得到的就是具体的 vw vh 单位      */.box{    width: vw(300);    height: vh(100);    font-size: vh(16);    background-color: black;    margin-left: vw(10);    margin-top: vh(10);    border: vh(2) solid red;}</style>

css 方案 - less

utils.less

@charset "utf-8";
// 默认设计稿的宽度@designWidth: 1920;
// 默认设计稿的高度@designHeight: 1080;
.px2vw(@name, @px) {  @{name}: (@px / @designWidth) * 100vw;}
.px2vh(@name, @px) {  @{name}: (@px / @designHeight) * 100vh;}
.px2font(@px) {  font-size: (@px / @designWidth) * 100vw;}

路径配置
vue.config.js里配置一下utils.less

const path = require("path");
function resolve(dir) {  return path.join(__dirname, dir);}
module.exports = {  publicPath: "",  configureWebpack: {    name: "app name",    resolve: {      alias: {        "@": resolve("src"),      },    },  },  css: {    // 全局配置utils.scss    loaderOptions: {      less: {        additionalData: `@import "@/styles/utils.less";`,      },    },  },};

在 .vue 文件中使用

<template>    <div class="box">          </div></template>
<script>export default{    name: "Box",}</script>
<style lang="less" scoped="scoped">/*  直接使用 vw 和 vh 函数,将像素值传进去,得到的就是具体的 vw vh单位      */.box{    .px2vw(width, 300);    .px2vh(height, 100);    .px2font(16);    .px2vw(margin-left, 300);    .px2vh(margin-top, 100);    background-color: black;}</style>

定义 js 样式处理函数

// 定义设计稿的宽高const designWidth = 1920;const designHeight = 1080;
// px转vwexport const px2vw = (_px) => {  return (_px * 100.0) / designWidth + 'vw';};
export const px2vh = (_px) => {  return (_px * 100.0) / designHeight + 'vh';};
export const px2font = (_px) => {  return (_px * 100.0) / designWidth + 'vw';};

屏幕变化后,图表自动调整

这种使用方式有个弊端,就是屏幕尺寸发生变化后,需要手动刷新一下才能完成自适应调整

为了解决这个问题,你需要在各个图表中监听页面尺寸变化,重新调整图表,在 vue 项目中,也可以借助element-resize-detector,最好封装个 resize 的指令,在各图表中就只要使用该指令就可以了,毕竟作为程序员,能偷懒就偷懒

  1. 安装 element-resize-detector

npm install element-resize-detector --save

  1. 引入工具包在组件中使用或者在单独的 js 中使用

import resizeDetector from 'element-resize-detector'

  1. 封装 directive

    // directive.jsimport * as ECharts from "echarts";import elementResizeDetectorMaker from "element-resize-detector";import Vue from "vue";const HANDLER = "_vue_resize_handler";function bind(el, binding) {  el[HANDLER] = binding.value    ? binding.value    : () => {        let chart = ECharts.getInstanceByDom(el);        if (!chart) {          return;        }        chart.resize();      };  // 监听绑定的div大小变化,更新 echarts 大小  elementResizeDetectorMaker().listenTo(el, el[HANDLER]);}function unbind(el) {  // window.removeEventListener("resize", el[HANDLER]);  elementResizeDetectorMaker().removeListener(el, el[HANDLER]);  delete el[HANDLER];}// 自定义指令:v-chart-resize 示例:v-chart-resize="fn"Vue.directive("chart-resize", { bind, unbind });
    
  2. main.js 中引入

    import '@/directive/directive';
    
  3. html 代码

    <template>  <div class="linechart">    <div ref="chart" v-chart-resize class="chart"></div>  </div></template>
    

这里要注意的是,图表中如果需要 tab 切换动态更新图表数据,在更新数据时一定不要用 echarts 的 dispose 方法先将图表移除,再重新绘制,因为 resize 指令中挂载到的图表实例还是旧的,就监听不到新的 chart 元素的 resize 了,更新数据只需要用 chart 的 setOption 方法重新设置配置项即可。

图表字体、间距、位移等尺寸自适应

echarts 的字体大小只支持具体数值(像素),不能用百分比或者 vw 等尺寸,一般字体不会去做自适应,当宽高比跟 ui 稿比例出入太大时,会出现文字跟图表重叠的情况

这里我们就需要封装一个工具函数,来处理图表中文字自适应了👇

  • 默认情况下,这里以你的设计稿是 1920*1080 为例,即网页宽度是 1920px (做之前一定问清楚 ui 设计稿的尺寸)
  • 把这个函数写在一个单独的工具文件dataUtil.js里面,在需要的时候调用
  • 其原理是计算出当前屏幕宽度和默认设计宽度的比值,将原始的尺寸乘以该值
  • 另外,其它 echarts 的配置项,比如间距、定位、边距也可以用该函数
  1. 编写 dataUtil.js 工具函数

    // Echarts图表字体、间距自适应export const fitChartSize = (size,defalteWidth = 1920) => {  let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;  if (!clientWidth) return size;  let scale = (clientWidth / defalteWidth);  return Number((size*scale).toFixed(3));}
    
  2. 将函数挂载到原型上

    import {fitChartSize} from '@src/utils/dataUtil.js'Vue.prototype.fitChartFont = fitChartSize;
    
  3. 这样你可以在.vue文件中直接使用this.fitChartSize()调用

    <template>  <div class="chartsdom" ref="chart" v-chart-resize></div></template>
    <script>export default {  name: "dashboardChart",  data() {    return {      option: null,    };  },  mounted() {    this.getEchart();  },  methods: {    getEchart() {      let myChart = this.$echarts.init(this.$refs.chart);      const option = {        backgroundColor: "transparent",        tooltip: {          trigger: "item",          formatter: "{a} <br/>{b} : {c}%",        },        grid: {          left: this.fitChartSize(10),          right: this.fitChartSize(20),          top: this.fitChartSize(20),          bottom: this.fitChartSize(10),          containLabel: true,        },        calculable: true,        series: [          {            color: ["#0db1cdcc"],            name: "计划投入",            type: "funnel",            width: "45%",            height: "70%",            x: "5%",
                minSize: "10%",            funnelAlign: "right",
                center: ["50%", "50%"], // for pie
                data: [              {                value: 30,                name: "下单30%",              },              {                value: 55,                name: "咨询55%",              },              {                value: 65,                name: "点击65%",              },              {                value: 60,                name: "访问62%",              },              {                value: 80,                name: "展现80%",              },            ].sort(function (a, b) {              return a.value - b.value;            }),            roseType: true,            label: {              normal: {                formatter: function () {},                position: "inside",              },            },            itemStyle: {              normal: {                borderWidth: 0,                shadowBlur: this.fitChartSize(20),                shadowOffsetX: 0,                shadowOffsetY: this.fitChartSize(5),                shadowColor: "rgba(0, 0, 0, 0.3)",              },            },          },
              {            color: ["#0C66FF"],            name: "实际投入",            type: "funnel",            width: "45%",            height: "70%",            x: "50%",
                minSize: "10%",            funnelAlign: "left",
                center: ["50%", "50%"], // for pie
                data: [              {                value: 35,                name: "下单35%",              },              {                value: 40,                name: "咨询40%",              },              {                value: 70,                name: "访问70%",              },              {                value: 90,                name: "点击90%",              },              {                value: 95,                name: "展现95%",              },            ].sort(function (a, b) {              return a.value - b.value;            }),            roseType: true,            label: {              normal: {                position: "inside",              },            },            itemStyle: {              normal: {                borderWidth: 0,                shadowBlur: this.fitChartSize(20),                shadowOffsetX: 0,                shadowOffsetY: this.fitChartSize(5),                shadowColor: "rgba(0, 0, 0, 0.3)",              },            },          },        ],      };      myChart.setOption(option, true);    },  },  beforeDestroy() {},};</script>
    <style lang="scss" scoped>.chartsdom {  width: 100%;  height: 100%;}</style>
    

5. sass里提取卡片背景样式

@mixin cardBackground($url:'card_primary.png'){
  background-size100% 100%;
  background-repeat: no-repeat;
  position: absolute;
  right:0;
  top:0;
  border-radius8px;
  width50%;
  height100%;
  &::after {
    content'';
    display: block;
    width50px;
    height50px;
    background-imageurl("@/static/image/#{$url}");
    background-size120%;
    background-repeat: no-repeat;
    position: absolute;
    right12px;
    bottom12px;
  }
}

.merc-card-primary {
  @include cardBackground('card_primary.png');
  background-image: linear-gradient(to left,rgba(13,123,255,0.08) 0%,rgba(13,123,255,0) 100%);
}

注释:

  • $url 为 混入方法变量,#{}为字符串里面包括变量的语法