CSS preprocessor

What is a CSS preprocessor? In general, they extend their own DSLS based on CSS to solve problems that are difficult to solve when we write CSS:

  • Syntax is not powerful enough, such as the inability to write in a nested way, resulting in many repetitive selectors to be written in modular development;
  • The absence of variables and a reasonable style reuse mechanism makes it difficult to maintain logically related attribute values that must be repeatedly printed as literals.

Thus, the primary goal of the CSS preprocessor is to provide the missing CSS style layer reuse mechanism, reduce redundant code, and improve the maintainability of style code. This is not icing on the cake, but just a timely help.

Less abstract

The official website Less is a CSS preprocessing language, which extends the CSS language, adding variables, mixins, functions and other features, making CSS easier to maintain and expand. Less can run on Node or in a browser.

Less installation

The installationlesscFor global use

Lessc -v // Convert the. Less file to the. CSS file lessc xxx.less xxx. CSSCopy the code

Node Environment Installation

For details about how to configure less-loader, see

npm i less less-loader --save-dev
Copy the code

Less grammar

The Variables Variables

1. Variable definition

Variables can be defined before and after use, and variable declarations can be promoted. However, we recommend that you write at the beginning of all styles in less files for uniform variable management

// Variables
@color: red;
// Usage
a {
  color: @color;
}
Copy the code

2. Use variables in urls

You can define url prefixes that reference files, images, etc., using @{} to use variables within “” quotes

// Variables @images: ".. /img"; // Usage .less-demo { background: url("@{images}/bg.png"); }Copy the code

3. Selector variable interpolation

Definition variables can be used in selectors and style properties as @{}. Skinning can be achieved by changing the prefixes of different LESS variables.

// define @prefix: less; / / using the @ {prefix} - demo {. @ {prefix} - left {}. @ {prefix} {}} - right / / selector @ the selector: the test; .@{selector} { color: red; } // attribute @property: color; .top { @{property}: red; background-@{property}: gray; }Copy the code

4. The variable name

Reference a variable within a variable, via ~”@{variable name}- attribute value “. Can be used in mixins functions, by passing different parameters, achieve different styles, reduce code duplication.

// Base variable definition @prefix: less; @left-width: 40%; @left-color: blue; @right-color: red; @right-width: 60%; // usage .content-color(left); .content-color(right); // function. Content-color (@content) {.@{prefix}-@{content} {// Variable definition, values depending on the type @content-color: ~"@{content}-color"; @content-width: ~"@{content}-width"; color: @@content-font-color; width: @@content-width; .bordered; }}Copy the code

The compiled

.less-left {
  color: blue;
  width: 40%;
  border: 1px solid #333;
}
.less-right {
  color: red;
  width: 60%;
  border: 1px solid #333;
}
Copy the code

The Extend extension

1. The extension

The A selector wishes to have the style of the B selector by passing &:extend(the name of the B selector)

// The h1 tag extension has the h2 tag style attribute h1 {&:extend(h2); font-size: 16px; } h2 { color: #333; }Copy the code

The compiled

h1 {
    font-size: 16px;
}
h1, h2 {
    color: #333;
}
Copy the code

2. To expand all

B selector has multiple styles. To have all the styles of B selector, extend(B selector all) can be used

