less学习心得

本文分享了作者在学习Less预处理器过程中的个人心得,包括官网资料的学习与个人理解,并计划通过实践Demo进一步巩固知识。内容包含作者的总结和实例,建议结合Less官网的详细例子进行深入学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面是我学习less的一些心得

大多数都是直接粘贴官网的,不过也加上了自己的一些理解,晚些时候再一个个做demo出来。

// 一、变量的使用

// 1-1.可以进行变量与定义和加减乘除运算,同时可以在定义的时候根据前面的变量进行运算
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
@background: #333;
@font50: 50px;

// 1-2.变量可以在定义时进行运算
// Variables
@link-color:        #428bca; // sea blue
@link-color-hover:  darken(@link-color, 10%);

// Usage
a,
.link {
  color: @link-color;
}
a:hover {
  color: @link-color-hover;
}
.widget {
  color: #fff;
  background: @link-color;
}


// 1-3.同时,变量还可以作为选择器的名字
// Variables
@my-selector: banner;

// Usage
.@{my-selector} {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
}


// 1.4 同时,路径也是可以作为一个变量使用的
// Variables
@images: "../img";

// Usage
body {
  color: #444;
  background: url("@{images}/white-sand.png");
}


// 1.5 同时,引入文件的时候,也可以使用变量拼接路径
// Variables
@themes: "../../src/themes";

// Usage
// @import "@{themes}/tidal-wave.less";


// 1.6 作为属性的一部分进行拼接
@property: color;

.widget {
  @{property}: #0ee;
  background-@{property}: #999;
}

// 1.7 可以像php那样进行变量名拼接
@fnord:  "I am fnord.";
@vars:    "fnord";

.contentCon{
    content: @@vars;
}

// 1.7 变量名后声明懒提升
.lazy-eval {
  width: @varwidth;
}

@varwidth: @awidth;
@awidth: 9%;


// 二、样式的使用

// 2-1.可以将定好的样式作为一个变量放到另外一个样式里面,使用分号结尾。
.header {
  color: @light-blue;
  font-size: @font50;
}

.fr {
  float: right;
}

.fl {
  float: left;
}
.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

#menu a {
  color: #111;
  .bordered;
}

.post a {
  color: red;
  .bordered;
}


// 2-2.使用extend直接应用其他样式中的属性,会跟其他选择器生成一个组合选择器
// nav ul {
//   &:extend(.inline);
//   background: blue;
// }
// .inline {
//   color: red;
// }
//output:
//nav ul,.inline {
//  color: red;
//}


// 2-3.直接使用extend继承其他属性,其实跟上面的用法一样的
nav ul:extend(.inline){
    background-color: #f00;
}
.inline {
  color: red;
}


// 2-4. 多个元素可以直接继承一个元素
div .pre {
    background-color: #f00;
}
pre:hover,
.some-class {
  &:extend(div .pre);
}
// output:
//.some-class,div .pre,pre:hover{background-color:red}



// 2.5 也可以使用嵌套元素进行继承
.bucket {
  tr { // nested ruleset with target selector
    color: blue;
  }
}
.some-class:extend(.bucket tr) {} // nested ruleset is recognized
// output:
.bucket tr,
.some-class {
  color: blue;
}


// 2.6 less中是精确匹配元素的,所以使用*通配符是无效的
.a.class,
.class.a,
.class > .a {
  color: blue;
}
.test:extend(.class) {} // 第一种情况,this will NOT match the any selectors above

*.class {
  color: blue;
}
.noStar:extend(.class) {} // 第二种情况,尽管在*.class和.class 等价,但是无法继承。this will NOT match the *.class selector


// 2.7 nth选择器如果数字不一样也不能继承,属性选择器只要属性相等就可以匹配
:nth-child(1n+3) {
  color: blue;
}
//.child:extend(:nth-child(n+3)) {} //这是无法继承的

[title=identifier] {
  color: blue;
}
[title='identifier'] {
  color: blue;
}
[title="identifier"] {
  color: blue;
}

.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {} //这个是完全可以继承的


