Skip to content

Less - 父选择器

父选择器由符号(&)表示,是 LESS 中一个强大的特性,它引用嵌套规则的完整父选择器链。它主要用于修改当前选择器、应用伪类或伪元素,或改变嵌套规则与其父规则之间的关系。

使用 & 可以使样式表更简洁易读,特别是在遵循 BEM (Block, Element, Modifier) 等命名约定或为 :hover 或 :focus 等状态添加样式时。

下表列出了父选择器的常见用例和行为:

ID用例与描述示例代码片段与编译后的 CSS
1应用伪类/伪元素
最常见的用法:&:hover, &:focus, &::before, &::after。
a { color: blue; &:hover { color: red; } }
编译为:a { color: blue; } a:hover { color: red; }
2附加类(修饰符或状态类)
用于 BEM 风格的修饰符或状态类:&.active, &—modifier。
.button { background: grey; &.primary { background: blue; } }
编译为:.button { background: grey; } .button.primary { background: blue; }
3前置选择器(上下文样式)
当 & 在嵌套规则的选择器中不是第一部分时,可用于将父选择器前置到另一个选择器。对上下文样式有用。
.element { .ancestor & { color: green; } }
编译为:.ancestor .element { color: green; }
4多个 &(引用更外层父级)
可以使用多个 & 来引用父级链中更靠外的部分,尽管这不太常见,且可能使选择器复杂。每个 & 通常指完整的当前父选择器字符串。
.grandparent { .parent { .child { && { color: red; } } } }
编译为:.grandparent .parent .child.grandparent .parent .child { color: red; }(通常不是想要的结果;通常一个 & 就足以表示当前父上下文)。多个 & 更实际的用法是在组合场景中。
5改变选择器顺序 / 兄弟组合器
在嵌套规则中将 & 放在另一个选择器之后,或与兄弟组合器(+, ~)一起使用。
li { &:hover + li { background: lightgray; } &:last-child { margin-right: 0; } }
编译为:li:hover + li { background: lightgray; } li:last-child { margin-right: 0; }
6组合爆炸(& 与逗号分隔列表)
当 & 与逗号分隔的选择器列表一起使用时,它会生成所有可能的排列组合。这功能强大,但也可能导致生成许多选择器,需谨慎使用。
.alert, .message { strong& { font-weight:bold; } }
编译为:strong.alert, strong.message { font-weight:bold; }(这里的 & 指父列表中的每个选择器)。
另一个示例:p, div { &:hover, &:focus { color: red; } } 将生成 p:hover, p:focus, div:hover, div:focus { … }

示例:使用父选择器处理状态和修饰符

Section titled “示例:使用父选择器处理状态和修饰符”

HTML (parent_selector_example.html):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Parent Selector Example</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<a href="#" class="button">Default Button</a>
<a href="#" class="button button--primary">Primary Button</a>
<a href="#" class="button button--large is-active">Large Active Button</a>
<ul class="menu">
<li>Item 1</li>
<li>Item 2</li>
</ul>
</body>
</html>

LESS (style.less):

@primary-color: #007bff;
@default-bg: #f0f0f0;
.button {
display: inline-block;
padding: 10px 15px;
background-color: @default-bg;
color: #333;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s ease;
&:hover {
background-color: darken(@default-bg, 10%);
}
&--primary { // BEM 风格修饰符
background-color: @primary-color;
color: white;
&:hover {
background-color: darken(@primary-color, 10%);
}
}
&--large {
padding: 15px 25px;
font-size: 1.2em;
}
// 状态类与父选择器结合使用
&.is-active {
box-shadow: 0 0 5px rgba(0,0,0,0.5) inset;
}
}
.menu {
list-style: none;
padding-left: 0;
li {
padding: 5px;
// 当 .menu 带有 .dark 类时,li 改变颜色
.dark& {
color: white;
background-color: #333;
}
}
}

将 style.less 编译为 style.css:

lessc style.less style.css

编译后的 style.css 如下:

.button {
display: inline-block;
padding: 10px 15px;
background-color: #f0f0f0;
color: #333;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: #d6d6d6; /* darken(#f0f0f0, 10%) */
}
.button--primary {
background-color: #007bff;
color: white;
}
.button--primary:hover {
background-color: #0056b3; /* darken(#007bff, 10%) */
}
.button--large {
padding: 15px 25px;
font-size: 1.2em;
}
.button.is-active {
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5) inset;
}
.menu {
list-style: none;
padding-left: 0;
}
.menu li {
padding: 5px;
}
.dark.menu li {
color: white;
background-color: #333;
}

