CSS3 专家级编程(五)
原文zh.annas-archive.org/md5/2789AE2FE8CABD493B142B2A68E84610译者飞龙协议CC BY-NC-SA 4.0第十四章最终自动化和流程优化在这最后一章中我们将讨论在创建 CSS 代码过程中重复流程的最终自动化。有很多流程可以自动化但是意识到它是否可以做到以及使用的工具的知识是必不可少的。在本章中我们将专注于工具以及如何在 Gulp 任务运行器中实现自动化。在本章中我们将涵盖以下主题视网膜和移动设备上的图像如何识别未使用的 CSS如何压缩代码如何从页面列表中制作截图以便快速概览如何使用 Jade 模板的基础知识并将其编译到 Gulp 中Gulp在本书的开头我介绍了 Gulp 作为 SASS 的入门。但是仅仅使用 Gulp 来编译 SASS 可能是浪费时间的。在本章中我们将向 Gulp 添加更多任务这些任务可以作为前端开发人员使用并将帮助你优化你的代码。Jade 作为你的模板引擎在大型项目的情况下编写 HTML 文件可能会有问题。页面的可重复元素的维护比如主导航页脚边栏在需要处理 10 个文件时可能会成为一个问题。每次你想要更改页脚中的内容你都需要更新 10 个文件。当一个项目有 50 个模板时情况会变得更加复杂。你可以开始使用 PHP 或任何包含重复代码部分的文件的语言或者使用其中一个模板语言。有多种模板系统。以下是一些知名和时髦的模板系统手柄HAMLJadeSlim让我们专注于 Jade。为什么因为有以下功能混合支持主模板文件的部分化缩进的语法类似于 SASS安装和使用 JadeJade 是通过 node 包管理器安装的。你可以用以下命令安装它npm install jade --global如果你想编译一些文件只需要调用 HTML 文件如下jade filename.html更多信息我建议你查看 Jade 模板系统的官方文档jade-lang.com/。Jade 的基础知识理论介绍很重要但让我们试着将代码的这部分描述成 Jadenav ul lia href#Home/a/li lia href#About/a/li lia href#Contact/a/li /ul /nav在 Jade 中它会是这样的nav ul lia(href#)Home lia(href#)About lia(href#)Contact你可以看到你不需要考虑标准的 HTML 问题“我的标签关闭了吗”缩进会跟踪标签的开启和关闭。你想要附加到标签中的每个文本都会出现在标签描述名称和属性后的空格后。让我们看一下代码的这部分a(href#)Home这部分代码将被编译成a href#Home/a如你所见在 Jade 中属性href出现在元素名称a之后用括号括起来。让我们看一下我们将要翻译成 Jade 的 HTML 代码的下一部分head meta charsetutf-8 titlePage title/title link relstylesheethrefcss/main.cssmediascreentitleno titlecharsetutf-8 /head这部分代码将在所有页面上重复出现因为它包含了我们 HTML 的head标签。在 Jade 中它会是这样的headmeta(charsetutf-8)title Page titlelink(relstylesheet,hrefcss/main.css,mediascreen,titleno title,charsetutf-8)在这里你可以看到如何向 HTML 元素添加更多属性。在link元素中括号中的每个属性都用逗号分隔。代码的下一部分与带有类和 ID 的 DOM 元素有关main idmain article classmain--article a href# img srcimg/error_log.pngalt/ span classcomments/span /a h3Lorem ipsum dolor sit amet,consectetur adipisicing elit/h3 p sed do eiusmod tempor incididunt ut labore et dolore /p a href#classreadmoreRead more/a /article /main在 Jade 中代码看起来是这样的main#main article.main--articlea(href#)img(srcimg/error_log.png,altError log).comments h3 Lorem ipsum dolor sit amet p sed do eiusmod tempor incididunt ut labore et dolorea(href#).readmore Read more你可以看到你不需要描述这部分main idmain这是写成这样的main(idmain)在 Jade 中有一个简短的形式main#main类似的情况也适用于类article classmain--article你也可以使用一个简短的形式article.main--article这种简短的方法使 Jade 易于理解因为它基于 CSS 中使用的选择器。Jade 中的混合Jade 中的混合很有用特别是当网页上有一些可重复的元素时。例如可能是一些带有href的小元素amixinlink(href,name)a(href href)name现在我们需要做的就是将它添加到你的模板中link(url,Your link)在你编译的文件中你会看到a hrefurlYour link/a在 Jade 中包含和扩展功能如前所述我们可以将代码的部分保存在单独的文件中。这样做的最简单方法是使用include方法。假设我们已经在文件navigation.jade中定义了主要的nav并且我们希望在我们的模板中添加其内容。代码如下文件名是navigation.jadenav ul lia(href#)Home lia(href#)About lia(href#)Contact文件名是template.jadedoctype html html headmeta(charsetutf-8)title Page titlelink(relstylesheet,hrefcss/main.css,mediascreen,titleno title,charsetutf-8)body include _navigation.jade当您编译template.jade时您将得到!DOCTYPE html html head meta charsetutf-8 titlePage title/title link relstylesheethrefcss/main.cssmediascreentitleno titlecharsetutf-8 /head body nav ul lia href#Home/a/li lia href#About/a/li lia href#Contact/a/li /ul /nav /body /html这是一个很好的时机来使用可以扩展的主布局。这可以通过代码操作来完成。第一次操作必须在主模板中进行 - 定义一个将在我们的 HTML 文件中交换的块。第二次需要在将代表最终 HTML 文件的文件中完成 - 指定将扩展的主模板。代码如下文件名是master.jadedoctype html html headmeta(charsetutf-8)title Page titlelink(relstylesheet,hrefcss/main.css,mediascreen,titleno title,charsetutf-8)body include _navigation.jade block content文件名是index.jadeextends master block content h1 Content编译后的文档!DOCTYPE html html head meta charsetutf-8 titlePage title/title link relstylesheethrefcss/main.cssmediascreentitleno titlecharsetutf-8 /head body nav ul lia href#Home/a/li lia href#About/a/li lia href#Contact/a/li /ul /nav h1Content/h1 /body /html在 gulp.js 中使用 Jade要在gulpfile.js中创建或添加 Jade 任务您需要使用npm安装特定的包gulp-jade。要这样做请使用以下命令npm install --save gulp-jade然后您需要在gulpfile.js中定义一个新任务并为模板添加一个监视器该模板将存储在src/jade目录中。以下是来自本书第一章的扩展gulpfile.js的清单var gulp require(gulp),sass require(gulp-sass),jade require(gulp-jade);gulp.task(sass, function (){return gulp.src(src/css/main.sass).pipe(sass().on(error,sass.logError)).pipe(gulp.dest(dist/css/main.css));});gulp.task(jade, function(){gulp.src(src/jade/*.jade).pipe(jade()).pipe(gulp.dest(dist/));});gulp.task(default, function (){gulp.watch(src/sass/*.sass,[sass]);gulp.watch(src/jade/*.jade,[jade]);});它会表现如何每当您更改src/jade文件夹中的任何文件时编译后的文件将会出现在dist文件夹中。当然如果您愿意这种结构可以更改这只是使用示例。随意更改它UnCSS有多少次你面对过这样的情况HTML 中没有使用某些类/选择器但在 CSS 代码中有描述每当您的项目更改或重新设计时这种情况都会发生。例如您的任务是删除某些部分并在 HTML 代码中添加几行。因此您将添加一些 CSS 代码然后删除其中的一些。但您确定 CSS 代码不包含未使用的 CSS 代码部分吗UnCSS 将帮助您完成此任务。要安装它您需要执行此命令npm install -g uncss让我们来看看在npm命令中使用的标志标志描述-g全局安装--save本地安装这些包将出现在package.json的dependencies部分。这些包是在生产中运行应用程序所需的。--save-dev本地安装这些包将出现在package.json的devDependencies部分。这些包是用于开发和测试过程的。在 Gulp 中集成 UnCSS首先我们需要通过npm安装gulp-uncssnpm install --save gulp-uncss现在我们需要在gulpfile.js中添加新的任务。我们需要在项目中创建一个测试阶段该阶段将存储在test目录中。您需要这些新任务来基于uncss进行处理gulp.task(clean-css-test, function (){return gulp.src(test/css/main.css,{read:false}) .pipe(rimraf({force:true}));});gulp.task(jade-test, function(){return gulp.src(src/jade/templates/*.jade).pipe(jade()).on(error,gutil.log).pipe(gulp.dest(test/));});gulp.task(sass-test,[clean-css-test], function (){return gulp.src(src/sass/main.sass).pipe(sass().on(error,sass.logError)).pipe(gulp.dest(test/css/));});gulp.task(uncss,[jade-test, sass-test], function (){return gulp.src(test/css/main.css) .pipe(uncss({html:[test/**/*.html]})).pipe(gulp.dest(./test/uncss));});要运行uncss任务您需要使用以下命令gulp uncss此命令将执行以下任务将 Jade 文件编译到test文件夹中从test文件夹中删除旧的 CSS 文件将 SASS 文件编译到test文件夹中运行uncss任务并将文档保存为test/uncss文件夹中仅使用的 CSS 部分现在我们需要实时测试。我们将准备一个简短的测试环境。以下是文件的结构├── jade │ ├── master_templates │ │ └── main.jade │ ├── partials │ │ ├── footer.jade │ │ └── navigation.jade │ └── templates │ ├── about.jade │ ├── contact.jade │ └── index.jade └── sass └── main.sass代码如下文件名是main.jadedoctype html html headmeta(charsetutf-8)title Page titlelink(relstylesheet,hrefcss/main.css,mediascreen,titleno title,charsetutf-8)body include ../partials/navigation block content include ../partials/footer文件名是navigation.jadenav ul lia(href#)Home lia(href#)About lia(href#)Contact文件名是footer.jadefooter p Copyright fedojo.com文件名是index.jadeextends ../master_templates/main block content .main p Test of INDEX page文件名是about.jadeextends ../master_templates/main block content .main h1 Test of ABOUT page文件名是contact.jadeextends ../master_templates/main block content .main h1 Test of CONTACT page文件名是main.sassbodybackground:#fff pcolor:#000 .headerbackground:#000color:#fff .footerbackground:#000color:#fff headerbackground:#000color:#fff footerbackground:#000color:#fff现在让我们检查这个过程对我们是否有利。这是从 SASS 编译的文件body{background:#fff;}p{color:#000;}.header{background:#000;color:#fff;}.footer{background:#000;color:#fff;}header{background:#000;color:#fff;}footer{background:#000;color:#fff;}此文件由uncss检查它查看了所有模板index.htmlabout.html和contact.htmlbody{background:#fff;}p{color:#000;}footer{background:#000;color:#fff;}我们的新命令是用 Gulp 构建的删除了所有不必要的 CSS 声明。压缩 CSS缩小文件的过程主要应该用于生产代码。在开发过程中对缩小的文件进行操作会很困难因此我们只需要为生产代码进行缩小。可以通过添加适当的标志--compressed来启用 SASS 或 Compass 编译中的缩小。我们还将使用一个外部工具在uncss过程之后对代码进行缩小。现在我们需要安装gulp-clean-cssnpm install --save gulp-clean-css现在缩小uncss过程的结果。我们将创建一个prod目录其中存储项目的最终版本。现在让我们导入gulp-clean-csscleanCSS require(gulp-clean-css)让我们在gulpfile.js中创建所需的部分gulp.task(clean-css-production, function (){return gulp.src(prod/css/main.css,{read:false}) .pipe(rimraf({force:true}));});gulp.task(sass-production,[clean-css-production], function (){return gulp.src(src/sass/main.sass) .pipe(sass().on(error, sass.logError)) .pipe(uncss({html:[prod/**/*.html]})).pipe(cleanCSS()).pipe(gulp.dest(prod/css/));});gulp.task(jade-production, function(){return gulp.src(src/jade/templates/*.jade).pipe(jade()).pipe(gulp.dest(prod/));});gulp.task(production,[jade-production,sass-production]);最终的自动化工具现在我们需要将之前创建的所有任务汇总到一个文件中。gulp项目的核心是两个文件package.json它汇总了所有项目依赖以及gulpfile你可以在其中存储所有任务。以下是任务文件名是package.json{name:automatizer,version:1.0.0,description:CSS automatizer,main:gulpfile.js,author:Piotr Sikora,license:ISC,dependencies:{gulp:latest,gulp-clean-css:latest,gulp-jade:latest,gulp-rimraf:latest,gulp-sass:latest,gulp-uncss:latest,gulp-util:latest,rimraf:latest}}文件名是gulpfile.jsonvar gulp require(gulp),sass require(gulp-sass),jade require(gulp-jade),gutil require(gulp-util),uncss require(gulp-uncss),rimraf require(gulp-rimraf),cleanCSS require(gulp-clean-css);gulp.task(clean-css-dist, function (){return gulp.src(dist/css/main.css,{read:false}) .pipe(rimraf({force:true}));});gulp.task(clean-css-test, function (){return gulp.src(test/css/main.css,{read:false}) .pipe(rimraf({force:true}));});gulp.task(sass,[clean-css-dist], function (){return gulp.src(src/sass/main.sass).pipe(sass().on(error,sass.logError)).pipe(gulp.dest(dist/css/));});gulp.task(jade, function(){return gulp.src(src/jade/templates/*.jade).pipe(jade()).pipe(gulp.dest(dist/));});gulp.task(jade-test, function(){return gulp.src(src/jade/templates/*.jade).pipe(jade()).on(error,gutil.log).pipe(gulp.dest(test/));});gulp.task(sass-test,[clean-css-test], function (){return gulp.src(src/sass/main.sass).pipe(sass().on(error,sass.logError)).pipe(gulp.dest(test/css/));});gulp.task(uncss,[jade-test, sass-test], function (){return gulp.src(test/css/main.css) .pipe(uncss({html:[test/**/*.html]})).pipe(gulp.dest(test/uncss));});gulp.task(clean-css-production, function (){return gulp.src(prod/css/main.css,{read:false}) .pipe(rimraf({force:true}));});gulp.task(sass-production,[clean-css-production], function (){return gulp.src(src/sass/main.sass) .pipe(sass().on(error, sass.logError)) .pipe(uncss({html:[prod/**/*.html]})).pipe(cleanCSS()).pipe(gulp.dest(prod/css/));});gulp.task(jade-production, function(){return gulp.src(src/jade/templates/*.jade).pipe(jade()).pipe(gulp.dest(prod/));});gulp.task(production,[jade-production,sass-production]);gulp.task(default, function (){gulp.watch(src/sass/*.sass,[sass]);gulp.watch(src/jade/*.jade,[jade]);});总结在本章中我们讨论了 Jade 模板系统的基础知识。我们看到了如何将其添加到前端开发人员的工作流程中。基于模板系统你现在可以将 UnCSS 包含到你的流程中并从 CSS 文件中删除不必要的代码。然后我们对最终结果进行了缩小并创建了生产代码。你可以将这个自动化工具视为项目的起点并根据自己的项目进行调整。你也可以添加新功能并不断完善它。

