前端工程化_CSS 工具链_学习笔记

CSS 工具链

css 呢,有以下两个缺点

1.语法缺失(循环、判断、拼接)

2.功能缺失(颜色函数、数学函数、自定义函数)

虽然 CSS 支持几个函数,比如:

url('') 用于引入外部资源

calc() 计算函数,计算尺寸、间距等

linear-gradient 渐变函数

但还是太少了

这时候有人就创造了新语言

新语言是 CSS 的超集

新语言 -编译器-> CSS语言

本文讲一讲 sass

sass/less/stylus -CSS预编译器-> CSS语言

预处理器

body{
    background-color: #f40;
}

写了一个纯粹的 CSS 代码

然后需要用到预编译器

使用命令下载

npm i -g sass

然后就可以使用 sass 这个命令了,这里需要注意 node 版本不能太低,需要12以上,我这里用的是18

image-20241214203333782

使用命令转换

sass 1.scss 1.css
image-20241214203501601

生成了两个,一个是 CSS,一个是源码地图,是用于调试的,下一篇博文也会提到

使用命令

sass 1.scss 1.css --no-source-map

就会生成源码地图了

image-20241214203710804

目前左右没用区别

下面可以使用变量

sass 1.scss 1.css --no-source-map -w

watch 表示监听文件的变化

image-20241214204044368 重新编译之后就变成绿色了

下面来用 sass 写一个星空背景

sass index.scss index.css -w --no-source-map

其中 html 代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div class="layer1"></div>
    <div class="layer2"></div>
    <div class="layer3"></div>
    <div class="title">星空</div>
</body>
</html>

当前效果

image-20241215200111937

设置阴影

html {
    height: 100%;
    background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
    overflow: hidden;
}

.title {
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    color: #fff;
    text-align: center;
    font-family: "lato", sans-serif;
    font-weight: 300;
    font-size: 50px;
    letter-spacing: 10px;
    margin-top: -60px;
    padding-left: 10px;
    background: linear-gradient(white, #38495a);
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
}

.layer1 {
    $size: 100px;
    position: fixed;
    width: $size;
    height: $size;
    border-radius: 50%;
    left: 0;
    right: 0;
    background-color: #fff;
    box-shadow: 10vw 10vh #fff;
}
image-20241215200714782

阴影是可以设置多个的

box-shadow: 10vw 10vh #fff, 20vw 20vh #fff, 30vw 30vh #fff, 40vw 40vh #fff;
image-20241215200846781

那这样就有一个思路了,能不能做成一个循环,循环的生成这些阴影,像 js 就一个 for 搞定,可是 css 没有循环

但是 scss 里面有循环,可以自定义函数

这个函数要做的无非是字符串的拼接

js 中用的是 $,这里是 #

@function createShadow($n){
    $shadow:'10vw 10vh #fff';
    @for $i from 2 through $n {
        $shadow: '#{$shadow}, 10vw 10vh #fff';
    }
    @return $shadow;
}

因为拼接的是字符串,所以返回带了“”,用 sass 里面的 unquote 去掉双引号

image-20241215202226191

可以看到现在都是偏移同一个量

@function createShadow($n) {
    $shadow: '#{random(100)}vw #{random(100)}vh #fff';

    @for $i from 2 through $n {
        $shadow: '#{$shadow}, #{random(100)}vw #{random(100)}vh #fff';
    }

    @return unquote($shadow);
}

改成这样,生成0-100随机数

image-20241215203024151

然后把星星改成一个像素即可

image-20241215203120503

有那味了

那么接下来就是星星的往上移动

.layer1 {
    $size: 4px;
    position: fixed;
    width: $size;
    height: $size;
    border-radius: 50%;
    left: 0;
    right: 0;
    background-color: #fff;
    box-shadow: createShadow(200);
    animation: moveUp 5s linear infinite;
}

@keyframes moveUp{
    100%{
        transform: translateY(-100vh);
    }
}

现在的问题就是星星只移动一半,星星底移动到视口顶之后再回到原来位置

image-20241215204825296

这样处理就可以了,复制一份星星

可以把下面的星星作为上面的子元素

    &::after {
        content: '';
        position: fixed;
        left: 0;
        top: 100vh;
        width: inherit;
        height: inherit;
        border-radius: inherit;
        box-shadow: inherit;
    }
image-20241215205206198

这样添加

image-20241215205326843

稳稳的,没有问题了

搞定了一个层之后,我们要搞定多个层

那么就希望循环生成选择器

@for $i from 1 through 3 {
    .layer#{$i} {
        $size: 1px;
        position: fixed;
        width: $size;
        height: $size;
        border-radius: 50%;
        left: 0;
        right: 0;
        box-shadow: createShadow(200);
        animation: moveUp 5s linear infinite;

        &::after {
            content: '';
            position: fixed;
            left: 0;
            top: 100vh;
            width: inherit;
            height: inherit;
            border-radius: inherit;
            box-shadow: inherit;
        }

    }
}