父选择器 & 对于编写清晰、结构化和可维护的 LESS 至关重要,尤其是在处理组件状态、修饰符和伪类时。

打开 parent_selector_example.html 将显示应用了各种样式的按钮,这些样式通过使用父选择器处理悬停状态、修饰符类(—primary, —large)和状态类(is-active)。.dark.menu li 示例展示了如何使用 & 来改变上下文。

有关 & 与复杂选择器交互的更高级用法和理解,LESS 官方文档是宝贵的资源。

LESS 包含几个杂项(misc)函数,它们提供各种任务的实用工具,例如类型转换、数据 URI 嵌入、单位操作和获取图像尺寸。这些函数不完全属于数学或颜色等类别,但提供了有价值的功能。

下表列出了一些重要的 LESS 杂项函数:

ID函数、语法与描述示例与概念性输出
1color(string)
解析颜色字符串表示(例如,“#FF0000” 或 “blue”)并返回 LESS 颜色对象。当颜色值以字符串形式存储时非常有用。
@my-color-string: “#3498db”; .element { background-color: color(@my-color-string); }
输出:.element { background-color: #3498db; }
2image-size(filePath)
返回图像文件的尺寸(宽度和高度)。要求 LESS 编译器能够访问文件系统。返回一个类似 100px 50px 的列表。
@path: “images/logo.png”; .logo { width: extract(image-size(@path), 1); height: extract(image-size(@path), 2); }
如果 logo.png 是 120x60px:.logo { width: 120px; height: 60px; }(在现代工作流程中,随着响应式图像和 CSS 尺寸调整的应用,这个函数不太常用)。
3image-width(filePath)
返回图像文件的宽度。类似于 image-size 但只针对宽度。
@path: “images/icon.svg”; .icon { width: image-width(@path); }
4image-height(filePath)
返回图像文件的高度。类似于 image-size 但只针对高度。
@path: “images/banner.jpg”; .banner { height: image-height(@path); }
5convert(numberWithUnit, targetUnit)
将带单位的数字从一个兼容单位转换为另一个兼容单位(例如,像素到 em,英寸到厘米)。
@length-in-px: 16px; .text { font-size: convert(@length-in-px, em); }
输出取决于基础字体大小上下文,但会将 16px 转换为例如 1em(如果基础字体大小是 16px)。
6data-uri(filePath, mimeType?)
将文件直接嵌入样式表作为 Base64 编码的数据 URI。可选地,可以指定 MIME 类型。这可以减少 HTTP 请求,但会增加 CSS 文件大小。适用于小型图标或字体。
.icon-disk { background-image: data-uri(‘images/disk-icon.png’); }
输出:.icon-disk { background-image: url(‘data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFerKKAUZAAAAAElFTkSuQmCC’); }(实际 Base64 字符串会有所不同)。
7default()
一个特殊函数,仅在混合宏守卫(mixin guards)中使用。如果没有其他(同名)且条件为真的守卫混合宏被匹配到,则此函数评估为 true。起到 ‘else’ 或备用条件的作用。
.mixin(@a) when (@a > 10) { /* styles for >10 / } .mixin(@a) when (default()) { / styles for <=10 */ }
8unit(dimension, newUnit?)
改变或移除尺寸的单位。如果提供了 newUnit,它会将尺寸转换为该单位(如果兼容,类似于 convert,但也可用于移除单位)。如果省略了 newUnit,它会移除单位,返回一个无单位的数字。
@value: 20px; .element { line-height: unit(@value); /* 20 / padding: unit(@value, em); / 例如,1.25em */ }
9get-unit(dimension)
将尺寸的单位作为关键字或关键字列表返回(对于像 px/s 这样的复杂单位)。
@length: 100px; @duration: 5s; ispixel(get-unit(@length)) // true (px)
这通常在守卫条件或其他函数中使用。
10svg-gradient(direction, colorStop1, colorStop2, …)
生成一个 SVG 渐变字符串,通常用作背景图像。这是一个更专业化的函数。
.gradient-bg { background-image: svg-gradient(to right, #FF0000 0%, #0000FF 100%); }
输出:.gradient-bg { background-image: url(‘data:image/svg+xml,…’); } (SVG 数据 URI)

这些杂项函数为在 LESS 样式表中处理各种数据类型和外部资源提供了额外的灵活性。