相关新闻

突破显卡性能瓶颈:NVIDIA Profile Inspector深度优化指南

突破显卡性能瓶颈:NVIDIA Profile Inspector深度优化指南

突破显卡性能瓶颈:NVIDIA Profile Inspector深度优化指南 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 当你在《艾尔登法环》的交界地艰难前行时,突然遭遇帧率从60骤降至30的卡…

2026/7/2 23:15:53 阅读更多 →
腾讯混元翻译终端Hunyuan-MT Pro:多场景应用全解析

腾讯混元翻译终端Hunyuan-MT Pro:多场景应用全解析

腾讯混元翻译终端Hunyuan-MT Pro:多场景应用全解析 1. 为什么需要专业级翻译工具? 在日常工作和生活中,我们经常遇到需要翻译的场景:阅读外文资料、与海外客户沟通、处理多语言文档等。虽然市面上有很多在线翻译工具&#xff0c…

2026/5/17 5:30:29 阅读更多 →
Whisper-large-v3在智能家居中的应用:语音控制与场景联动

Whisper-large-v3在智能家居中的应用:语音控制与场景联动

Whisper-large-v3在智能家居中的应用:语音控制与场景联动 1. 引言 你有没有经历过这样的场景:晚上躺在床上准备睡觉,突然想起客厅的灯还没关,但又懒得起身?或者做饭时双手沾满面粉,想调节空调温度却无从下…

