Do you know the world of [Less]?

        What is LESS? LESS is a CSS preprocessor that enables customizable, manageable and reusable style sheets for websites. LESS is a dynamic style sheet language that extends the capabilities of CSS. LESS is also cross-browser friendly. A CSS preprocessor is a scripting language that expands CSS and compiles it into regular CSS syntax so it can be read by a web browser. It provides features such as variables, functions, mixins and actions to build dynamic CSS.

1. First experience of using Less

1. Use Less to write styles

Install Less globally using Npm

$ npm install less -g

Create an empty folder, named here:learn-less

Create an index.html file in the root directory, and copy the content as follows:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>初识 Less</title>
    <link href="./main.css" rel="stylesheet">
</head>
<body>
    <div class="container">1</div>
    <div class="container2">2</div>
    <div class="container3">3</div>
</body>
</html>

Create a main.less file in the root directory, and copy the content as follows:

// main.less
@width: 100%;
@height: 100px;
@color: red;

.container{
   width: @width;
   height: @height;
   background-color: @color;
   margin-bottom: 5px;
 }

.container2{
  width: @width;
  height: @height;
  background-color: @color;
  margin-bottom: 5px;
}

.container3{
  width: @width;
  height: @height;
  background-color: @color;
  margin-bottom: 5px;
}

Now open the browser and take a look, you will find that the style is not loaded. This is because the style file introduced in index.html is main.css instead of main.less. So next, we need to convert main.less to main.css, don't worry, this step does not require you to do it manually, just run a command and the conversion will be done automatically.

$ lessc main.less

After completing the above steps, you will find that a main.css file has been generated in the root directory. At this time, open the browser to see that the style has appeared.

The escaped content of main.css is:

.container {
  width: 100%;
  height: 100px;
  background-color: red;
  margin-bottom: 5px;
}
.container2 {
  width: 100%;
  height: 100px;
  background-color: red;
  margin-bottom: 5px;
}
.container3 {
  width: 100%;
  height: 100px;
  background-color: red;
  margin-bottom: 5px;
}

If you use Webstorm as a development tool, you can skip the step of manually entering the command line, because Webstorm will automatically generate the corresponding .css file after your .less file is modified. For specific configuration jump: Webstorm configuration Less Automatically translate to css

2. Feel the convenience of Less

Now there is a new requirement, which needs to change the background color of the three divs to blue (blue). If it is the previous css writing method, you need to find container, container2, and container3 in sequence, and modify the background-color attribute in it accordingly, but use less We just modify the value of the variable defined earlier.

// main.less
@width: 100%;
@height: 100px;
@color: blue;

...

After translating using lessc main.lessto open the browser, you can see that the background colors of the three divs have been changed.

2. Variables

We often see the same value repeated many times in CSS, which makes the code difficult to maintain.
Ideally, it should look like this:

const bgColor="skyblue";
$(".post-content").css("background-color",bgColor);
$("#wrap").css("background-color",bgColor);
$(".arctive").css("background-color",bgColor);

As long as we modify  bgColorthis variable, the background color of the entire page will change accordingly.

The variables in Less are very powerful and can change everything. It is worth mentioning that the variables are constants, so they can only be defined once and cannot be reused.
value variable

      /* Less */
      @color: #999;
      @bgColor: skyblue;//Do not add quotes
      @width: 50%;
      #wrap {
        color: @color;
        width: @width;
      }
    
      /* Generated CSS */
      #wrap {
        color: #999;
        width: 50%;
      }

Variables are defined starting with  @ , and the name is typed in directly when used  @.

In normal work, we can encapsulate commonly used variables into a file, which is conducive to code organization and maintenance.

      @lightPrimaryColor: #c5cae9;
      @textPrimaryColor: #fff;
      @accentColor: rgb(99, 137, 185);
      @primaryTextColor: #646464;
      @secondaryTextColor: #000;
      @dividerColor: #b6b6b6;
      @borderColor: #dadada;

selector variable

Make the selector dynamic

      /* Less */
      @mySelector: #wrap;
      @Wrap: wrap;
      @{mySelector}{ //The variable name must be wrapped in braces
        color: #999;
        width: 50%;
      }
      .@{Wrap}{
        color:#ccc;
      }
      #@{Wrap}{
        color:#666;
      }
    
      /* Generated CSS */
      #wrap{
        color: #999;
        width: 50%;
      }
      .wrap{
        color:#ccc;
      }
      #wrap{
        color:#666;
      }

attribute variable

Can reduce the amount of code writing

      /* Less */
      @borderStyle: border-style;
      @Soild:solid;
      #wrap{
        @{borderStyle}: @Soild;//The variable name must be wrapped in braces
      }
    
      /* Generated CSS */
      #wrap{
        border-style:solid;
      }
    