// 2.8 完全继承一个选择器所有同名的选择器
.a.b.test,
.test.c {
  color: orange;
}
.test {
  &:hover {
    color: green;
  }
}

.replacement:extend(.test all) {}  //这样的话.replacement会成为跟test一样的选择器,连父类也是一样的

// 2.9 范围继承的属性
@media print {
  .screenClass:extend(.selector) {} // extend inside media
  .selector { // this will be matched - it is in the same media
    color: black;
  }
}
.selector { // ruleset on top of style sheet - extend ignores it
  color: red;
}
@media screen {
  .selector {  // ruleset inside another media - extend ignores it
    color: blue;
  }
}
// output:
// @media print {
//   .selector,
//   .screenClass { /*  ruleset inside the same media was extended */
//     color: black;
//   }
// }
// .selector {  ruleset on top of style sheet was ignored 
//   color: red;
// }
// @media screen {
//   .selector { /* ruleset inside another media was ignored */
//     color: blue;
//   }
// }


// 2.10 使用情况继承,也就是一个父元素定义初始样式,子类再修改就好
.animal {
  background-color: black;
  color: white;
}
.bear {
  &:extend(.animal);
  background-color: brown;
}


// 2.11 mixin和extend的区别
.my-inline-block() {
  display: inline-block;
  font-size: 0;
}
.thing1 {
  .my-inline-block;
}
.thing2 {
  .my-inline-block; //这个是利用mixin直接复制属性
}
// output
// .thing1 {
//   display: inline-block;
//   font-size: 0;
// }
// .thing2 {
//   display: inline-block;
//   font-size: 0;
// }

.my-inline-block {
  display: inline-block;
  font-size: 0;
}
.thing1 {
  &:extend(.my-inline-block);
}
.thing2 {
  &:extend(.my-inline-block); //这个是继承属性,继承的样式会和原来的样式组成组合选择器
}
// output:
// .my-inline-block,
// .thing1,
// .thing2 {
//   display: inline-block;
//   font-size: 0;
// }



// 三、mixin的使用

// 3.1 mixin加了()以后是不进行样式输出的
.my-mixin {
  color: black;
}
.my-other-mixin() {
  background: white;
}
.classx {
  .my-mixin;
  .my-other-mixin;
}
// output:
// .my-mixin {
//   color: black;
// }
// .class {
//   color: black;
//   background: white;
// }


// 3.2 mixin使用的时候会连父元素也一起继承了
.my-hover-mixin() {
  &:hover {
    border: 1px solid red;
  }
}
button {
  .my-hover-mixin();
}

// output
// button:hover {
//   border: 1px solid red;
// }


// 3.3获取mixin中的子元素的样式
#outer {
  .inner {
    color: red;
  }
}

.coutput {
  #outer > .inner;
}


// 3.4 严格的mixin命名空间
@mode: huge;
#namespace when (@mode=huge) {
  .mixin() { /* */ }
}

// #namespace {
//   .mixin() when (@mode=huge) { /* */ }
// }


// 3.5 可以让mixin自动添加important的important
.foo (@bg: #f5f5f5, @color: #900) {
  background: @bg;
  color: @color;
}
.unimportant {
  .foo();
}
.important {
  .foo() !important;
}
// output
// .unimportant {
//   background: #f5f5f5;
//   color: #900;
// }
// .important {
//   background: #f5f5f5 !important;
//   color: #900 !important;
// }


// 3.6 带参数的mixin
// 可以在使用的时候传参数
.border-radius(@radius) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
}
#header {
  .border-radius(4px); //直接输入参数
}
.button {
  .border-radius(6px);
}
// 也可以指定一个默认参数
// .border-radius(@radius: 5px) {
//   -webkit-border-radius: @radius;
//      -moz-border-radius: @radius;
//           border-radius: @radius;
// }
// #header {
//   .border-radius;  //如果有默认参数,也可以直接调用
// }


