位置:石家庄网页制作 > 新闻中心 > seo知识 >

网站建设之CSS知识【十年老前台不传之秘】
2020-12-12 展为网络
在mixin中,我们需要编写Sass来执行以下操作:

render()
“嘿$imports,天气好吗?说,您的地图中有容器对象吗?”
$进口
false
render()
“太可惜了,看起来它那时不会被编译。按钮组件呢?”
$进口
true
render()
“不错!那就是正在编译的按钮。跟我妻子打个招呼。”
在Sass中,这转换为以下内容:

src/scss/tools/_render.scss
@mixin render($name, $layer) {
   @if(index(map-get($imports, $layer), $name)) {
      @content;
   }
}
复制
基本上,检查局部$imports变量是否包含在变量中,如果是,则使用Sass@content指令对其进行渲染,这使我们可以将内容块传递给mixin。

我们将这样使用它:

例子5
@include render('button', 'component') {
   .c-button {
      // styles et al
   }

   // any other class declarations
}
复制
在使用此mixin之前,我们可以对其进行一些小的改进。层名称(对象,组件,实用程序等)是可以安全预测的,因此我们有机会稍微简化一下。

在渲染mixin声明之前,创建一个名为的变量$layer,然后从mixins参数中删除名称相同的变量。像这样:

src/scss/tools/_render.scss
$layer: null !default;
@mixin render($name) {
   @if(index(map-get($imports, $layer), $name)) {
      @content;
   }
}
复制
现在,在_core.scss对象,组件和实用程序所在的局部中,@imports将这些变量重新声明为以下值;表示要导入的CSS类的类型。

src/scss/objects/_core.scss
$layer: 'object';

@import 'box';
@import 'container';
@import 'layout';
复制
src/scss/components/_core.scss
$layer: 'component';

@import 'button';
@import 'expander';
@import 'typography';
复制
src/scss/utilities/_core.scss
$layer: 'utility';

@import 'alignments';
@import 'widths';
复制
这样,当我们使用render()mixin时,我们要做的就是声明部分名称。

按照以下说明,将render()mixin包装在每个对象,组件和实用程序类声明周围。这将为您提供每个部分的渲染混合使用。

例如:

src/scss/objects/_layout.scss
@include render('button') {
   .c-button {
      // styles et al
   }

   // any other class declarations
}
复制
src/scss/components/_button.scss
@include render('button') {
   .c-button {
      // styles et al
   }

   // any other class declarations
}
复制
注意:对于utilities/_widths.scss,将render()函数包装在整个部分中会在编译时出错,因为在Sass中,您不能在mixin调用中嵌套mixin声明。相反,只需将render()mixin包裹在create-widths()调用周围,如下所示:

@include render('widths') {

// GENERATE STANDARD WIDTHS
//---------------------------------------------------------------------

// Example: .u-width-1/3
@include create-widths($utility-widths-sets);

// GENERATE RESPONSIVE WIDTHS
//---------------------------------------------------------------------

// Create responsive variants using settings.breakpoints
// Changes width when breakpoint is hit
// Example: .u-width-1/3@md

@each $bp-name, $bp-value in $mq-breakpoints {
   @include mq(#{$bp-name}) {
      @include create-widths($utility-widths-sets, \@, #{$bp-name});
   }
}

// End render
}
复制
有了这个,在构建时,只会$imports编译其中引用的部分。

混合并匹配注释掉的组件$imports并npm run build在终端中运行以进行尝试。

依存关系图
现在我们以编程方式导入局部函数,我们可以开始实现依赖关系逻辑。

在src/scss/settings,创建一个新的部分叫_dependencies.scss,@import它settings/_core.scss,但要确保它之后_imports.scss。然后在其中创建以下SCSS映射:

src/scss/settings/_dependencies.scss
$dependencies: (
   expander: (
      object: (
         'box',
         'layout'
    ),
    component: (
         'button',
         'typography'
    ),
    utility: (
         'alignments',
         'widths'
    )
   )
);
复制
在这里,我们声明扩展器组件的依赖关系,因为它需要其他部分的样式才能正确呈现,如dist / index.html所示。

使用此列表,我们可以编写逻辑,这意味着无论$imports变量的状态如何,这些依赖项始终会与它们的依赖项一起被编译。

在下面$dependencies,创建一个名为的mixin dependency-setup()。在这里,我们将执行以下操作:

1.遍历依赖关系图。
@mixin dependency-setup() {
   @each $componentKey, $componentValue in $dependencies {
    
   }
}
复制
2.如果可以在中找到该组件$imports,请循环浏览其依赖项列表。
@mixin dependency-setup() {
   $components: map-get($imports, component);
   @each $componentKey, $componentValue in $dependencies {
      @if(index($components, $componentKey)) {
         @each $layerKey, $layerValue in $componentValue {

         }
      }
   }
}
复制
3.如果依赖项不在中$imports,请添加它。
@mixin dependency-setup() {
   $components: map-get($imports, component);
   @each $componentKey, $componentValue in $dependencies {
       @if(index($components, $componentKey)) {
           @each $layerKey, $layerValue in $componentValue {
               @each $partKey, $partValue in $layerValue {
                   @if not index(map-get($imports, $layerKey), $partKey) {
                       $imports: map-merge($imports, (
                           $layerKey: append(map-get($imports,  $layerKey), '#{$partKey}')
                       )) !global;
                   }
               }
           }
       }
   }
}
复制
包含该!global标志告诉Sass$imports在全局范围而不是mixin的本地范围中查找变量。

4.然后,只需调用mixin。
@mixin dependency-setup() {
   ...
}
@include dependency-setup();
复制
因此,我们现在有了一个增强的部分导入系统,在该系统中,如果导入了组件,则开发人员也不必手动导入其各个依赖部分。

配置$imports变量,以便仅导入扩展器组件,然后运行npm run build。您应该在编译后的CSS中看到扩展器类及其所有依赖项。

但是,就过滤掉未使用的CSS而言,这实际上并没有为表带来任何新东西,因为仍在以相同的方式(无论是否通过编程方式)导入相同数量的Sass。让我们对此进行改进。

改进的依赖项导入
组件可能只需要依赖项中的单个类,因此继续进行操作并导入该依赖项的所有类只会导致我们试图避免的不必要的膨胀。

我们可以优化系统以允许在逐个类的基础上进行更细化的过滤,以确保仅使用所需的依赖项类来编译组件。

对于大多数设计模式,无论是否进行装饰,都需要在样式表中提供更少数量的类,才能正确显示模式。

对于使用已建立的命名约定(例如BEM)的类名,通常至少需要“ Block”和“ Element”命名类,而“ Modifiers”通常是可选的。

注意: 实用程序类通常不会遵循BEM路线,因为它们的关注点很窄,它们在本质上是孤立的。

例如,看一下这个媒体对象,它可能是更著名的面向对象CSS的示例:

<div class="o-media o-media--spacing-small">
   <div class="o-media__image">
     <img src="url" alt="Image">
   </div>
   <div class="o-media__text">
      Oh!
   </div>
</div>
复制
如果组件具有这个集合的依赖,这是有道理的,始终编译.o-media,.o-media__image并且.o-media__text,因为这是需要CSS的更低量,使模式的工作原理。但是,.o-media--spacing-small由于它是一个可选的修饰符,因此只有在我们明确声明时才应对其进行编译,因为它的用法在所有媒体对象实例中可能不一致。

我们将修改$dependencies地图的结构,以允许我们导入这些可选类,同时包括一种在不需要修饰符的情况下仅导入块和元素的方法。

首先,请检查dist / index.html中的扩展器HTML,并记下所有正在使用的依赖项类。将这些记录在$dependencies地图上,如下所示:

src/scss/settings/_dependencies.scss
$dependencies: (
   expander: (
       object: (
           box: (
               'o-box--spacing-small'
           ),
           layout: (
               'o-layout--fit'
           )
       ),
       component: (
           button: true,
           typography: (
               'c-type-echo',
           )
       ),
       utility: (
           alignments: (
               'u-flex-middle',
               'u-align-center'
           ),
           widths: (
               'u-width-grow',
               'u-width-shrink'
           )
       )
   )
);
复制
将值设置为true时,我们会将其转换为“仅编译块和元素级别的类,没有修饰符!”。

下一步涉及创建一个白名单变量来存储这些类以及我们希望手动导入的任何其他(非依赖)类。在此/src/scss/settings/imports.scss之后$imports,创建一个名为的新Sass列表$global-filter。

src/scss/settings/_imports.scss
$global-filter: ();
复制
背后的基本前提$global-filter是,此处存储的任何类都将在build上编译,只要它们属于的部分通过导入即可$imports。

如果这些类名是组件依赖项,则可以通过编程方式添加,也可以在声明变量时手动添加,如以下示例所示:

全局过滤器示例
$global-filter: (
   'o-box--spacing-regular@md',
   'u-align-center',
   'u-width-6/12@lg'
);
复制
接下来,我们需要向@dependency-setupmixin添加更多的逻辑,以便将其中引用的任何类$dependencies自动添加到我们的$global-filter白名单中。

在此块下面:

src/scss/settings/_dependencies.scss
@if not index(map-get($imports, $layerKey), $partKey) {

}
复制
...添加以下代码段。

src/scss/settings/_dependencies.scss
@each $class in $partValue {
   $global-filter: append($global-filter, '#{$class}', 'comma') !global;
}
复制
这将遍历所有依赖项类,并将它们添加到$global-filter白名单中。

此时,如果您@debug在dependency-setup()mixin下面添加一条语句以打印$global-filter终端中的内容:

@debug $global-filter;
复制
...您应该在构建时看到类似这样的内容:

DEBUG: "o-box--spacing-small", "o-layout--fit", "c-box--rounded", "true", "true", "u-flex-middle", "u-align-center", "u-width-grow", "u-width-shrink"
复制
现在我们有了一个类白名单,我们需要在所有不同的对象,组件和实用程序部分之间强制执行此白名单。

创建一个名为_filter.scssin的新部分src/scss/tools并将一个添加@import到工具层的_core.scss文件。

在这个新的部分中,我们将创建一个名为的混合filter()。我们将使用它来应用逻辑,这意味着仅在$global-filter变量中包含类时才编译类。

从简单开始,创建一个接受单个参数的混入-$class过滤器控制。接下来,如果$class列入$global-filter白名单中,请对其进行编译。

src/scss/tools/_filter.scss
@mixin filter($class) {
   @if(index($global-filter, $class)) {
      @content;
   }
}
复制
在局部中,我们将mixin包裹在可选类的周围,如下所示:

@include filter('o-myobject--modifier') {
   .o-myobject--modifier {
      color: yellow;
   }
}
复制
这意味着.o-myobject--modifier该类仅在其包含在中时才可以编译$global-filter,可以直接设置或通过in中的设置间接设置$dependencies。

遍历存储库,并将filter()mixin应用于对象和组件层上的所有可选修饰符类。在处理印刷术组件或实用程序层时,由于每个类都与下一个类无关,因此将它们全部都设为可选是有意义的,因此我们可以根据需要启用类。

以下是一些示例:

src/scss/objects/_layout.scss
@include filter('o-layout__item--fit-height') {
    .o-layout__item--fit-height {
        align-self: stretch;
    }
}
复制
src/scss/utilities/_alignments.scss
// Changes alignment when breakpoint is hit
// Example: .u-align-left@md
@each $bp-name, $bp-value in $mq-breakpoints {
    @include mq(#{$bp-name}) {
        @include filter('u-align-left@#{$bp-name}') {
            .u-align-left\@#{$bp-name} {
                text-align: left !important;
            }
        }

        @include filter('u-align-center@#{$bp-name}') {
            .u-align-center\@#{$bp-name} {
                text-align: center !important;
            }
        }

        @include filter('u-align-right@#{$bp-name}') {
            .u-align-right\@#{$bp-name} {
                text-align: right !important;
            }
        }
    }
}
复制
注意:将响应性后缀类名添加到filter()mixin时,不必用'\'来转义'@'符号。

在此过程中,将filter()混入应用于部分片段时,您可能(也可能没有)注意到一些事情。

分组课程
返回列表

13933871212