h2, .test-extend { color: #333; } .test-extend { font-size: 14px; } // Extend all style attributes of a selector. Test-expand-content :extend(. Test-extend all) {text-decoration: underline; }Copy the code

The compiled

h2, .test-extend, .test-expand-content {
    color: #333;
}
.test-extend, .test-expand-content {
    font-size: 14px;
}
.test-expand-content {
    text-decoration: underline;
}
Copy the code

Mixins hybrid

1. Selector mix

Define a class style that can be used directly in other styles. The important thing to note in this approach is that the class style definition is output. If the style is not used, it is recommended not to use the style definition method and generate redundant CSS code.

Bordered {border: 1px solid #333; } .demo { .left { width: 40%; .bordered; } .right { width: 60%; .bordered; }}Copy the code

The compiled

Bordered {border: 1px solid #333; } .demo .left { width: 40%; border: 1px solid #333; } .demo .right { width: 60%; border: 1px solid #333; }Copy the code

2. Namespace

Mixins are nested with # ID names to distinguish between different libraries and avoid conflicts when using multiple libraries

#my-library {
  .my-mixin() {
    color: black;
  }
}
// which can be used like this
.class {
  #my-library > .my-mixin();
}
Copy the code

The compiled

.class {
  color: black;
}
Copy the code

3. Parameterize the mix

When multiple parameters are passed in, the default value of parameters can be set. Parameters and parameters can be used directly. separated

Color (@bg: f5f5f5; @color: #333) { background-color: @bg; color: @color; } .left { .color(); } .right { .color(#f0f0f0; # 666); }Copy the code

4. @ the arguments variables

You can use @arguments to get all the arguments passed in

Box-shadow (@x: 0; @y: 0; @blur: 5px; @color: rgba(0, 0, 0, 0.2)) {-webkit-box-shadow: @arguments; -moz-box-shadow: @arguments; box-shadow: @arguments; } .demo{ .box-shadow(2px; 5px); }Copy the code

5. The rest parameters

. Represents a variable number of arguments (0-n), and @rest represents all arguments other than the specified one

.mixin(...) { // matches 0-N arguments .mixin() { // matches exactly 0 arguments .mixin(@a: 1) { // matches 0-1 arguments .mixin(@a: 1; ...). { // matches 0-N arguments .mixin(@a; ...). { // matches 1-N arguments .mixin(@a; @rest...) { // @rest is bound to arguments after @a // @arguments is bound to all arguments }Copy the code

6.! Important keywords

Use it after mixin! Important, all mixin attributes will be inherited, plus! important

.foo (@bg: #f5f5f5, @color: #900) { background: @bg; color: @color; } .unimportant { .foo(); } .important { .foo() ! important; }Copy the code

The compiled

.unimportant { background: #f5f5f5; color: #900; } .important { background: #f5f5f5 ! important; color: #900 ! important; }Copy the code

Mixins Guards defense

Conditional execution is implemented with the keyword when, according to the @media execution specification. The comparison operators: >, >=, =, =<, <, true are the only “true” values. Parameters can also be compared with each other. Logical operators: ‘and’,’,'(equivalent to or),’not’. Type verification functions: iscolor, isNumber, ISString, iskeyword, isURL. Unit function ispixel, ispercentage, isem, isunit.

.mixin (@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin (@a) {
  color: @a;
}
Copy the code

Detached Ruleset Set of separation rules

A split rule set, defined by the @ sign, is a collection of styles of CSS properties, nested rule sets, media declarations, and so on.

// declare detached ruleset @detached-ruleset: { background: red; }; // use detached ruleset .top { @detached-ruleset(); } // function. Desktop -and-old-ie(@media screen) {@media screen and (min-width: 1200) {@rules(); } html.lt-ie9 & { @rules(); } } header { background-color: blue; .desktop-and-old-ie({ background-color: red; }); } // scope #space { .importer-1() { @detached: { scope-detached: @variable; }; // define detached ruleset } } .importer-2() { @variable: value; // unlocked detached ruleset CAN see this variable #space > .importer-1(); // unlock/import detached ruleset } .use-place { .importer-2(); // unlock/import detached ruleset second time @detached(); }Copy the code

Loops loop

Use when to check that a function can be called in a loop until the condition is not met

.generate-columns(4);

.generate-columns(@n, @i: 1) when (@i =< @n) {
  .column-@{i} {
    width: (@i * 100% / @n);
  }
  .generate-columns(@n, (@i + 1));
}
Copy the code

Output:

.column-1 {
  width: 25%;
}
.column-2 {
  width: 50%;
}
.column-3 {
  width: 75%;
}
.column-4 {
  width: 100%;
}
Copy the code

Merge Merge attributes

Style merge with + and +_, the former separated by commas and the latter separated by Spaces

Mixin () {box-shadow+: inset 0 0 10px #555; } .myclass { .mixin(); box-shadow+: 0 0 20px black; } .mixin() { transform+_: scale(2); } .myclass { .mixin(); transform+_: rotate(15deg); }Copy the code

Output:

.myclass {
  box-shadow: inset 0 0 10px #555, 0 0 20px black;
}

.myclass {
  transform: scale(2) rotate(15deg);
}
Copy the code

Parent Selectors Parent Selectors &

.header {
    & &-title {
    }
    &-title {
    }
    &:first-child {
    }
    .less & {
    }
    & & {
    }
}
Copy the code

The compiled

.header .header-title {
}
.header-title {
}
.header:first-child {
}
.less .header {
}
.header .header {
}
Copy the code

@ the plugin plug-in

@plugin “my-plugin”; Define a plug-in JS file that returns a Less node. You can define the same name function for different files in the plug-in reference scope. Return false Calls this function but does not return an arbitrary value. After version 3.0, functions can return any type.

// function.js module.exports = {install(less, pluginManager, functions) {// return functions. Add ('args', functions) node => { if (typeof node.value === 'string') { return node.value; } let result = []; for (let i = 0; i < node.value.length; i++) { result.push(node.value[i].value); } return result.join(', '); }); }}; // usage @plugin "./functions"; .transition(...) { transition-property: args(@arguments); The transition - duration: 0.2 s; }Copy the code

The syntax for Less is summarized here. Where is wrong welcome to point out oh ~~ another productive day! 🆙

Reference article:

  1. Introduction to CSS preprocessing
  2. Less summary
  3. Less tutorial