Less入门与提升
使用vscode插件进行操作
less 会在保存后自动转化为css文件因此编辑的html绑定好对应css代码就可以了
变量
@变量名:变量值;
选择器就使用@{变量}
作为URL:@{url}路径的时候就可以这样写
提升篇:
1.变量可以是属性名也可以是部分属性名,也可以出现嵌套变量名
2.变量名不必提前声明,也可以放后面声明,不需要那么严谨
3.如果只有多个相同声明就选最下面的为变量值
4.copy 属性 用$属性名
5.引入less
//1.变量可以是属性名也可以是部分属性名,也可以出现嵌套变量名
@primary: green;
@secondary: blue;
.section {
@color: primary;
.element {
color: @@color;
}
}
//2.变量名不必提前声明,也可以放后面声明,不需要那么严谨
.lazy-eval {
width: @var;
@a: 9%;
}
@var: @a;
@a: 100%;
//or
.lazy-eval {
width: @var;
}
@var: @a;
@a: 9%;
//编译后
.lazy-eval {
width: 9%;
}
//4.copy 属性 用$属性名,同样是出现属性最下原则
.widget {
color: #efefef;
background-color: $color;
}
//编译后
.widget {
color: #efefef;
background-color: #efefef;
}
嵌套
选择器具有父子关系可以省略相同的关系
父类包裹子类
父类与子类选择器要使用& (相当于父类的代号)
&表示所有的父类
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}
clearfix {
display: block;
zoom: 1;
&:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
}
提升篇
//&可以用于重复命名类
.button-ok {
background-image: url("ok.png");
}
.button-cancel {
background-image: url("cancel.png");
}
.button-custom {
background-image: url("custom.png");
}
//& (相当于父类的代号)
.link {
& + & {
color: red;
}
& & {
color: green;
}
&& {
color: blue;
}
&, &ish {
color: cyan;
}
}
//编译后
.link + .link {
color: red;
}
.link .link {
color: green;
}
.link.link {
color: blue;
}
.link, .linkish {
color: cyan;
}
//代表所有父类
.grand {
.parent {
& > & {
color: red;
}
& & {
color: green;
}
&& {
color: blue;
}
&, &ish {
color: cyan;
}
}
}
//编译后
.grand .parent > .grand .parent {
color: red;
}
.grand .parent .grand .parent {
color: green;
}
.grand .parent.grand .parent {
color: blue;
}
.grand .parent,
.grand .parentish {
color: cyan;
}
//可以灵活的调整顺序
.header {
.menu {
border-radius: 5px;
.no-borderradius & {
background-image: url('images/button-background.png');
}
}
}
//编译后
.header .menu {
border-radius: 5px;
}
.no-borderradius .header .menu {
background-image: url('images/button-background.png');
}
//可以对列表排列组合
p, a, ul, li {
border-top: 2px dotted #366;
& + & {
border-top: 0;
}
}
//编译后
p,
a,
ul,
li {
border-top: 2px dotted #366;
}
p + p,
p + a,
p + ul,
p + li,
a + p,
a + a,
a + ul,
a + li,
ul + p,
ul + a,
ul + ul,
ul + li,
li + p,
li + a,
li + ul,
li + li {
border-top: 0;
}
Extend伪类
Extend是一个Less伪类,它把它放在的选择器与它所引用的选择器合并,就是公用属性,公用的是括号里面规则的属性(括号里面要先好)
nav ul {
&:extend(.inline);
background: blue;
}
.inline {
color: red;
}
//编译后
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
//同样的写法
.c:extend(.d all) {
// extends all instances of ".d" e.g. ".x.d" or ".d.x"
}
//也可以合并写
.e:extend(.f) {}
.e:extend(.g) {}
// the above and the below do the same thing
.e:extend(.f, .g) {}
//可以分开写
.bucket {
tr & { // nested ruleset with target selector
color: blue;
}
}
.some-class:extend(tr .bucket) {} // nested ruleset is recognized
//编译后
tr .bucket,
.some-class {
color: blue;
}
//******不能共用属性的情况
.a.class,
.class.a,
.class > .a {
color: blue;
}
.test:extend(.class) {} // this will NOT match the any selectors above
//or
*.class {
color: blue;
}
//编译后
.noStar:extend(.class) {} // this will NOT match the *.class selector
//同时不能识别特别表达方式
link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
//********选择具体子节点也不行
:nth-child(1n+3) {
color: blue;
}
.child:extend(:nth-child(n+3)) {}
//编译后
:nth-child(1n+3) {
color: blue;
}
//属性选择器的多种表达都是可以的
[title=identifier] {
color: blue;
}
[title='identifier'] {
color: blue;
}
[title="identifier"] {
color: blue;
}
.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {}
//编译后
[title=identifier],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title="identifier"],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
//all的使用当你在extend参数中最后指定all关键字时,它告诉Less将该选择器作为另一个选择器的一部分来匹配。该选择器将被复制,然后选择器中仅有的匹配部分将被替换成extend,成为一个新的选择器
.a.b.test,
.test.c {
color: orange;
}
.test {
&:hover {
color: green;
}
}
.replacement:extend(.test all) {}
//编译后
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}
//带有变量的选择器不能匹配(不能放括号里)
@variable: .bucket;
@{variable} { // interpolated selector
color: blue;
}
.some-class:extend(.bucket) {} // does nothing, no match is found
//or
.bucket {
color: blue;
}
.some-class:extend(@{variable}) {} // interpolated selector matches nothing
@variable: .bucket
//放括号外面可以
.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
//@media 里面的只能匹配里面的,下一级@media嵌套在里面的也不行
@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;
}
}
//编译后
@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;
}
}
//重复共用不会删除
.alert-info,
.widget {
/* declarations */
}
//编辑后
.alert:extend(.alert-info, .widget) {}
.alert-info,
.widget,
.alert,
.alert {
/* declarations */
}
//extend 可以只写一个类就行了
<a class="animal bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
background-color: brown;
}
//可以写成下面的形式
<a class="bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
&:extend(.animal);
background-color: brown;
}
总之,extend可以解决许多重复代码问题
混合
一个选择器包裹另外一个选择器的属性而不是父子关系(类似与函数调用)
定义的"函数"不会出现在css
无参数类型,中间没有括号或是插入空格是无效的
#menu a {
color: #111;
.bordered();
}
.post a {
color: red;
.bordered();
}
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
//已经写好规则可以直接采用无参数形式引用
.my-mixin {
color: black;
}
.my-other-mixin() {
background: white;
}
.class {
.my-mixin();
.my-other-mixin();
}
//编译后
.my-mixin {
color: black;
}
.class {
color: black;
background: white;
}
//带有父类选择器的融合
.my-hover-mixin() {
&:hover {
border: 1px solid red;
}
}
button {
.my-hover-mixin();
}
//编辑后
button:hover {
border: 1px solid red;
}
//复杂的重叠结构可以简化
#outer() {
.inner {
color: red;
}
}
//比如
.c {
#outer.inner();
}
//在 mixin 调用后使用 !important 关键字将其继承的所有属性标记为 !important:
.foo (@bg: #f5f5f5; @color: #900) {
background: @bg;
color: @color;
}
.unimportant {
.foo();
}
.important {
.foo() !important;
}
//编辑
.unimportant {
background: #f5f5f5;
color: #900;
}
.important {
background: #f5f5f5 !important;
color: #900 !important;
}
也可以使用类似构造器的形式调用,使用有参形式
#menu a {
color: #111;
.bordered(2px);
}
.post a {
color: red;
.bordered(2px);
}
.bordered(@W) {
border-top: dotted @W black;
border-bottom: solid 2px black;
}
//如果内部已经定义好了数值就可以进行无参调用
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.border-radius();
}
//多参数传递时
//多变量用逗号隔开可以是值,变量,赋值的变量,列表.name(@param1: ~(red, blue))
// 进行重载,只要形参都有值就会调用
.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);
}
//编译后
.some .selector div {
color-1: #008000;
color-2: #008000;
padding-2: 2;
}
// 实参会顶替带值的形参
.mixin(@color: black; @margin: 10px; @padding: 20px) {
color: @color;
margin: @margin;
padding: @padding;
}
.class1 {
.mixin(@margin: 20px; @color: #33acfe);
}
.class2 {
.mixin(#efca44; @padding: 40px);
}
//编译后
.class1 {
color: #33acfe;
margin: 20px;
padding: 20px;
}
.class2 {
color: #efca44;
margin: 10px;
padding: 40px;
}
//@arguments 在 mixin 中具有特殊含义,它包含调用 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);
}
//编译后
.big-block {
-webkit-box-shadow: 2px 5px 1px #000;
-moz-box-shadow: 2px 5px 1px #000;
box-shadow: 2px 5px 1px #000;
}
//灵活的参数设置 ...
.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
}
// 开关选择规则
.mixin(dark, @color) {
color: darken(@color, 10%);
}
.mixin(light, @color) {
color: lighten(@color, 10%);
}
.mixin(@_, @color) {
display: block;
}
@switch: light;
.class {
.mixin(@switch, #888);
}
//编译后
.class {
color: #a2a2a2;
display: block;
}
//抢夺定义定义两个数就用第二个代替
.mixin(@a) {
color: @a;
}
.mixin(@a, @b) {
color: fade(@a, @b);
}
//用函数形式调用
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
// call a mixin and look up its "@result" value
padding: .average(16px, 50px)[@result];
}
//函数调用形式
#theme.dark.navbar {
.colors(light) {
primary: purple;
}
.colors(dark) {
primary: black;
secondary: grey;
}
}
.navbar {
@colors: #theme.dark.navbar.colors(dark);
background: @colors[primary];
border: 1px solid @colors[secondary];
}
//编译后
.navbar {
background: black;
border: 1px solid grey;
}
// 嵌套调用
#library() {
.colors() {
background: green;
}
}
.box {
@alias: #library.colors();
@alias();
}
//编译后
.box {
background: green;
}
//开关选择属性(用函数判断实现)
@config: {
option1: true;
option2: false;
}
.mixin() when (@config[option1] = true) {
selected: value;
}
.box {
.mixin();
}
//编译后
.box {
selected: value;
}
//多重嵌套函数使用的方法
@config: {
@dark: {
primary: darkblue;
}
@light: {
primary: lightblue;
}
}
//编译后
.box {
@lookup: dark;
color: @config[@@lookup][primary];
}
@规则嵌套和冒泡
@ 规则(例如 @media 或 @supports)可以与选择器以相同的方式进行嵌套。@ 规则会被放在前面,同一规则集中的其它元素的相对顺序保持不变。这叫做冒泡(bubbling)
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;
}
}
运算
算术运算符 +、-、*、/ 可以对任何数字、颜色或变量进行运算。如果可能的话,算术运算符在加、减或比较之前会进行单位换算。计算的结果以最左侧操作数的单位类型为准。如果单位换算无效或失去意义,则忽略单位。无效的单位换算例如:px 到 cm 或 rad 到 % 的转换。
// 所有操作数被转换成相同的单位
@conversion-1: 5cm + 10mm; // 结果是 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果是 -1.5cm
// conversion is impossible
@incompatible-units: 2 + 5px - 3cm; // 结果是 4px
// example with variables
@base: 5%;
@filler: @base * 2; // 结果是 10%
@other: @base + @filler; // 结果是 15%
乘法和除法不作转换。因为这两种运算在大多数情况下都没有意义,一个长度乘以一个长度就得到一个区域,而 CSS 是不支持指定区域的。Less 将按数字的原样进行操作,并将为计算结果指定明确的单位类型你还可以对颜色进行算术运算:。
可以使用特殊的函数进行计算
@var: 50vh/2;
width: calc(50% + (@var - 20px)); // 结果是 calc(50% + (25vh - 20px))
转义
转义(Escaping)允许你使用任意字符串作为属性或变量值。任何 ~"anything" 或 ~'anything' 形式的内容都将按原样输出,除非 interpolation。使用字符表示值不可以不用转义
@min768: (min-width: 768px);
.element {
@media @min768 {
font-size: 1.2rem;
}
}
函数
用于快速实现某些功能具体操作
@base: #f04615;
@width: 0.5;
.class {
width: percentage(@width); // returns `50%`
color: saturate(@base, 5%);
background-color: spin(lighten(@base, 25%), 8);
}
命名空间与访问符
对内部的部分属性进行分组,并且可以用于外部混合
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white;
}
}
.tab { ... }
.citation { ... }
}
#header a {
color: orange;
#bundle.button(); // 还可以书写为 #bundle > .button 形式
}
映射
直接从一个混合集里获取元素
#colors() {
primary: blue;
secondary: green;
}
.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}
//编译结果
.button {
color: blue;
border: 1px solid green;
}
作用域
变量的主要范围就近原则由内到外
注释
/ *
多行注释 */
//单行注释
导入
“导入”的工作方式和你预期的一样。你可以导入一个 .less 文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less 扩展名,则可以将扩展名省略掉如果该文件的扩展名是.css,它将被视为CSS,并且@import语句保持原样(见下面的内联选项)。如果它有任何其他扩展名,它将被视为Less并被导入如果它没有扩展名,.less将被附加,它将被作为一个导入的Less文件。导入可以设置选项
@import "library"; // library.less
@import "typo.css";
Less提供了对CSS @import at-rule的一些扩展,为你对外部文件的处理提供了更多的灵活性。
语法。@import (keyword) "filename";
以下的导入选项已经实现。
reference:使用一个Less文件,但不输出它 在混合与拓展的时候调用就会使用不会显示原来的属性 inline:在输出中包括源文件,但不处理它 less:将文件视为Less文件,不管文件的扩展名是什么 css:将该文件视为CSS文件,不管其扩展名是什么 once: 只包含一次文件(这是默认行为)。 multiople:多次包含同样文件 可选的:在没有找到文件时继续编译 每个@import允许有一个以上的关键词,你必须用逗号来分隔这些关键词。
例子。@import(可选,参考)"foo.less"。
插入插件
Using a @plugin at-rule is similar to using an @import for your .less files. 用于插入js文件
@plugin "my-plugin"; // automatically appends .js if no extension
@plugin "my-plugin";
.show-me-pi {
value: pi();
}
//编译结果
.show-me-pi {
value: 3.141592653589793;
}
//插件符合作用域规则
.el-1 {
@plugin "lib1";
value: foo();
}
.el-2 {
@plugin "lib2";
value: foo();
}
//
.el-1 {
value: foo;
}
.el-2 {
value: bar;
}
maps
@sizes: {
mobile: 320px;
tablet: 768px;
desktop: 1024px;
}
.navbar {
display: block;
@media (min-width: @sizes[tablet]) {
display: inline-block;
}
}
//编译后
.navbar {
display: block;
}
@media (min-width: 768px) {
.navbar {
display: inline-block;
}
}