// 3.7 多种参数的mixin
.mixin2(@color) {
  color-1: @color;
}
.mixin2(@color; @padding: 2) {
  color-2: @color;
  padding-2: @padding;
}
.mixin2(@color; @padding; @margin: 2) {
  color-3: @color;
  padding-3: @padding;
  margin: @margin @margin @margin @margin;
}
.some .selector div {
  .mixin2(#008000);  //只会调用最满足的mixin进行计算,因为第三个mixin2没有带参数无法计算,所以无法形成参数
}


// 3.8带命名和默认值的参数
.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;
// }


// 3.9 一个带arguments的mixin
.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;
// }

.mixin3(@a; @rest...){
    font-size: @a;
    border:@rest;
}
.small-block {
    .mixin3(12px;1px;1px;solid;#f00); //@rest的意思就是出了@a以外的所有输入的参数值都会放到@rest这个变量中,@rest是less中的变量,不能覆盖的。
}
// output
// .small-block {
//  font-size: 12px;
//  border: 1px 1px solid #f00;
// }


//3.10 带正则表达式的mixin
.mixin4(dark; @color) {
  color: darken(@color, 10%);
}
.mixin4(light; @color) {
  color: lighten(@color, 10%);
}
.mixin4(@_; @color) {
  display: block;
}
@switch: light;
.class2 {
  .mixin4(@switch; #888);
}
// output
// .class {
//   color: #a2a2a2;
//   display: block;
// }


// 3.11 将mixin当成带返回值的函数使用
.mixin5() {
  @width:  100%;
  @height: 200px;
}

.caller {
  .mixin5();
  width:  @width;
  height: @height; //例子1
}
// output
// .caller {
//   width:  100%;
//   height: 200px;   
// }

.average(@x, @y) {
  @average: ((@x + @y) / 2);
}

div {
  .average(16px, 50px); // "call" the mixin
  padding: @average;    // use its "return" value。 //例子2,可以用来计算屏幕大小变更的时候元素的宽高
}
// output
// div {
//   padding: 33px;
// }


// 3.12 mixin的作用返回会覆盖掉原来调用父级的作用范围
.mixin6() {
  @size: in-mixin;
  @definedOnlyInMixin: in-mixin;
}

.class6 {
  margin: @size @definedOnlyInMixin;
  .mixin6();
}

@size: globaly-defined-value; // callers parent scope - no protection

// output
// .class {
//   margin: in-mixin in-mixin;
// }


// 3.13 变量在定义的时候就可以当作mixin使用
// declare detached ruleset
@detached-ruleset1: { background: red; };

// use detached ruleset
.top {
    @detached-ruleset1(); 
}

// output
// .top {
//   background: red;
// }


// 3.14父级调用mixin的时候可以完成传递参数,同时,可以在父级内部定义mixin返回值
@detached-ruleset: {
  caller-variable: @caller-variable; // variable is undefined here
  .caller-mixin(); // mixin is undefined here
};

selector {
  // use detached ruleset
  @detached-ruleset(); 

  // define variable and mixin needed inside the detached ruleset
  @caller-variable: value;
  .caller-mixin() {
    variable: declaration;
  }
}
// output
// selector {
//   caller-variable: value;
//   variable: declaration;
// }


// 3.15 不能直接获取其中的具体属性的mixin,意思就是虽然访问到了子集,但是并不能获取其中的元素
@detached-1: { scope-detached: @one @two; };
.one {
  @one: visible;
  .two {
    @detached-2: @detached-1; // copying/renaming ruleset 
    @two: visible; // ruleset can not see this variable
  }
}

.use-place {
  .one > .two(); 
  @detached-2();
}

// output
// ERROR 1:32 The variable "@one" was not declared.

// 正确的修改方式:
// .one {
//   @one: visible;
//   @detached-1: { scope-detached: @one @two; };
//   .two {
//     @detached-2: @detached-1; // copying/renaming ruleset 
//     @two: visible; // ruleset can not see this variable
//   }
// }

// .use-place {
//   .one > .two(); 
//   @detached-2();
// }

// output
// .use-place{scope-detached:visible visible}



// 四、一些其他原则

// 4.1 使用import引入的原则
//@import "foo";      // foo.less is imported
//@import "foo.less"; // foo.less is imported
//@import "foo.php";  // foo.php imported as a Less file 作为less文件引入
//@import "foo.css";  // statement left in place, as-is,是css文件就按css引入

// 4.1 import的一些属性
// Syntax: @import (keyword) "filename";

// The following import directives have been implemented:

// reference: use a Less file but do not output it
// inline: include the source file in the output but do not process it
// less: treat the file as a Less file, no matter what the file extension
// css: treat the file as a CSS file, no matter what the file extension
// once: only include the file once (this is default behavior)
// multiple: include the file multiple times
// optional: continue compiling when file is not found
// More than one keyword per @import is allowed, you will have to use commas to separate the keywords:
// Example: @import (optional, reference) "foo.less";


// 五、条件判断语句

// 为了尽可能的接近@media的使用,使用mixin guard来进行判断
// 5.1 多参数进行判断的mixin guard
@a: #f00;
.mixin (@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin (@a) {
  color: @a;
}
// output
// .class1 { .mixin(#ddd) }
// .class2 { .mixin(#555) }



// 5.2 可以进行比较的minxin guard
@media: mobile;

.mixin (@a) when (@media = mobile) { }
.mixin (@a) when (@media = desktop) {  }

.max (@a; @b) when (@a > @b) { width: @a }
.max (@a; @b) when (@a < @b) { width: @b }

// 可以进行逻辑运算的mixin guard
.mixin (@a) when (isnumber(@a)) and (@a > 0) {  }  //逻辑与
.mixin (@a) when (@a > 10), (@a < -10) {  }//逻辑或
.mixin (@b) when not (@b > 0) {  }// 逻辑非


// 5.3 使用less自带的检测函数进行函数数值判断
// @b:0;
// .mixin (@a; @b: 0) when (isnumber(@b)) { }
// .mixin (@a; @b: black) when (iscolor(@b)) {}
// 下面是一些常用的检测函数
// Here are the basic type checking functions:

// iscolor
// isnumber
// isstring
// iskeyword
// isurl
// If you want to check if a value is in a specific unit in addition to being a number, you may use one of:

// ispixel
// ispercentage
// isem
// isunit


// 5.4 使用default()的mixin guard
.mixin (@a) when (@a > 0) {   }
.mixin (@a) when (default()) {  } // matches only if first mixin does not, i.e. when @a <= 0



// 六、CSS Guard的使用(less1.5以后带的特性)

// 说白了就是定义一个参数,当满足这个参数的时候css样式就生效
@my-option: true;
.button1 when (@my-option = true) {
  color: white;
}


// 七、循环

// 例子1
.loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // next iteration
  width: (10px * @counter); // code for each iteration
}

div {
  .loop(5); // launch the loop
}
// output:
// div {
//   width: 10px;
//   width: 20px;
//   width: 30px;
//   width: 40px;
//   width: 50px;
// }

// 例子2
.generate-columns(4);

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


// 八、属性融合

// 1.使用逗号组合
.mixin() {
  box-shadow+: inset 0 0 10px #555;
}
.myclass {
  .mixin();
  box-shadow+: 0 0 20px black;
}
// output
// .myclass {
//   box-shadow: inset 0 0 10px #555, 0 0 20px black;
// }

// 2.使用空格组合
.mixin() {
  transform+_: scale(2);
}
.myclass {
  .mixin();
  transform+_: rotate(15deg);
}
// output
// .myclass {
//   transform: scale(2) rotate(15deg);
// }



// 九、能够充分代表自己的“&”操作符

//  例子一、&在自身作用范围可以作为代表自己的可以很多字母
.button {
  &-ok {
    background-image: url("ok.png");
  }
  &-cancel {
    background-image: url("cancel.png");
  }

  &-custom {
    background-image: url("custom.png");
  }
}
// output
// .button-ok {
//   background-image: url("ok.png");
// }
// .button-cancel {
//   background-image: url("cancel.png");
// }
// .button-custom {
//   background-image: url("custom.png");
// }

// 例子二,可以看出实际上&这个是代表了.link这个选择器
.link {
  & + & {
    color: red;
  }

  & & {
    color: green;
  }

  && {
    color: blue;
  }

  &, &ish {
    color: cyan;
  }
}

// output
// .link + .link {
//   color: red;
// }
// .link .link {
//   color: green;
// }
// .link.link {
//   color: blue;
// }
// .link, .linkish {
//   color: cyan;
// }

//例子三,可以在子元素中调用父类选择器,这样的话可以方便很多操作,例如提高选择器渲染优先权重
.header {
  .menu {
    border-radius: 5px;
    .no-borderradius & {
      background-image: url('images/button-background.png');
    }
  }
}
// output
// .header .menu {
//   border-radius: 5px;
// }
// .no-borderradius .header .menu {
//   background-image: url('images/button-background.png');
// } 


// 十、其他的一些规则


//10.1 嵌套规则,可以在父元素中嵌套使用自元素
.header {
  width: 1000px;
  height: 500px;
  backgournd-color: @background;
  .navigation {
    font-size: @font50;
    .fl;
  }
  .logo {
    width: 300px;
    height: 400px;
    background: @nice-blue;
    .fl;
  }
}



//10.2 对于伪类元素可以使用&代替
.clearfix {
  dispaly: block;
  zoom: 1;
  &:after {
    content: '';
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}


// 10.3 对于规则性的属性可以进行嵌套,自身会进行元素关联和冒泡顶层,例如@media
// .screen-color {
//  @media screen{
//      color: green;
//  }
//  @media (min-width: 768px) {
//      color: red;
//  }
//  @media tv {
//      color: black; //tv值已经废弃
//  }
// }



// 10.4没有条件的规则例如巷font-face或者keyframes也会自动冒泡
#a {
  color: blue;
  @font-face {
    src: made-up-url;
  }
    padding: 2;
}

@screenparams: 320 360 375 400 414 480 540 600 640 641 !default;
@length: 10;



// 10.5 使用函数进行屏幕适应
//.screenAdapter(resolution ratio:屏幕分辨率)
// 计算屏幕响应
.screenAdapterFn(@counter) when(@counter <= 640) {
  html, body{
    @media screen width (max-width: @counter) {
      font-size: (@counter/10px);
    }
  }
}
//特定屏幕需要特定参数响应
.screenAdapterFn(@counter) when(@counter = 641) {
  html, body {
    @media screen width (max-width: @counter) {
      font-size: 72px;
    }
  }
}
.screenAdapterFn(320);
.screenAdapterFn(360);
.screenAdapterFn(375);
.screenAdapterFn(400);
.screenAdapterFn(414);
.screenAdapterFn(480);
.screenAdapterFn(540);
.screenAdapterFn(600);
.screenAdapterFn(640);
.screenAdapterFn(641);


//10.6 可以进行加减乘除运算,但是最后的话只会按照第二个单位输出
// numbers are converted into the same units
@conversion-1: 5cm + 10mm; // result is 6cm
@conversion-2: 2 - 3cm - 5mm; // result is -1.5cm

// 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%
@base: 2cm * 3mm; // result is 6cm
@color: #224488 / 2; //results in #112244
.bg{
    background-color: #112244 + #111; // result is #223355
}


//10.7 异常字符串的处理
.weird-element {
  // content: ~"^//* some horrible but needed css hack";
}


//10.8 使用less自带函数
@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); // returns `50%`
  color: saturate(@base, 5%);
  background-color: spin(lighten(@base, 25%), 8);
}


// 10.9 使用定义好的样式直接可以获取其其中的样式
#bundle {
  .button {
    display: block;
    border: 1px solid black;
    background-color: grey;
    &:hover {
      background-color: white
    }
  }
  .tab { 
    font-size: 15px;
   }
  .citation { 
    font-size: 16px;
   }
}

.header a {
  color: orange;
  #bundle > .button;
}


//10.10 变量作用域的使用
@var: red;

#page {
  @var: white;
  #header {
    color: @var; // white
  }
}
@var: red;

// #page {
//   #header {
//     color: @var; // white
//   }
//   @var: white;
// }


// 10.11 注释
/* One hell of a block
style comment! */
@var: red;

// Get in line!
@var: white;


// 10.12引入其他定义好的样式
// @import "library"; // library.less
// @import "typo.css";

上面都是我的一些总结和例子,可能说明不够详细,可以去官网查具体的例子和说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值