url variable

When the project structure changes, just modify its variables.

      /* Less */
      @images: "../img";//Need to add quotation marks
      body {
        background: url("@{images}/dog.png");//The variable name must be wrapped in braces
      }
    
      /* Generated CSS */
      body {
        background: url("../img/dog.png");
      }
    

declare variables

Somewhat similar to the hybrid approach below

      - struct: @name: { attribute: value;};
      - Use: @name();
      /* Less */
      @background: {background:red;};
      #main{
          @background();
      }
      @Rules:{
          width: 200px;
          height: 200px;
          border: solid 1px red;
      };
      #con{
        @Rules();
      }
    
      /* Generated CSS */
      #main{
        background:red;
      }
      #con{
        width: 200px;
        height: 200px;
        border: solid 1px red;
      }

variable operation

I have to mention that the variable operation of Less has completely exceeded my expectations and is very powerful.

  - Add and subtract based on the unit of the first data
  - When multiplying and dividing, pay attention to the unit must be unified
      /* Less */
      @width:300px;
      @color:#222;
      #wrap{
        width:@width-20;
        height:@width-20*5;
        margin:(@width-20)*5;
        color:@color*2;
        background-color:@color + #111;
      }
    
      /* Generated CSS */
      #wrap{
        width:280px;
        height:200px;
        margin:1400px;
        color:#444;
        background-color:#333;
      }

variable scope

One sentence understanding is: the principle of proximity

With the help of the Demo on the official website

      /* Less */
      @var: @a;
      @a: 100%;
      #wrap {
        width: @var;
        @a: 9%;
      }
    
      /* Generated CSS */
      #wrap {
        width: 9%;
      }

use variables to define variables

      /* Less */
      @fnord:  "I am fnord.";
      @var:    "fnord";
      #wrap::after{
        content: @@var; //Replace @var with its value content:@fnord;
      }
      /* Generated CSS */
      #wrap::after{
        content: "I am fnord.";
      }

3. Nesting

The magic of &

& : The name of the upper-level selector represented, as in this example header.

      /* Less */
      #header{
        &:after{
          content:"Less is more!";
        }
        .title{
          font-weight:bold;
        }
        &_content{//Understanding method: directly replace & with #header
          margin:20px;
        }
      }
      /* Generated CSS */
      #header::after{
        content:"Less is more!";
      }
      #header .title{ //Nested
        font-weight:bold;
      }
      #header_content{//No nesting!
          margin:20px;
      }

media query

In previous work, we used media queries to write an element separately

      #wrap{
        width:500px;
      }
      @media screen and (max-width:768px){
        #wrap{
          width:100px;
        }
      }

Less provides a very convenient way

      /* Less */
      #main{
          //something...
    
          @media screen{
              @media (max-width:768px){
                width:100px;
              }
          }
          @media tv {
            width:2000px;
          }
      }
      /* Generated CSS */
      @media screen and (maxwidth:768px){
        #main{
            width:100px; 
        }
      }
      @media tv{
        #main{
          width:2000px;
        }
      }

The only downside is that each element will compile its own  @media declaration and not be merged.

Practical skills

You can use Less to define your own private styles in elements.

      /* Less */
      #main{
        // something..
        &.show{
          display:block;
        }
      }
      .show{
        display:none;
      }
      const main = document.getElementById("main");
      main.classList.add("show");

result:

      #main.show{
        display:block;
      }
      .show{
        display:none; //will be overwritten.
      }

4. Hybrid method

No parameter method

A method is like a collection of declarations, just type in the name when using it.

      /* Less */
      .card { // equivalent to .card()
          background: #f6f6f6;
          -webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
          box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
      }
      #wrap{
        .card;//equivalent to .card();
      }
      /* Generated CSS */
      #wrap{
        background: #f6f6f6;
        -webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
        box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
      }

where  .card and  .card() are equivalent.
Personal suggestion, in order to avoid code confusion, it should be written as:

      .card(){
        //something...
      }
      #wrap{
        .card();
      }
Main points:
  Both `.` and `#` can be used as method prefixes.
  Whether to write `()` after the method depends on personal habits.

default parameter method

Less can use default parameters, if no parameters are passed, then default parameters will be used.

@argumentsarguments It's like referring to all parameters  in JS  .