2026/7/4 22:48:15 阅读更多 →

最新新闻

AIC/BIC 模型选择实战:Python 3步实现线性回归与Lasso变量筛选

AIC/BIC 模型选择实战:Python 3步实现线性回归与Lasso变量筛选

AIC/BIC 模型选择实战:Python 3步实现线性回归与Lasso变量筛选在数据科学和机器学习领域,模型选择是一个永恒的话题。面对同一个数据集,我们往往可以构建无数个不同的模型,但如何从中选出最优的那个?这就是AIC&#xf…

2026/7/6 12:49:33 阅读更多 →
AI视频生成实战:扣子SKILL一键制作产品宣传片

AI视频生成实战:扣子SKILL一键制作产品宣传片

1. AI视频生成实战:用扣子SKILL一键制作产品宣传片 最近在帮客户制作产品宣传片时,发现了一个效率神器——扣子平台的Seedance 2.0视频生成功能。这个工具最吸引我的地方在于,它把原本需要专业团队协作数天的工作流程,简化成了几个…

2026/7/6 12:49:33 阅读更多 →
RINDNet 多类型边缘检测实战:BSDS-RIND 数据集 4 类边缘联合训练

RINDNet 多类型边缘检测实战:BSDS-RIND 数据集 4 类边缘联合训练

