预编译器基本原理
- 编写 css 时,受限于 css 语言本身,常常难以处理一些问题:
- 重复的样式值:例如常用颜色、常用尺寸;
- 重复的代码段:例如绝对定位居中、清除浮动;
- 重复的嵌套书写;
- 由于官方迟迟不对 css 语言本身做出改进,一些第三方机构开始想办法来解决这些问题,其中一种方案便是 预编译器,预编译器的原理很简单,即使用一种更加优雅的方式来书写样式代码,通过一个编译器,将其转换为可被浏览器识别的传统 css 代码;
- 目前,最流行的预编译器有 LESS 和 SASS;
less 的使用
less 安装、编译
-
安装:
# LESS 编译器是基于 node 开发的,可以通过 npm 下载安装 npm i -D less
-
编译方法一:在 nodejs 环境中使用 less
lessc styles.less styles.css
-
编译方法二:在浏览器环境中使用 less
<link rel="stylesheet/less" type="text/css" href="styles.less" /> <script src="http://cdnjs.cloudflare.com/ajax/libs/less.js/2.5.3/less.min.js"></script>
-
编译方法三:考拉 编译工具
-
编译方法四:vscode 插件 easy less
less 的基本使用
变量: 符号@
@selector: #header; /* 选择器 作为变量 */
@m: margin; /* 样式名 作为变量 */
@width: 10px; /* 样式值 作为变量 */
@{selector} {
@{m}: 20px;
width: @width;
background-color: red;
}
/* less 转换成 css */
#header {
margin: 20px;
width: 10px;
background-color: red;
}
嵌套
#header {
color: black;
/* 父子关系 */
.logo {
width: 300px;
}
}
.clearfix {
display: block;
zoom: 1;
/* & 同级 */
&:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
}
.component {
width: 300px;
@media (min-width: 768px) {
width: 600px;
@media (min-resolution: 192dpi) {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
width: 800px;
}
}
/* less 转换成 css */
#header {
color: black;
}
/* 父子关系 */
#header .logo {
width: 300px;
}
.clearfix {
display: block;
zoom: 1;
}
/* & 同级 */
.clearfix:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
.component {
width: 300px;
}
@media (min-width: 768px) {
.component {
width: 600px;
}
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
.component {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
.component {
width: 800px;
}
}
混合
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu {
color: antiquewhite;
.bordered();
}
.post {
color: red;
.bordered();
}
/* less 转换成 css */
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu {
color: antiquewhite;
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
.post {
color: red;
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
扩展:会把重复的代码抽离出去
@w: 200px;
@h: 200px;
.block {
width: @w;
height: @h;
border: 10px solid #ccc;
}
.box1:extend(.block) {
background: red;
}
.box2:extend(.block) {
background: green;
}
/* less 转换成 css */
.block,
.box1,
.box2 {
width: 200px;
height: 200px;
border: 10px solid #ccc;
}
.box1 {
background: red;
}
.box2 {
background: green;
}
命名空间:类似 js 对象.方法
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white;
}
}
.tab {
color: red;
}
.citation {
color: green;
}
}
#header a {
color: orange;
/* 还可以书写为 #bundle > .button 形式 */
#bundle.button();
}
/* less 转换成 css */
#header a {
color: orange;
display: block;
border: 1px solid black;
background-color: grey;
}
#header a:hover {
background-color: white;
}
映射
#colors() {
primary: blue;
secondary: green;
}
.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}
/* less 转换成 css */
.button {
color: blue;
border: 1px solid green;
}
作用域,先在本级作用域查找,找不到向上查找
@var: red;
#page {
#header {
color: @var;
}
@var: white;
}
/* less 转换成 css */
#page #header {
color: white;
}
循环
.gen-col(@n) when (@n > 0) {
/* 递归调用自身 */
.gen-col(@n - 1);
.col-@{n} {
width: 1000px/12*@n;
}
}
.gen-col(3);
/* less 转换成 css */
.col-1 {
width: 1000px/12*1;
}
.col-2 {
width: 1000px/12*2;
}
.col-3 {
width: 1000px/12*3;
}
导入 import
/* variable.less */
@themeColor: blue;
@fontSize: 14px;
/* module1.less */
.module1 {
.box {
font-size: @fontSize + 2px;
color: @themeColor;
}
}
/* module2.less */
.module2 {
.box {
font-size: @fontSize + 4px;
color: @themeColor;
}
}
/* importing.less */
@import "./variable.less";
@import "./module1.less";
@import "./module2.less";
/* less 转换成 css */
.module1 .box {
font-size: 16px;
color: blue;
}
.module2 .box {
font-size: 18px;
color: blue;
}
sass 的使用
sass 安装、编译
-
安装
npm i -D sass
-
编译方法一:命令编译
sass --watch styles.scss styles.css
-
编译方法二:GUI 界面工具编译
- Koala - 推荐
- Compass.app
- Scout
- CodeKit - 推荐
- Prepros
-
编译方法三:自动化编译 (利用 Grunt、Gulp、webpack)
sass 的基本使用
sass 变量: 符号$
$nav-color: #F90;
nav {
$width: 100px;
width: $width;
color: $nav-color;
}
/* 将局部变量转换为全局变量可以添加 !global 声明 */
#main {
$width: 5em !global;
width: $width;
}
#sidebar {
width: $width;
}
/* scss 转换成 css */
nav {
width: 100px;
color: #F90;
}
#main {
width: 5em;
}
#sidebar {
width: 5em;
}
sass 嵌套
#content {
article {
h1 {
color: #333
}
p {
margin-bottom: 1.4em
}
}
aside {
background-color: #EEE
}
}
/* scss 转换成 css */
#content article h1 {
color: #333;
}
#content article p {
margin-bottom: 1.4em;
}
#content aside {
background-color: #EEE;
}
sass 混入: @mixin声明/@include调用
/* 公用代码 */
@mixin rounded-corners {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}
/* 给混合器传参 */
@mixin link-colors($normal, $hover, $visited) {
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
a {
@include link-colors(blue, red, green);
}
/* scss 转换成 css */
/* 公用代码 */
.notice {
background-color: green;
border: 2px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
/* 给混合器传参 */
a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }
sass 扩展: @extend
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
/* scss 转换成 css */
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
sass 循环
/***
* @for $i from <start> through/to <end>
* $i 表示变量
* start 表示起始值
* end 表示结束值
* through 表示包括 end 这个数
* to 则不包括 end 这个数
*/
@for $i from 1 through 2 {
.col-#{$i} {
width: 1000px/12*$i;
}
}
/* scss 转换成 css */
.col-1 {
width: 83.33333px;
}
.col-2 {
width: 166.66667px;
}
sass 导入
/* variable.scss */
$themeColor: blue;
$fontSize: 14px;
/* module1.scss */
.module1 {
.box {
font-size: $fontSize + 2px;
color: $themeColor;
}
.tips {
font-size: $fontSize;
color: lighten($themeColor, 40%);
}
}
/* module2.scss */
.module2 {
.box {
font-size: $fontSize + 4px;
color: $themeColor;
}
.tips {
font-size: $fontSize + 2px;
color: lighten($themeColor, 20%);
}
}
/* importing.less */
@import "./variable.scss";
@import "./module1.scss";
@import "./module2.scss";
/* scss 转换成 css */
.module1 .box {
font-size: 16px;
color: blue;
}
.module1 .tips {
font-size: 14px;
color: #ccccff;
}
.module2 .box {
font-size: 18px;
color: blue;
}
.module2 .tips {
font-size: 16px;
color: #6666ff;
}
webpack 中使用 less、scss
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: "development",
devServer: {
open: true
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", 'css-loader'],
},
{
test: /\.less$/,
use: ["style-loader", 'css-loader', 'less-loader'],
},
{
test: /\.s[ac]ss$/,
use: ["style-loader", 'css-loader', 'sass-loader'],
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html"
})
]
}
css 工程化👉 css 模块化
上一篇