本站在允许 JavaScript 运行的环境下浏览效果更佳


CSS 预处理器如何正确的复用样式(stylus 中使用 @extend 继承的坑)

99

文章第二版发布时间:2024.5.9 19:00:00
文章更新日期:2024.5.8

初版本发布:2024.4.9 10:09:00
初版本发布标题:stylus 关于 @media 和继承的坑

文章更新日志:点我跳转

需求

要写一个亮暗自动切换的样式

渲染要求

明亮模式时 body[theme="auto"] 的样式要和 body[theme="light"] 一致
暗黑模式时 body[theme="auto"] 的样式要和 body[theme="dark"] 一致

styl 文件编译后预期结果

亮的样式在light.css (应有一个 body[theme="light"] 样式)
暗的样式在dark.css(应有一个 body[theme="dark"] 样式)
自动切换的样式在auto.css
auto.css 文件中应有三个有媒体查询
无结果 @media (prefers-color-scheme: no-preference)
查询为亮 @media (prefers-color-scheme: light)
查询为暗 @media (prefers-color-scheme: dark)
每个 @media 下都应有一个body[theme="auto"] 样式)

一句话总结本文

样式复用要用mixin或者@block,而不是直接@extend 所谓“继承”

如何使用本文中的代码

  1. 确保你配置好了 pnpm

  2. 创建一个目录

  3. 在这个目录下按照本文提供的目录结构创建对应空文件
    (例:运行本文第一个错误代码示例此时应该创建这三个文件 light.styldark.stylauto.styl

  4. 在这个目录下打开终端

  5. 在终端运行以下代码

    pnpm install stylus --save-dev
    
  6. 复制文中的代码到对应文件

  7. 在终端运行以下代码,将 styl 文件转换为 css 文件

    pnpm stylus auto.styl dark.styl light.styl
    
  8. 终端应提示

    compiled auto.css
    compiled dark.css
    compiled light.css
    
  9. 查看目录下生成的 light.cssdark.cssauto.css 是否符合期望

错误代码

本例文件结构

.
├── light.styl
├── dark.styl
└── auto.styl

light.styl

body[theme="light"]
    background-color: white

dark.styl

body[theme="dark"]
    background-color: black

auto.styl

@import "dark"
@import "light"

@media (prefers-color-scheme: no-preference)
    body[theme="auto"]
        @extend body[theme="light"]

@media (prefers-color-scheme: light)
    body[theme="auto"]
        @extend body[theme="light"]

@media (prefers-color-scheme: dark)
    body[theme="auto"]
        @extend body[theme="dark"]

错误代码编译后的结果

light.css

body[theme="light"] {
  background-color: #fff;
}

dark.css

body[theme="dark"] {
  background-color: #000;
}

auto.css

body[theme="dark"],
body[theme="auto"] {
  background-color: #000;
}
body[theme="light"],
body[theme="auto"] {
  background-color: #fff;
}

正确代码

Mixins写法

本例文件结构

.
├── mixins
│   ├── mixin-light.styl
│   └── mixin-dark.styl
├── light.styl
├── dark.styl
└── auto.styl

mixins/mixin-light.styl

theme-light()
    background-color: white

mixins/mixin-dark.styl

theme-dark()
    background-color: black

light.styl

@import "mixins/mixin-light"

body[theme="light"]
    theme-light()

dark.styl

@import "mixins/mixin-dark"

body[theme="dark"]
    theme-dark()

auto.styl

@import "mixins/mixin-light"
@import "mixins/mixin-dark"

@media (prefers-color-scheme: no-preference)
    body[theme="auto"]
        theme-light()

@media (prefers-color-scheme: light)
    body[theme="auto"]
        theme-light()

@media (prefers-color-scheme: dark)
    body[theme="auto"]
        theme-dark()

另一种正确的写法

@block写法

本例文件结构

.
├── mixins
│   ├── mixin-light.styl
│   └── mixin-dark.styl
├── light.styl
├── dark.styl
└── auto.styl

mixins/mixin-light.styl

theme-light =
    background-color: white

mixins/mixin-dark.styl

theme-dark =
    background-color: black

light.styl

@import "mixins/mixin-light"

body[theme="light"]
    {theme-light}

dark.styl

@import "mixins/mixin-dark"

body[theme="dark"]
    {theme-dark}

auto.styl

@import "mixins/mixin-light"
@import "mixins/mixin-dark"

@media (prefers-color-scheme: no-preference)
    body[theme="auto"]
        {theme-light}

@media (prefers-color-scheme: light)
    body[theme="auto"]
        {theme-light}

@media (prefers-color-scheme: dark)
    body[theme="auto"]
        {theme-dark}

正确代码编译后的结果

light.css

body[theme="light"]{
    background-color: white
}

dark.css

body[theme="dark"]{
    background-color: black
}

auto.css

@media (prefers-color-scheme: no-preference){
    body[theme="auto"]{
        background-color: white
    }
}

@media (prefers-color-scheme: light){
    body[theme="auto"]{
        background-color: white
    }
}

@media (prefers-color-scheme: dark){
    body[theme="auto"]{
        background-color: black
    }
}

结语

如想进行进一步交流,请在评论区留言

文章更新日志

24.5.8

  • 为代码示例补充了目录结构
  • 重写 需求
  • 添加 如何使用本文中的代码

24.4.6

  • 文章初发布