Stylus 是一个富有表现力、动态且功能强大的 CSS 预处理器。它由 TJ Holowaychuk(Pug 模板引擎的作者)创建,与 Less 和 Sass 齐名,是前端开发中提高 CSS 编写效率和可维护性的重要工具之一。Stylus 以其高度灵活和简洁的语法而著称,允许开发者以多种方式编写 CSS,包括类似原生 CSS 的语法、省略括号和冒号的缩进语法等。
核心思想:Stylus 通过灵活的语法(可省略分号、冒号、括号),提供变量、混合、函数、条件判断、循环等高级特性,使 CSS 编写更高效、模块化和可维护。
一、Stylus 简介 1.1 什么是 CSS 预处理器? CSS 预处理器是一种编程语言,它允许你使用变量、函数、混合 (Mixins)、嵌套、继承等编程特性来编写 CSS。这些预处理器代码最终会被编译成浏览器能够理解的标准 CSS。它们解决了传统 CSS 编程性差、难以维护和复用的问题。
常见的 CSS 预处理器包括:Sass/SCSS、Less 和 Stylus。
1.2 Stylus 的特点
极度灵活的语法 :
可省略分号 :一行一个属性时,可省略分号。
可省略冒号 :属性名和属性值之间的冒号可省略。
可省略大括号 :嵌套规则时,大括号可省略,通过缩进来表示。
可省略 @import :直接写文件名即可导入。
可省略圆括号 :在某些函数调用、条件语句中可以省略。
功能强大 :支持变量、混合 (Mixins)、函数、条件判断 (if/else)、循环 (for/in)、逻辑运算符、算术运算等。
内建函数和插件 :提供了丰富的内建函数,并支持通过 JavaScript 或 Stylus 自身编写插件。
Node.js 环境 :基于 Node.js,与 Node.js 生态系统(如 Express、Webpack)无缝集成。
简洁和表现力 :通过其灵活的语法,可以编写出非常简洁且富有表现力的样式代码。
1.3 适用场景
大型或复杂的 CSS 项目,需要高度模块化和可维护性。
追求极致简洁和灵活语法的开发者。
Node.js 生态下的前端项目。
二、Stylus 的安装与使用 Stylus 作为 Node.js 模块发布,通常通过 npm 或 yarn 进行安装。
2.1 安装 全局安装 (方便命令行使用):
1 2 3 npm install -g stylus yarn global add stylus
项目依赖安装 (推荐):
1 2 3 npm install --save-dev stylus yarn add --dev stylus
2.2 命令行编译 如果全局安装了 Stylus,可以直接在命令行编译 .styl 文件。
style.styl:
1 2 3 4 5 6 body font 14px Arial, sans-serif color #333 p margin 10px 0
编译:
1 2 3 4 stylus style.styl -o style.css stylus style.styl -w -o style.css
输出 style.css:
1 2 3 4 5 6 7 body { font : 14px Arial, sans-serif; color : #333 ; } p { margin : 10px 0 ; }
2.3 在 Node.js 项目中使用 在 Node.js 中,可以通过中间件(如 Express)或构建工具(如 Webpack)来集成 Stylus。
2.3.1 Express 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 const express = require ('express' );const stylus = require ('stylus' ); const path = require ('path' );const app = express ();const port = 3000 ;app.use (stylus.middleware ({ src : path.join (__dirname, 'public' ), dest : path.join (__dirname, 'public' ), compile : function (str, path ) { return stylus (str) .set ('filename' , path) .set ('compress' , true ); } })); app.use (express.static (path.join (__dirname, 'public' ))); app.get ('/' , (req, res ) => { res.send ('<h1>Hello Stylus!</h1><link rel="stylesheet" href="/style.css">' ); }); app.listen (port, () => { console .log (`Stylus App running at http://localhost:${port} ` ); });
2.3.2 Webpack 示例 (需安装 stylus-loader) 1 2 3 npm install --save-dev stylus stylus-loader css-loader style-loader yarn add --dev stylus stylus-loader css-loader style-loader
webpack.config.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 module .exports = { module : { rules : [ { test : /\.styl$/ , use : [ 'style-loader' , 'css-loader' , 'stylus-loader' ] } ] } };
三、Stylus 核心语法详解 3.1 变量 变量以 $ 或不带前缀的标识符定义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $primary -color = #3498db $font -stack = Arial, sans-serifbody font-family $font -stack color $primary -color accent-color = #e74c3c .button background-color accent-color padding 10px 20px
编译为:
1 2 3 4 5 6 7 8 body { font-family : Arial, sans-serif; color : #3498db ; } .button { background-color : #e74c3c ; padding : 10px 20px ; }
3.2 混合器 (Mixins) Mixins 允许你定义一组可重用的 CSS 属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 shadow (x = 0 , y = 0 , blur = 5px , color = rgba(0 ,0 ,0 ,.5 ) ) -webkit-box-shadow x y blur color -moz-box-shadow x y blur color box-shadow x y blur color .card background-color #fff padding 20px shadow () .icon display inline-block width 24px height 24px shadow (2px , 2px , 10px , rgba (0 ,0 ,0 ,.3 ))
编译为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .card { background-color : #fff ; padding : 20px ; -webkit-box-shadow : 0 0 5px rgba (0 , 0 , 0 , 0.5 ); -moz-box-shadow : 0 0 5px rgba (0 , 0 , 0 , 0.5 ); box-shadow : 0 0 5px rgba (0 , 0 , 0 , 0.5 ); } .icon { display : inline-block; width : 24px ; height : 24px ; -webkit-box-shadow : 2px 2px 10px rgba (0 , 0 , 0 , 0.3 ); -moz-box-shadow : 2px 2px 10px rgba (0 , 0 , 0 , 0.3 ); box-shadow : 2px 2px 10px rgba (0 , 0 , 0 , 0.3 ); }
3.3 嵌套 (Nesting) 嵌套允许你将相关的 CSS 规则组织在一起,提高可读性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .menu margin 0 padding 0 list-style none li display inline-block a display block padding 10px 15px text-decoration none color #333 &:hover background-color #eee color red p font-size 12px
编译为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 .menu { margin : 0 ; padding : 0 ; list-style : none; } .menu li { display : inline-block; } .menu li a { display : block; padding : 10px 15px ; text-decoration : none; color : #333 ; } .menu li a :hover { background-color : #eee ; color : red; } .menu li a p { font-size : 12px ; }
3.4 导入 (Import) 使用 @import 导入其他 .styl 文件。Stylus 会自动查找文件。
_vars.styl:
1 2 primary-color = #007bff padding -base = 10px
_buttons.styl:
1 2 3 4 5 6 7 .btn display inline-block padding padding-base * 1.5 padding-base * 2 border-radius 4px background-color primary-color color #fff text-decoration none
main.styl:
1 2 3 4 5 6 @import '_vars.styl' @import '_buttons' body font-family sans-serif color primary-color
3.5 函数 (Functions) Stylus 允许你定义自己的函数,或者使用其丰富的内建函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 add-px (n) return n + 'px' .box width add-px (100 ) height add-px (50 ) .dark-bg background-color #333 color lighten (#333 , 50% ) // 将颜色亮度提高 50%
编译为:
1 2 3 4 5 6 7 8 .box { width : 100px ; height : 50px ; } .dark-bg { background-color : #333 ; color : #bfbfbf ; }
3.6 条件判断 (if/else) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 rounded (radius = 5px ) if radius is a 'string' or radius is a 'unit' and radius >= 0 border-radius radius else warning ('radius 必须为正值或字符串' ) .avatar rounded (10px ) .square rounded (0 ) .invalid rounded (-5px )
3.7 循环 (for/in) 1 2 3 4 5 6 7 8 9 10 11 for i in 1 ..3 .column-{i} width (100% / 3 ) * i colors = red green blue for color in colors .text-{color } color color
编译为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 .column-1 { width : 33.333333% ; } .column-2 { width : 66.666667% ; } .column-3 { width : 100% ; } .text-red { color : #f00 ; } .text-green { color : #008000 ; } .text-blue { color : #00f ; }
3.8 运算符 支持各种算术、比较、逻辑运算符。
1 2 3 4 5 6 7 8 9 container -width = 960px gutter = 20px .grid-item width (container-width - gutter * 2 ) / 3 margin-right gutter &:last-child margin-right 0
四、Stylus 的灵活语法 Stylus 最显著的特点是其语法灵活性,它可以让你以多种方式书写,兼容性强。
例如,下面的所有 Stylus 语法都将被编译成相同的 CSS:
标准 CSS 风格:
1 2 3 4 body { font-size : 14px ; color : #333 ; }
省略分号:
1 2 3 4 body { font-size : 14px color : #333 }
省略冒号和分号:
1 2 3 4 body { font-size 14px color #333 }
省略大括号(缩进):
1 2 3 body font-size 14px color #333
完全省略(最简洁):
1 2 3 4 5 6 7 body font-size 14px color #333 .header background-color #f0f0f0 padding 10px
这种灵活性使得开发者可以根据个人喜好或团队规范选择最合适的书写方式。
五、Stylus 的优缺点 5.1 优点
极度灵活的语法 :这是 Stylus 最大的亮点,允许开发者自由选择语法风格,可以写得像原生 CSS,也可以写得非常简洁。
功能强大 :变量、混合、函数、条件、循环等一应俱全,满足复杂的 CSS 编写需求。
JavaScript 扩展性 :可以轻松地在 Stylus 中调用 JavaScript 函数,甚至用 JavaScript 编写插件,提供了极高的扩展性。
简洁明了 :在采用缩进语法时,代码行数明显减少,可读性高。
基于 Node.js :与 Node.js 生态系统完美融合,便于集成到现代前端工作流。
5.2 缺点
生态系统相对较小 :相比于 Sass 和 Less,Stylus 的用户群体和第三方库(如 Mixin 库)规模较小。
学习曲线 :虽然灵活,但对于新手来说,多种语法风格可能反而增加选择困难或混淆。
调试稍复杂 :预处理器共同的缺点是编译后的 CSS 可能难以直接映射回源代码行数。
社区支持 :虽然文档齐全,但遇到问题时,可能不如 Sass/Less 容易找到解决方案。
六、结语 Stylus 是一个优秀且功能强大的 CSS 预处理器,尤其适合那些追求极致简洁和语法灵活性的开发者。它提供了一套完整的特性集,可以帮助你编写出更结构化、可维护和高效的 CSS 代码。尽管其生态系统不如 Sass 庞大,但其独特的语法和强大的功能使其在 Node.js 生态中拥有自己的一席之地。如果你习惯了基于缩进的语法(如 Pug、YAML)或者喜欢自定义语法风格,那么 Stylus 将是一个非常值得尝试的选择。