introduce

Less is a dynamic style language. It belongs to the CSS preprocessing language. It extends the CSS language by adding variables, mixins, functions, and other features to make CSS easier to maintain and extend.

Less can run on Node or browser.

annotation

Looks that start with // are not compiled into CSS files; comments wrapped in /**/ are

variable

Use @ to declare a variable

  1. As a normal attribute value

    @nice-blue: #5B83AD;
    @light-blue: @nice-blue + # 111;
    
    #header {
      color: @light-blue;
    }
    Copy the code
  2. For selectors and property names: @{variable name}

    // Variables
    @my-selector: banner;
    
    // Usage
    .@{my-selector} {
      font-weight: bold;
      line-height: 40px;
      margin: 0 auto;
    }
    
    @fnord:  "I am fnord.";
    @var:    "fnord";
    content: @@var;	// content: "I am fnord.";
    Copy the code
  3. As a URL: @{URL}

    // Variables
    @images: ".. /img";
    
    // Usage
    body {
      color: # 444;
      background: url("@{images}/white-sand.png");
    }
    Copy the code
  4. Lazy loading of variables

    @var: 0;
    .class {
      @var: 1;
      .base {
        @var: 2;
        z-index: @var;	/ / 3; Wait until the scope is loaded
        @var: 3;
      }
      z-index: @var;	/ / 1
    }
    Copy the code

Nested rules

  1. Basically nested rules

    #header {
      color: black;
      .navigation {
        font-size: 12px;
      }
      .logo {
        width: 300px; }}Copy the code
  2. The use of &

    // 1. Apply pseudo-classes to existing selectors
    .clearfix {
      display: block;
      zoom: 1;
    
      &:after {
        content: "";
        display: block;
        font-size: 0;
        height: 0;
        clear: both;
        visibility: hidden; }}// 2. Generate duplicate class names
    .button {
      &-ok {	// .button-ok
        background-image: url("ok.png");
      }
      &-cancel {	// .button-cancel
        background-image: url("cancel.png");
      }
    
      &-custom {	// .button-custom
        background-image: url("custom.png"); }}// 3. Repeat the parent selector
    .link {
      & + & {	// .link + .link
        color: red;
      }
    
      & & {	// .link .link 
        color: green;
      }
    
      && {	// .link.link
        color: blue;
      }
    
      &.&ish {	// .link, .linkish
        color: cyan; }}// 4. & represents all parent selectors (not just recent ancestors)
    .grand {
      .parent {
        & > & {	// .grand .parent > .grand .parent
          color: red;
        }
    
        & & {	// .grand .parent .grand .parent
          color: green;
        }
    
        && {	// .grand .parent.grand .parent
          color: blue;
        }
    
        &.&ish {	// .grand .parent, .grand .parentish
          color: cyan; }}}Copy the code

hybrid