RINDNet多类型边缘检测实战:从环境配置到工业级应用全解析在计算机视觉领域,边缘检测作为基础却至关重要的技术,长期以来都是研究热点。传统边缘检测方法如Canny、Sobel等算子虽能提取通用边缘,却难以区分边缘的物理本质——这正是…

2026/7/6 12:49:33 阅读更多 →
Claude Code沙箱与强制访问控制:为AI编码助手构建纵深安全防线

Claude Code沙箱与强制访问控制:为AI编码助手构建纵深安全防线

1. 项目概述:为什么我们需要为AI编码助手戴上“紧箍咒”?最近在开发者圈子里,Claude Code的热度持续攀升,无论是VSCode的集成配置,还是与DeepSeek等开源模型的联动,都成了大家讨论的焦点。但与此同时&#…

2026/7/6 12:45:29 阅读更多 →
YOLOv8数据集配置文件data.yaml详解与最佳实践

YOLOv8数据集配置文件data.yaml详解与最佳实践

1. YOLOv8数据集配置文件基础解析 在目标检测项目中,data.yaml文件是YOLOv8模型训练的核心配置文件之一。这个看似简单的YAML文件实际上承载着整个数据集的元信息,直接影响模型的训练效果和泛化能力。作为从业者,我经常遇到因为配置文件编写不…

2026/7/6 12:43:26 阅读更多 →
汽车碰撞仿真CAE实战:HyperWorks与LS-DYNA高效应用指南

汽车碰撞仿真CAE实战:HyperWorks与LS-DYNA高效应用指南

1. 项目概述:汽车碰撞仿真CAE的核心价值 汽车碰撞仿真是现代汽车研发中不可或缺的环节。作为一名从业十年的CAE工程师,我亲历了从物理碰撞试验到虚拟仿真验证的行业变革。HyperWorks与LS-DYNA的组合,就像给工程师配备了一套数字化的碰撞实验室…

2026/7/6 12:41:24 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