/* 传统写法 */
.parent {
color: red;
}
.parent .child {
color: blue;
}
.parent:hover {
color: green;
}
/* 使用嵌套写法 */
.parent {
color: red;
.child {
color: blue;
}
&:hover {
color: green;
}
}
当前支持状态(2024)
/* 元素嵌套 */
.card {
padding: 20px;
.header {
font-size: 24px;
.title {
color: #333;
span {
font-weight: bold;
}
}
}
.content {
margin-top: 10px;
p {
line-height: 1.6;
}
}
}
& 符号(父选择器引用)/* 伪类和伪元素 */
.button {
background: blue;
color: white;
&:hover {
background: darkblue;
}
&:active {
transform: scale(0.98);
}
&:focus {
outline: 2px solid orange;
}
&::before {
content: "→ ";
}
}
/* 连接类名 */
.btn {
&-primary {
background: blue;
}
&-secondary {
background: gray;
}
&-large {
padding: 15px 30px;
font-size: 18px;
}
}
.container {
width: 100%;
padding: 20px;
@media (min-width: 768px) {
max-width: 750px;
margin: 0 auto;
.sidebar {
width: 250px;
float: left;
}
.content {
margin-left: 270px;
}
}
@media (min-width: 1200px) {
max-width: 1140px;
}
}
/* 检查 Grid 支持 */
.grid {
display: flex;
flex-wrap: wrap;
@supports (display: grid) {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
& > .item {
margin: 0;
}
}
}
/* 相邻兄弟选择器 */
h1 {
color: #333;
+ p {
margin-top: 10px;
color: #666;
}
}
/* 通用兄弟选择器 */
h2 {
color: #222;
~ p {
font-style: italic;
}
}
/* 属性选择器嵌套 */
input {
border: 1px solid #ccc;
&[type="text"] {
width: 200px;
}
&[type="checkbox"] {
width: 20px;
height: 20px;
}
}
Sass/Less 嵌套的区别/* Sass 和 CSS 原生嵌套看起来相似 */
.card {
.title {
color: red;
}
}
& 符号的必须性(重要区别!)/* ✅ CSS 原生嵌套:必须使用 & 来连接选择器 */
.component {
&__part {
color: red;
}
}
/* ❌ 这会出错(在 CSS 中) */
.component {
__part { /* 无效!需要 & */
color: red;
}
}
/* ✅ 这样可以 */
.component {
.part { /* 有效:空格表示后代 */
color: red;
}
}
/* CSS 原生嵌套:嵌套必须放在前面 */
.card {
color: black; /* 属性 */
.title { /* 嵌套规则必须放在所有属性之后 */
color: red;
}
}
.card1 {
/* ❌ 这样会无效 */
.title {
color: red;
}
color: black; /* 错误:属性不能在嵌套规则之后 */
}
/* Sass 允许更灵活的顺序 */
@规则嵌套/* CSS 原生支持嵌套的 @规则 */
.container {
@media (min-width: 768px) {
padding: 40px;
.item {
width: 50%;
}
}
}
/* 不支持所有 @规则嵌套 */
.container {
@keyframes slide { /* 这个可能有问题 */
from { opacity: 0; }
to { opacity: 1; }
}
}
不要过度嵌套(保持深度在3层以内)
注意选择器特异性
/* 嵌套会增加特异性 */
#header {
.nav { /* 特异性: 1,1,0 */
color: blue;
}
}
/* 可能覆盖不了这个 */
.nav { /* 特异性: 0,1,0 */
color: red; /* 这个不会生效 */
}
PostCSS 处理兼容性(如果需要支持旧浏览器)// package.json
{
"devDependencies": {
"postcss": "^8.0.0",
"postcss-preset-env": "^8.0.0"
},
"postcss": {
"plugins": {
"postcss-preset-env": {
"stage": 1,
"features": {
"nesting-rules": true
}
}
}
}
}
/* 你写的现代 CSS(使用嵌套) */
.card {
padding: 20px;
& .title {
color: red;
}
&:hover {
background: blue;
}
}
/* PostCSS 会编译成 */
.card {
padding: 20px;
}
.card .title {
color: red;
}
.card:hover {
background: blue;
}