The passed parameter must have a unit.

      /* Less */
      .border(@a:10px,@b:50px,@c:30px,@color:#000){
          border:solid 1px @color;
          box-shadow: @arguments;//Refers to all parameters
      }
      #main{
          .border(0px,5px,30px,red);//Must have units
      }
      #wrap{
          .border(0px);
      }
      #content{
        .border;//equivalent to .border()
      }
    
      /* Generated CSS */
      #main{
          border:solid 1px red;
          box-shadow:0px,5px,30px,red;
      }
      #wrap{
          border:solid 1px #000;
          box-shadow: 0px 50px 30px #000;
      }
      #content{
          border:solid 1px #000;
          box-shadow: 10px 50px 30px #000;
      }
    

method matching pattern

Very similar to polymorphism in object-oriented

      /* Less */
      .triangle(top,@width:20px,@color:#000){
          border-color:transparent  transparent @color transparent ;
      }
      .triangle(right,@width:20px,@color:#000){
          border-color:transparent @color transparent  transparent ;
      }
    
      .triangle(bottom,@width:20px,@color:#000){
          border-color:@color transparent  transparent  transparent ;
      }
      .triangle(left,@width:20px,@color:#000){
          border-color:transparent  transparent  transparent @color;
      }
      .triangle(@_,@width:20px,@color:#000){
          border-style: solid;
          border-width: @width;
      }
      #main{
          .triangle(left, 50px, #999)
      }
      /* Generated CSS */
      #main{
        border-color:transparent  transparent  transparent #999;
        border-style: solid;
        border-width: 50px;
      }

main point

  - The first parameter `left` will find the method with the highest matching degree. If the matching degree is the same, all will be selected, and there will be a style override replacement.

  - Will match if the matched argument is a variable, such as `@_`.

method namespace

Make the method more standardized

      /* Less */
      #card(){
          background: #723232;
          .d(@w:300px){
              width: @w;
              
              #a(@h:300px){
                  height: @h;//You can use the method passed in from the previous layer
                  width: @w;
              }
          }
      }
      #wrap{
          #card > .d > #a(100px); // parent element cannot add brackets
      }
      #main{
          #card .d();
      }
      #con{
          //Must not use namespaced methods alone
          //.d() If the namespace #card is not introduced earlier, an error will be reported
          
          #card; // equivalent to #card();
          .d(20px); //Must introduce #card first
      }
      /* Generated CSS */
      #wrap{
        height:100px;
        width:300px;
      }
      #main{
        width:300px;
      }
      #con{
        width:20px;
      }
    

main point

  - In CSS, the `>` selector selects the child element, that is, the element that must have a direct blood source with the parent element.
  - When introducing a command space, such as using the `>` selector, the parent element cannot be parenthesized.
  - A method that cannot use a namespace alone must first introduce a namespace before using its methods.
  - The sub-method can use the method passed in from the previous layer

Conditional filter of the method

Less doesn't have if else, but it has when

    /* Less */
    #card{
        
        // The and operator is equivalent to the AND operation &&, and it will only be executed if all conditions are met
        .border(@width,@color,@style) when (@width>100px) and(@color=#999){
            border:@style @color @width;
        }
    
        // not operator, equivalent to not operation!, will be executed only if the condition is not met
        .background(@color) when not (@color>=#222){
            background:@color;
        }
    
        // , comma separator: equivalent to OR operation ||, as long as one of the conditions is met, it will be executed
        .font(@size:20px) when (@size>50px) , (@size<100px){
            font-size: @size;
        }
    }
    #main{
        #card>.border(200px,#999,solid);
        #card .background(#111);
        #card > .font(40px);
    }
    /* Generated CSS */
    #main{
      border:solid #999 200px;
      background:#111;
      font-size:40px;
    }

main point

  - Comparison operations are: > >= = =< <.
  - = represents equal to
  - Values ​​other than the keyword true are considered false:

variable number of parameters

If you want your method to accept a variable number of arguments, you can use ... , like the ES6 spread operator.

      /* Less */
      .boxShadow(...){
          box-shadow: @arguments;
      }
      .textShadow(@a,...){
          text-shadow: @arguments;
      }
      #main{
          .boxShadow(1px,4px,30px,red);
          .textShadow(1px,4px,30px,red);
      }
    
      /* Generated CSS */
      #main{
        box-shadow: 1px 4px 30px red;
        text-shadow: 1px 4px 30px red;
      }

The method uses the important!

The method of use is very simple, just add keywords after the method name.

      /* Less */
      .border{
          border: solid 1px red;
          margin: 50px;
      }
      #main{
          .border() !important;
      }
      /* Generated CSS */
      #main {
          border: solid 1px red !important;
          margin: 50px !important;
      }

loop method

Less does not provide a for loop function, but it is not difficult for smart programmers to use recursion to achieve it.