这下可以 layer1、2、3了

image-20241215205751038

然后是处理星星个数和星星大小

$count: 1000;

@for $i from 1 through 3 {
    $count: floor(calc($count/2));
    @debug $count;
    .layer#{$i} {
        $size: #{$i}px;
        position: fixed;
        width: $size;
        height: $size;
        border-radius: 50%;
        left: 0;
        right: 0;
        box-shadow: createShadow($count);
        animation: moveUp 5s linear infinite;

        &::after {
            content: '';
            position: fixed;
            left: 0;
            top: 100vh;
            width: inherit;
            height: inherit;
            border-radius: inherit;
            box-shadow: inherit;
        }

    }
}

这样处理,越大的星星就越少

再改一下时间

$count: 1000;
$duration:400s;
@for $i from 1 through 3 {
    $count: floor(calc($count/2));
    $duration:floor(calc($duration/2));
    @debug 'count: #{$count}';
    @debug 'duration: #{$duration}';
    .layer#{$i} {
        $size: #{$i}px;
        position: fixed;
        width: $size;
        height: $size;
        border-radius: 50%;
        left: 0;
        right: 0;
        box-shadow: createShadow($count);
        animation: moveUp $duration linear infinite;

        &::after {
            content: '';
            position: fixed;
            left: 0;
            top: 100vh;
            width: inherit;
            height: inherit;
            border-radius: inherit;
            box-shadow: inherit;
        }

    }
}

啪的一下,像模像样了

image-20241215213820544 image-20241215213227147

显然 css 的代码比 scss 代码多了很多,这就是工程化的意义

SCSS 的出现让我们可以使用到很多的新语法和新功能,从而增强 CSS 目的,提升我们的开发效率

后处理器

image-20241214215239678

后处理器:

  • 厂商前缀:autoprefixer
  • 代码压缩:cssnano
  • 代码剪枝:purgecss
  • 类名冲突:css module

不管是预处理器还是后处理器,做的都是转换

转换就是这些东西的共同逻辑

比如说日期选择的组件,其实就是在做抽象

对于日期选择进一步抽象就是下拉选择/下拉框+日期选择

抽象下拉框就不仅适用于日期选择了,也可以下拉列表等等

做出通用的下拉框就是更高级别的抽象

再抽象,触发+弹出

image-20241214220228168

这其实和 JS 里面的 babel 逻辑是一样的

使用命令

npm install --save-dev postcss postcss-cli
image-20241215214441549

来了,postcss、postcss-cli 其实和 babel-core、babel-cli 是可以类比的

npm install --save-dev postcss postcss-cli postcss-modules postcss-preset-env tailwindcss autoprefixer

package.json 加上内容

{
  "name": "basic",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "compile": "postcss src/**/*.css -d dist -w --no-map"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.49",
    "postcss-cli": "^11.0.0",
    "postcss-modules": "^6.0.1",
    "postcss-preset-env": "^10.1.2",
    "tailwindcss": "^3.4.16"
  }
}

tailwind.config.js 也配置一下

module.exports = {
    content: [
        "./src/**/*.{html,js,jsx,ts,tsx,css}", // 扫描 src 目录下的所有文件
        "./public/index.html",                 // 包括 HTML 文件
    ],
    theme: {
        extend: {},
    },
    plugins: [],
};

postcss.config.js 也配置一下

module.exports = {
    plugins: {
      'postcss-preset-env': { stage: 1 }, // 支持最新的 CSS 特性
      'tailwindcss': {},                 // TailwindCSS 支持
      'autoprefixer': {},                // 添加浏览器前缀
      'postcss-modules': {               // 启用 CSS Modules
        generateScopedName: '[name]__[local]___[hash:base64:5]',
      },
    },
  };

我的结构是这样的

image-20241215220707927

可以看到编译后类名变了

image-20241215220012337

同时还会出来 json 做类名映射

image-20241215220056198

这个又有加厂商前缀

image-20241215220223547

这就是 postcss

tailwind

tailwind:称为原子化 CSS,是基于 postcss 的一个插件

image-20241215220344995

这三行编译完就是这么多内容

这就是插件能力

END

本文主要介绍了 CSS 工具链,可以看出工具链的出现都是为了解决语言的问题,文中就介绍了预处理器和后处理器,预处理器主要介绍了 sass,并举了星空这个例子,sass 是通过与预编译器编译成 css 后给 html 使用;后处理器则介绍了 postcss,其中 postcss 和 babel 类似,都有很多插件,简单介绍了一下 tailwind 这个原子化 CSS,它也是 postcss 的一个插件

posted @ 2024-12-16 10:48  goicandoit  阅读(6)  评论(0编辑  收藏  举报