• Scss--@extend--使用/实例


    原文网址:Scss--@extend--使用/实例_IT利刃出鞘的博客-CSDN博客

    简介

            本文介绍Scss的@extend的用法。

    @extend的作用

            在设计网页的时候常常遇到这种情况:一个元素使用的样式与另一个元素完全相同,但又添加了额外的样式。通常会在 HTML 中给元素定义两个 class,一个通用样式,一个特殊样式。假设现在要设计一个普通错误样式与一个严重错误样式,一般会这样写:

    1. <div class="error seriousError">
    2.   Oh no! You've been hacked!
    3. div>

    样式如下

    1. .error {
    2.   border: 1px #f00;
    3.   background-color: #fdd;
    4. }
    5. .seriousError {
    6.   border-width: 3px;
    7. }

            麻烦的是,这样做必须时刻记住使用 .seriousError 时需要参考 .error 的样式,带来了很多不变:智能比如加重维护负担,导致 bug,或者给 HTML 添加无语意的样式。使用 @extend 可以避免上述情况,告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。

    1. .error {
    2.   border: 1px #f00;
    3.   background-color: #fdd;
    4. }
    5. .seriousError {
    6.   @extend .error;
    7.   border-width: 3px;
    8. }

            上面代码的意思是将 .error 下的所有样式继承给 .seriousError,border-width: 3px; 是单独给 .seriousError 设定特殊样式,这样,使用 .seriousError 的地方可以不再使用 .error。

            其他使用到 .error 的样式也会同样继承给 .seriousError,例如,另一个样式 .error.intrusion 使用了 hacked.png 做背景,

    也同样会使用 hacked.png 背景。

    1. .error.intrusion {
    2.   background-image: url("/image/hacked.png");
    3. }

    原理概述

            @extend 的作用是将重复使用的样式 (.error) 延伸 (extend) 给需要包含这个样式的特殊样式(.seriousError),刚刚的例子:

    Scss:

    1. .error {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .error.intrusion {
    6. background-image: url("/image/hacked.png");
    7. }
    8. .seriousError {
    9. @extend .error;
    10. border-width: 3px;
    11. }

    编译后的CSS:

    1. .error, .seriousError {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .error.intrusion, .intrusion.seriousError {
    6. background-image: url("/image/hacked.png");
    7. }
    8. .seriousError {
    9. border-width: 3px;
    10. }

            合并选择器时,@extend 会很聪明地避免无谓的重复,.seriousError.seriousError 将编译为 .seriousError,不能匹配任何元素的选择器(比如 #main#footer )也会删除。

    复杂的选择器

            Class 选择器并不是唯一可以被延伸 (extend) 的,Sass 允许延伸任何定义给单个元素的选择器,比如 .special.cool,a:hover 或者 a.user[href^="http://"] 等。

    简单示例

    Scss

    1. a:hover {
    2.   text-decoration: underline;
    3. }
    4. .hoverlink {
    5.   @extend a:hover;
    6. }

    编译为

    1. a:hover, .hoverlink {
    2.   text-decoration: underline;
    3. }

    继承所有样式

            与上面 .error.intrusion 的例子一样,所有 a:hover 的样式将继承给 .hoverlink,包括其他使用到 a:hover 的样式。

    Scss

    1. .comment a.user:hover {
    2. font-weight: bold;
    3. }
    4. .hoverlink {
    5. @extend a:hover;
    6. }

    编译为

    1. .comment a.user:hover, .comment .user.hoverlink {
    2. font-weight: bold;
    3. }

    多重继承

    说明

            同一个选择器可以延伸给多个选择器,它所包含的属性将继承给所有被延伸的选择器。

    示例

    Scss

    1. .error {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .attention {
    6. font-size: 3em;
    7. background-color: #ff0;
    8. }
    9. .seriousError {
    10. @extend .error;
    11. @extend .attention;
    12. border-width: 3px;
    13. }

    编译后的CSS:

    1. .error, .seriousError {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .attention, .seriousError {
    6. font-size: 3em;
    7. background-color: #ff0;
    8. }
    9. .seriousError {
    10. border-width: 3px;
    11. }

            每个 .seriousError 将包含 .error 与 .attention 下的所有样式,这时,后定义的样式享有优先权:.seriousError 的背景颜色是 #ff0 而不是 #fdd,因为 .attention 在 .error 之后定义。

            多重延伸可以使用逗号分隔选择器名,比如 @extend .error, .attention; 与 @extend .error; @extend.attention 有相同的效果。

    链式继承

    说明

            当一个选择器继承给第二个后,可以继续将第二个选择器继承给第三个。

    示例

    SCSS

    1. .error {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .seriousError {
    6. @extend .error;
    7. border-width: 3px;
    8. }
    9. .criticalError {
    10. @extend .seriousError;
    11. position: fixed;
    12. top: 10%;
    13. bottom: 10%;
    14. left: 10%;
    15. right: 10%;
    16. }

            现在,每个 .seriousError 选择器将包含 .error 的样式,而 .criticalError 不仅包含 .seriousError 的样式也会同时包含 .error 的所有样式 

    编译后的CSS:

    1. .error, .seriousError, .criticalError {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. .seriousError, .criticalError {
    6. border-width: 3px;
    7. }
    8. .criticalError {
    9. position: fixed;
    10. top: 10%;
    11. bottom: 10%;
    12. left: 10%;
    13. right: 10%;
    14. }

    选择器列

    说明

            暂时不可以将选择器列 (Selector Sequences),比如 .foo .bar 或 .foo + .bar,延伸给其他元素,但是,却可以将其他元素延伸给选择器列。

    示例

    Scss

    1. #fake-links .link {
    2. @extend a;
    3. }
    4. a {
    5. color: blue;
    6. &:hover {
    7. text-decoration: underline;
    8. }
    9. }

    编译后的CSS:

    1. a, #fake-links .link {
    2. color: blue;
    3. }
    4. a:hover, #fake-links .link:hover {
    5. text-decoration: underline;
    6. }

    合并选择器列

    需要合并的场景

            有时会遇到复杂的情况,比如选择器列中的某个元素需要延伸给另一个选择器列,这种情况下,两个选择器列需要合并,比如:

    1. #admin .tabbar a {
    2. font-weight: bold;
    3. }
    4. #demo .overview .fakelink {
    5. @extend a;
    6. }

            技术上讲能够生成所有匹配条件的结果,但是这样生成的样式表太复杂了,上面这个简单的例子就可能有 10 种结果。所以,Sass 只会编译输出有用的选择器。

    示例1:不包含相同的选择器

            当两个列 (sequence) 合并时,如果没有包含相同的选择器,将生成两个新选择器:第一列出现在第二列之前,或者第二列出现在第一列之前。

    Scss

    1. #admin .tabbar a {
    2. font-weight: bold;
    3. }
    4. #demo .overview .fakelink {
    5. @extend a;
    6. }

    编译后的CSS:

    1. #admin .tabbar a,
    2. #admin .tabbar #demo .overview .fakelink,
    3. #demo .overview #admin .tabbar .fakelink {
    4. font-weight: bold;
    5. }

    示例2:包含相同的选择器

            如果两个列 (sequence) 包含了相同的选择器,相同部分将会合并在一起,其他部分交替输出。在下面的例子里,两个列都包含 #admin,输出结果中它们合并在了一起。

    SCSS:

    1. #admin .tabbar a {
    2. font-weight: bold;
    3. }
    4. #admin .overview .fakelink {
    5. @extend a;
    6. }

    编译后的CSS:

    1. #admin .tabbar a,
    2. #admin .tabbar .overview .fakelink,
    3. #admin .overview .tabbar .fakelink {
    4. font-weight: bold;
    5. }

    @extend-Only 选择器

    说明

            有时,需要定义一套样式并不是给某个元素用,而是只通过 @extend 指令使用,尤其是在制作 Sass 样式库的时候,希望 Sass 能够忽略用不到的样式。

            如果使用普通的 CSS 规则,最后会编译出很多用不到的样式,也容易与其他样式名冲突,所以,Sass 引入了“占位符选择器” (placeholder selectors),看起来很像普通的 id 或 class 选择器,只是 # 或 . 被替换成了 %。可以像 class 或者 id 选择器那样使用,当它们单独使用时,不会被编译到 CSS 文件中。

            占位符选择器需要通过延伸指令使用,用法与 class 或者 id 选择器一样,被延伸后,占位符选择器本身不会被编译。

    示例

    SCSS:

    1. // This ruleset won't be rendered on its own.
    2. #context a%extreme {
    3. color: blue;
    4. font-weight: bold;
    5. font-size: 2em;
    6. }
    1. .notice {
    2. @extend %extreme;
    3. }

    编译后的CSS: 

    1. #context a.notice {
    2. color: blue;
    3. font-weight: bold;
    4. font-size: 2em;
    5. }

    !optional 声明

            如果 @extend 失败会收到错误提示。比如: a.important {@extend .notice},当没有 .notice 选择器时将会报错,只有 h1.notice 包含 .notice 时也会报错,因为 h1 与 a 冲突,会生成新的选择器。

            如果要求 @extend 不生成新选择器,可以通过 !optional 声明达到这个目的,例如:

    1. a.important {
    2. @extend .notice !optional;
    3. }

    在指令中继承

            在指令中使用 @extend 时(比如在 @media 中)有一些限制:Sass 不可以将 @media 层外的 CSS 规则继承给指令层内的 CSS,这样会生成大量的无用代码。也就是说,如果在 @media (或者其他 CSS 指令)中使用 @extend,必须继承给相同指令层中的选择器。

    正确用法

    1. @media print {
    2. .error {
    3. border: 1px #f00;
    4. background-color: #fdd;
    5. }
    6. .seriousError {
    7. @extend .error;
    8. border-width: 3px;
    9. }
    10. }

    错误用法

    1. .error {
    2. border: 1px #f00;
    3. background-color: #fdd;
    4. }
    5. @media print {
    6. .seriousError {
    7. // INVALID EXTEND: .error is used outside of the "@media print" directive
    8. @extend .error;
    9. border-width: 3px;
    10. }
    11. }

    希望有一天,浏览器可以原生支持 @extend 指令,这样就可以在任何指令中使用延伸功能,不再受限制了。

  • 相关阅读:
    Allegro教学:Assembly层和Silkscreen元器件编号如何处理?
    单片机简介
    outlook邮件使用技巧
    扩展的多曝光图像合成算法及其在单幅图像增强中的应用。
    Neo4j导入RDF文件
    解读2022年度敏捷教练行业现状报告
    竞赛选题 机器视觉opencv答题卡识别系统
    视效剧情口碑双爆棚!Netflix 现象级剧集《怪奇物语》第四季神级视效专访大揭秘!
    2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?
    .NET周刊【5月第2期 2024-05-12】
  • 原文地址:https://blog.csdn.net/feiying0canglang/article/details/125790099