The following is a demo on the official website, which simulates the generated grid system.

      /* Less */
      .generate-columns(4);
    
      .generate-columns(@n, @i: 1) when (@i =< @n) {
        .column-@{i} {
          width: (@i * 100% / @n);
        }
        .generate-columns(@n, (@i + 1));
      }
      /* Generated CSS */
      .column-1 {
        width: 25%;
      }
      .column-2 {
        width: 50%;
      }
      .column-3 {
        width: 75%;
      }
      .column-4 {
        width: 100%;
      }

Five, function

Once upon a time, when writing dull css, did you think about making the class name dynamic and generating different styles according to different parameters. See the example below:

// func.less
.border-radius(@radius) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
}

#header {
  .border-radius(4px);
}
.button {
  .border-radius(6px);
}

Use $ lessc func.lessto translate the contents of the func.css file as follows:

#header {
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border-radius: 4px;
}
.button {
  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;
  border-radius: 6px;
}

It can be seen that the concept of function is used here, #headerand .buttondifferent parameters are passed in and respectively, and different codes are generated as a result.

There are several ways to write functions in less:

// 函数的参数设置默认值:
.border-radius(@radius: 5px) {
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
  border-radius: @radius;
}

// 函数有多个参数时用分号隔开
.mixin(@color; @padding:2) {
  color-2: @color;
  padding-2: @padding;
}

// 函数如果没有参数,在转译成 css 时就不会被打印出来,详见上面混合中的示例
.wrap() {
  text-wrap: wrap;
}

// 函数参数如果有默认,调用时就是通过变量名称,而不是位置
.mixin(@color: black; @margin: 10px; @padding: 20px) {
  color: @color;
  margin: @margin;
  padding: @padding;
}
.class1 {
  .mixin(@margin: 20px; @color: #33acfe);
}

// 函数参数有个内置变量 @arguments,相当于 js 中的 arguments
.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
  -webkit-box-shadow: @arguments;
     -moz-box-shadow: @arguments;
          box-shadow: @arguments;
}

// 函数名允许相同,但参数不同,类似于 java 中多态的概念
.mixin(@color: black) {      
.mixin(@color: black; @margin: 10px) { 

Of course, the above are functions customized by developers, and Less also defines many useful built-in functions for us. Regarding built-in functions, if you master them, you can save a lot of time in the development process. Since there are a lot of built-in functions, I won’t introduce them one by one here. Portal: Official documentation of Less built-in functions .

6. The writing method of parent and child elements

Parent-child elements are usually written as follows in css:

.container {
    padding: 0;
}
.container .article {
    background-color: red;
}

In Less, the writing method is as follows, and the parent-child nesting relationship is clear at a glance.

.container {
    padding: 0;
    .article {
        background-color: red;
    }
}

Of course, parent-child elements also need a pseudo-class writing method, which is written in css as follows:

#header :after {
  content: " ";
  display: block;
  font-size: 0;
  height: 0;
  clear: both;
  visibility: hidden;
}

The writing method in less is as follows, you can see that a new symbol has been introduced to& replace the main class .&#header

#header {
  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}

7. Magical @import

In traditional css files, each file is independent. In less, you can introduce another less file in a less file like a js module.

Create the one.less file:

.container {
  width: 100px;
  height: 200px;
}

Create the two.less file:

@import "one";

Use $ lessc two.lessTranslate two.cssa file, you can see the content as follows:

.container {
  width: 100px;
  height: 200px;
}

The role of @import can be seen as copying the contents of one.less to the current .less file.

8. Others

  1. note

    • /* */ CSS native comments will be compiled in the CSS file.
    • // A comment provided by Less, which will not be compiled in the CSS file.
  2. avoid compiling
      /* Less */
      #main{
        width:~'calc(300px-30px)';
      }
    
      /* Generated CSS */
      #main{
        width:calc(300px-30px);
      }
          Structure: `~'value'`

      3. Avoid compiling

        Because Less is written in JS, Less has a unique feature: Javascript is used in the code.

      /* Less */
      @content:`"aaa".toUpperCase()`;
      #randomColor{
        @randomColor: ~"rgb(`Math.round(Math.random() * 256)`,`Math.round(Math.random() * 256)`,`Math.round(Math.random() * 256)`)";
      }
      #wrap{
        width: ~"`Math.round(Math.random() * 100)`px";
        &:after{
            content:@content;
        }
        height: ~"`window.innerHeight`px";
        alert:~"`alert(1)`";
        #randomColor();
        background-color: @randomColor;
      }
      /* Generated CSS */
    
      // pop 1
      #wrap{
        width: random value (0~100)px;
        height: 743px;//Varies by computer
        background: random color;
      }
      #wrap::after{
        content:"AAA";
      }

Guess you like

Origin blog.csdn.net/qq_60633836/article/details/123785367