Mixing is how a set of attributes is introduced from one rule set to another

  1. Ordinary hybrid

    // Parentheses are optional when you call a mixin.
    .a.#b {
      color: red;
    }
    .mixin-class {
      .a(a); }.mixin-id {
      #b(a); }Copy the code
  2. Mixing without output

    // Create a mixin but don't want to print the mixin, you can put parentheses after it.
    .my-mixin {
      color: black;
    }
    .my-other-mixin() {
      background: white;
    }
    .class {
      .my-mixin;
      .my-other-mixin;
    }
    
    / / output
    .my-mixin {
      color: black;
    }
    .class {
      color: black;
      background: white;
    }
    Copy the code
  3. Mix with selector

    .my-hover-mixin() {
      &:hover {
        border: 1pxsolid red; }}button {
      .my-hover-mixin(a); }/ / output
    button:hover {
      border: 1px solid red;
    }
    Copy the code
  4. Mixing with parameters

    .border-radius(@radius) {
      -webkit-border-radius: @radius;
         -moz-border-radius: @radius;
              border-radius: @radius;
    }
    #header {
      .border-radius(4px);
    }
    .button {
      .border-radius(6px);
    }
    Copy the code
  5. A mixture with parameters and default values

    .border-radius(@radius: 5px) {
      -webkit-border-radius: @radius;
         -moz-border-radius: @radius;
              border-radius: @radius;
    }
    Copy the code
  6. Mixing with multiple parameters

    .mixin(@color) {
      color-1: @color;
    }
    .mixin(@color; @padding: 2) {
      color-2: @color;
      padding-2: @padding;
    }
    .mixin(@color; @padding; @margin: 2) {
      color-3: @color;
      padding-3: @padding;
      margin: @margin @margin @margin @margin;
    }
    .some .selector div {
      .mixin(# 008000);
    }
    
    / / output
    .some .selector div {
      color-1: # 008000;
      color-2: # 008000;
      padding-2: 2;
    }
    Copy the code
  7. Named parameters

    .mixin(@color: black; @margin: 10px; @padding: 20px) {
      color: @color;
      margin: @margin;
      padding: @padding;
    }
    .class1 {
      .mixin(@margin: 20px; @color: #33acfe);
    }
    .class2 {
      .mixin(#efca44; @padding: 40px);
    }
    
    / / output
    .class1 {
      color: #33acfe;
      margin: 20px;
      padding: 20px;
    }
    .class2 {
      color: #efca44;
      margin: 10px;
      padding: 40px;
    }
    Copy the code
  8. Match the pattern

    .mixin(dark; @color) {
      color: darken(@color.10%);
    }
    .mixin(light; @color) {
      color: lighten(@color.10%);
    }
    .mixin(@ _; @color) {
      display: block;
    }
    
    / / call
    @switch: light;
    
    .class {
      .mixin(@switch; # 888);
    }
    
    /* Result: The first mixin definition does not match because it expects dark as the first argument. The second mixin defines a match because it expects light. The third mixin defines a match because it expects any value. * /
    .class {
      color: #a2a2a2;
      display: block;
    }
    
    
    // Match by parameter
    /* If we.mixin is called with a single argument, we'll get the output of the first definition, but if we call it with two arguments, we'll get the second definition, @a fades in and out @b. * /
    .mixin(@a) {
      color: @a;
    }
    .mixin(@a; @b) {
      color: fade(@a; @b);
    }
    Copy the code
  9. The arguments variable

    .box-shadow(@x: 0; @y: 0; @blur: 1px; @color: # 000) {
      -webkit-box-shadow: @arguments;
         -moz-box-shadow: @arguments;
              box-shadow: @arguments;
    }
    .big-block {
      .box-shadow(2px; 5px);
    }
    
    / / output
    .big-block {
      -webkit-box-shadow: 2px 5px 1px # 000;
         -moz-box-shadow: 2px 5px 1px # 000;
              box-shadow: 2px 5px 1px # 000;
    }
    Copy the code
  10. Advanced parameters and @REST variables

    .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

operation

The arithmetic operations +, -, *,/ can operate on any number, color, or variable. If possible, mathematical operations consider units and convert numbers before adding, subtracting, or comparing them. The result has the unit type clearly stated on the left. If the conversion is not possible or does not make sense, units are ignored. Examples of impossible conversions: px to CM or RAD to %.

// numbers are converted into the same units
@conversion-1: 5cm + 10mm; // result is 6cm
@conversion-2: 2 - 3cm - 5mm; / / result is 1.5 cm

// conversion is impossible
@incompatible-units: 2 + 5px - 3cm; // result is 4px

// example with variables
@base: 5%;
@filler: @base * 2; // result is 10%
@other: @base + @filler; // result is 15%
Copy the code

Multiplication and division do not convert numbers. In most cases it doesn’t make sense – length times length gives you a range, and CSS doesn’t support specifying a range. Less will operate on numbers as is and assign the result a clearly defined unit type.

@base: 2cm * 3mm; // result is 6cm
Copy the code

Colors are divided into red, green, blue, and alpha dimensions. This operation applies separately to each color dimension. For example, if the user adds two colors, the green dimension of the result is equal to the sum of the green dimensions of the input color. If the user multiplies a color by a number, each color dimension is multiplied.

Note: The arithmetic of alpha is not defined because the arithmetic of color does not have the meaning of the standard convention. Do not rely on the current implementation, as it may change in later releases.

Manipulations on colors always produce valid colors. If a color dimension of the result ends up being greater than FF or less than 00, the dimension is rounded to ff or 00. If the alpha ends up being greater than 1.0 or less than 0.0, the alpha is rounded to 1.0 or 0.0.

@color: # 224488 / 2; //results in #112244
background-color: # 112244 + # 111; // result is #223355
Copy the code

Succession (extension)

Extend is a Less pseudo-class that matches the selector it places with the selector it references.

Extensions to the class

// :extend selector will say "extend selector" (apply nav ul) to anywhere in the. Inline class. The declaration block will remain as is, but without any reference to the extension
nav ul {
  &:extend(.inline);
  background: blue;
}
.inline {
  color: red;
}

/ / output
nav ul {
  background: blue;
}
.inline.nav ul {
  color: red;
}

// Expand the grammar
.a:extend(.b) {}
// the above block does the same thing as the below block
.a {
  &:extend(.b);
}

// This parameter is optional
.c:extend(.d all) {
  // extends all instances of ".d" e.g. ".x.d" or ".d.x"
}
.c:extend(.d) {
  // extends only instances where the selector will be output as just ".d"
}

// Multiple extended classes separated by commas
.e:extend(.f) {}
.e:extend(.g) {}
// the above an the below do the same thing
.e:extend(.f, .g) {}
Copy the code

Extend to selectors

The extension attached to the selector looks like a normal pseudo-class, taking the selector as an argument. A selector can contain multiple extension clauses, but all extensions must be at the end of the selector.

  1. Extension after selector: pre:hover:extend(div pre).

  2. Spaces are allowed between selectors and extensions: pre:hover :extend(div pre).

  3. Allow multiple extensions: pre:hover:extend(div pre):extend(.bucket tr)- Note this with pre:hover:extend(div pre,.bucket tr)

  4. This is not allowed: pre:hover:extend(div pre).nth-child(odd). The extension must be at the end.

  5. A rule set extends multiple selectors

    .big-division..big-bag:extend(.bag),
    .big-bucket:extend(.bucket) {
      // body
    }
    Copy the code

Extend the internal rule set

You can use the &:extend(selector) syntax to put extensions into the body of a rule set. Putting an extension into the body is a shortcut to each selector that puts it into the rule set.

pre:hover..some-class {
  &:extend(div pre);
}
/ / consistent
pre:hover:extend(div pre),
.some-class:extend(div pre) {}
Copy the code

Classic cases

Add an animal subtype that covers the background color */
.animal {
  background-color: black;
  color: white;
}
.bear {
  &:extend(.animal);
  background-color: brown;
}

/* 2. Mixins copy all properties into selectors, which may cause unnecessary duplication. Therefore, you can use extends instead of mixins to move the selector up to the property you want to use, thereby reducing the CSS generated. * /
.my-inline-block {
  display: inline-block;
  font-size: 0;
}
.thing1 {
  &:extend(.my-inline-block);
}
.thing2 {
  &:extend(.my-inline-block);
}

Another use case is as an alternative to mixins - since mixins can only be used with simple selectors, if you have two different HTML blocks but need to apply the same style to both, you can use an extension to associate the two regions */
li.list > a {
  // list styles
}
button.list-style {
  &:extend(li.list > a); // use the same list styles
}
Copy the code

@import

Import styles from other style sheets; In standard CSS, @import must precede all other types of rules. But less.js doesn’t care where you put the @import statement

File extension

  1. If the file has.cssExtension, which will be treated as CSS and@importThe statement is left as is.
  2. If it hasAny other extension, it will be treated as Less and imported.
  3. If it doesn’t have an extension,.lessWill be attached and included in the Less file as an import.
@import "foo";      // foo.less is imported
@import "foo.less"; // foo.less is imported
@import "foo.php";  // foo.php imported as a less file
@import "foo.css";  // statement left in place, as-is
Copy the code

The import options

Less provides multiple extensions to CSs@ImportCSS at-rule to provide greater flexibility in what you can do to external files.

Syntax: @import (keyword) “filename”;

  1. reference: Uses the Less file but does not output it
  2. inline: Includes the source file in the output but does not process it
  3. less: Treat a file as Less regardless of its extension
  4. css: Treat the file as a CSS file, whatever the file extension is
  5. once: Include files only once (this is the default behavior)
  6. multiple: Include files multiple times
  7. optional: Continue compiling if no file is found

Each @import allows multiple keywords, you must use commas to separate keywords:

Example: @import (optional, reference) “foo.less”;

Avoid compilation

Wrap styles with ~ “” to avoid compilation

BEM naming conventions

.block_element--modifier

The name of the explain example
Block A meaningful independent entity header.container.menu.checkbox.input
Element A part of a Block that has no independent meaning and is associated with a Block above menu item .list item.checkbox caption.header tittle
Modifier Block or Element flags, using them to change the appearance or behavior disabled.highlighted.checked.fixed.size big.color yellow

Example:

<form class="form form--theme-xmas form--simple">
  <input class="form__input" type="text" />
  <input
    class="form__submit form__submit--disabled"
    type="submit" />
</form>
Copy the code
.form{}.form--theme-xmas{}.form--simple{}.form__input{}.form__submit{}.form__submit--disabled{}Copy the code