• Sass中连体符(&)的运用


    在CSS中,这种想法是无法实现的,但在Sass中,可以轻松的通过连体符&来实现。这也是我们今天要说的。

    我们先来回忆一下,CSS中常见的一组样式:

    /*页面中链接的颜色*/
    a {clolor: #ff3366; }
    a:hover {color: #cc0033; }
    /*主菜单中链接的颜色*/
    .nav-menu a {color: #ff668c; }
    .nav-menu a:hover {color: #ff99b3; }
    .nav-menu a.active {color: #ff0040; }
    /*页脚菜单中链接的颜色*/
    .footer-menu a {color: #ff1a53; }
    .footer-menu a:hover {color: #cc0033; }

    这是一组控制页面链接颜色的样式代码,首先在样式中定义了通样的链接文本颜色,而主菜和页脚菜单中链接文本颜色各不相同,我们需要通过类名.nav-menu.footer-menu来覆盖默认的样式。这样我们在写样式的时候,在选择器这一部分,我们都需要书写相同的一个部分:

    a
    a:hover
    

    或许很多同学会说,这有什么的,真是大惊小怪。但是,如果你的选择器偏长,重复的代码偏多,一定会影响您的开发速度。从而影响您的效率。那么在Sass中,通过连体符&可以帮助我们避免这样的问题,而且还可以实现一些其他的效果。接下来,我们一起来看看Sass中&的一些使用方法以及其功能。

    与伪类的结合

    伪类和伪元素在CSS中是常用的一种方式。比如最常见的是链接的伪类或者说伪元素:after:before的使用。大家常看到的就是清除浮动的clearfix:

    .clearfix:before,
    .clearfix:after {
        content:"";
        display:table;
    }
    .clearfix:after {
        clear:both;
        overflow:hidden;
    }
    .clearfix {
        *zoom: 1;
    }

    那么在Sass中,使用&会变得更简单,更方便:

    $lte-ie: true !default;
    
    .clearfix {
        @if $lte-ie {
            *zoom: 1;
        }
    
        &:before,
        &:after {
            content: "";
            display: table;
        }
        &:after {
            clear: both;
            overflow: hidden;
        }
    }
    

    这个简单的例子非常明确说明,在Sass中可以使用&和伪元素、伪类配合使用,而且使用的方法非常简单。就是用&替代元素自身。

    多类选择器

    多类选择器.className1.className2在CSS中并不常见(主要因为在IE6中解析有所偏差,详情参考这里),但还是非常有用。比如说增加一个悬浮效果的时候,可以看到这样的样式代码:

    .mod.on {
        color: green;
    }

    那么在Sass中,同样可以使用&来替代选择器.mod

    .mod {
        &.on{
            color: green;
        }
    }
    

    这里需要特别的注意,&和相连的类名之间不能有任何的空格,不然就会变成CSS选择器中的后代选择器:

    .mod {
        & .on {
            color: green;
        }
    }
    

    编译出来的CSS就成了:

    .mod .on {
      color: green; 
    }

    在Sass中还有同等效果的写法是Sass的直接嵌套:

    .mod {
        .on {
            color: green;
        }
    }
    

    后代选择器

    正如上面的示例所示,在Sass中可以通过Sass的层级嵌套来实现后代选择器。嵌套的越深,层级越多:

    .nav-menu {
        li {
            a {
                color: green;
            }
        }
    }
    

    生成的CSS:

    .nav-menu li a {
      color: green; 
    }

    看到这里大家或许会问,这跟&有什么关系呢?因为在选择器前面加上&符和不加上&符将得到的效果是一样。但大家可能也碰到过,有时候在Sass先写了子元素的效果,但还需要另一个地方来覆盖,那么&将会起到大作用。先来看一个简单的示例:

    a {
        color: red;
    
        .nav-menu &{
            color: blue;
        }
    }
    

    生成的CSS:

    a {
      color: red; 
    }
    .nav-menu a {
      color: blue; 
    }

    示例非常简单的说明了一切,&在选择器后面时的功能。但这里需要特别的注意,&写在后面的,前面必须要有空格。不然Sass在编译时将会报错:

    >>> Change detected to: test.scss
          error test.scss (Line 78: Invalid CSS after " .nav-menu": expected "{", was "&{"
    
    "&" may only be used at the beginning of a compound selector.)
    

    综合上面所述,我们回到文章最开头的那段CSS代码,我们只需要灵活的运用好&,就可以轻松的完成:

    $color: #444;
    $bg-color: #f5f5f5;
    $link-color: #f36;
    
    a {
        clolor: $link-color;
    
        &:hover {
            color: darken($link-color, 20%);
        }
    
        //Main menu Link Color
        .nav-menu & {
            color: lighten($link-color, 10%);
    
            &:hover {
                color: lighten($link-color, 20%);
            }
    
            &.active {
                color: darken($link-color, 10%);
            }
        }
    
        //Footer menu link color
        .footer-menu & {
            color: darken($link-color, 5%);
    
            &:hover {
                color: darken($link-color, 20%);
            }
        }
    }
    

    相邻兄弟选择

    在CSS选择器中还有一种是相邻兄弟选择器+。如:

    label + input[type="text"]{...}
    

    input[type="text"]元素紧邻label元素。在Sass中,同样可以使用&符来替代其中某个元素:

    lable {
        color: green;
    
        & + input[type="text"] {
            border: 1px solid green;
        }
    }
    

    编译CSS:

    lable {
      color: green; 
    }
    lable + input[type="text"] {
      border: 1px solid green; 
    }

    在这里仅仅想通过这样一个简单的示例来演示&在选择器中所承载的对象,换句话说,就是&替代的是哪一处元素。这跟其所处的位置以及对应使用的选择器符号很有关系。

    媒体查询中的嵌套

    在Sass中,媒体查询配合&符,可以轻松的让你管理几个不同版式的样式(方便管理不同断点下的样式),先来看一个简单的示例:

    .main {
        float: left;
         45em;
    
        @media (max- 480px) {
            & {
                float: none;
                 100%;
            }
        }
    }
    

    编译出来的CSS:

    .main {
      float: left;
      width: 45em; 
    }
    @media (max- 480px) {
      .main {
        float: none;
        width: 100%; 
      } 
    }
    

    这样在制作响应式设计的时候是不是变得非常的简单,而且易于管理您的代码。

    不过除了上面种方式之外,我们还可以采用下面的方式与媒体查询配合使用:

    .main {
        float: left;
         45em;
    
        & {
            @media (max- 480px) {
                float: none;
                 100%;
            }
        }
    }
    

    这段SCSS代码编译出来的CSS和前面的是一模一样的。

    &符在Sass中存在的问题

    前面主要演示了&在Sass中如何让你更好的使用您的选择器,但是&在Sass中运用也存在一些问题。接下来一起看看&在Sass中存在的问题,以及如何避免这些问题。

    说到这个问题,我们继续拿CSS中的BEM来说事。先简单回忆一下BEM的模式:

    .block{...}
    .block__element{...}
    .block--modifier{...}
    

    很想在Sass中通过下面的方式实现BEM的模式:

    .block{
        ...
        &__element{...}
        &--modifier{...}
    }
    

    可是这样书写,编译器无法编译,将会报出错误信息:

    Invalid CSS after " &": expected "{", was "__element{"
    
    "__element" may only be used at the beginning of a compound selector.)
    

    此时很多人有可能想到了使用Sass中的插件#{&}的方式来替代.block

    .block{
        clolor: red;
        #{&}__element{
            color: green;
        }
        #{&}--modifier{
            color: blue;
        }
    }
    

    但编译出来的CSS代码还是不尽人意:

    .block {
      clolor: red; 
    }
    .block .block__element {
      color: green; 
    }
    .block .block--modifier {
      color: blue; 
    }

    编译出来的CSS代码虽然有效,但并不是好的CSS代码。而且这样编译出来的CSS也离开了BEM的初衷。

    这也是&在Sass中当作插值使用不尽人意之处。不过这种现像也有方法可以解决。简单一点的:

    $last-rule: null; 
    .block{
        clolor: red;
        $last-rule: &;
    }
    #{$last-rule}__element{
        color: green;
    }
    #{$last-rule}--modifier{
        color: blue;
    }
    

    编译出来的CSS:

    .block {
      clolor: red; 
    }
    .block__element {
      color: green; 
    }
    .block--modifier {
      color: blue; 
    }

    这种方法有两个关键之处:

    • 定义一个变量$last-rule,赋予变量值为null主要用来代表相同的前缀;
    • 在B中通过$last-rule:&来赋予新值也就代表了对应的缀。

    特别声明:采用这种方法,编译的时候会提示警告信息,但并不会影响代码编译:

    Assigning to global variable "$last-rule" by default is deprecated.
    In future versions of Sass, this will create a new local variable.
    If you want to assign to the global variable, use "$last-rule: & !global" instead.
    

    值得庆幸的是,在Sass的测试版本中有一个新的功能@at-root。使用他配合#{&}可以轻松的解决这个问题。

    .block {
        color: red;
    
        @at-root #{&}__element{
            color: green;
        }
    
        @at-root #{&}--modifier{
            color: blue;
        }
    }
    

    编译出来的CSS:

    .block {
      clolor: red; 
    }
    .block__element {
      color: green; 
    }
    .block--modifier {
      color: blue; 
    }

    这个是不是简单轻松多了。那么有关于@at-root与BEM结合在一起的详细介绍,可以猛击《Sass @at-root》一文。

    总结

    Sass中的连体符&让你在嵌套和插值的使用过程时,会让你忧,会让你喜。忧的是一不小心使用不对带来错误,或者让你的代码变得冗余。喜的是让你控制选择器变得更加的灵活。在这篇文章中,仅通过几个简单的示例,阐述了&在Sass中的一些基本使用方式,以有这些方式将会产生什么样的效果,又会带来什么样的麻烦,以及如何避免这些麻烦。希望对初学者有所帮助。

    著作权归作者所有。
    商业转载请联系作者获得授权,非商业转载请注明出处。
    原文: http://www.w3cplus.com/preprocessor/use-ampersand-in-selector-name-with-Sass.html © w3cplus.com

  • 相关阅读:
    计算机网络知识总结-网络安全
    域名恶意指向的解决方法
    域名恶意解析的原因是什么
    域名被人恶意解析的解决方法
    防止域名被恶意解析
    公安部网防G01-网站安全卫士软件/linux防御
    详解web容器
    关于 服务器ip和域名进行一个绑定
    重新温习软件设计之路(2)
    重新温习软件设计之路(1)
  • 原文地址:https://www.cnblogs.com/moxiaowohuwei/p/7388457.html
Copyright © 2020-2023  润新知