Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

background

The traditional way to write CSS class names is to write:

.container .form .input .warpper .icon {
  /* Write your desired CSS */
}  
 
.container .form .text  {
  /* Write your desired CSS */
}
 
.page .warpper .layout .content{
  /* Write your desired CSS */
}
Copy the code

The above has the following problems:

  • When maintaining CSS, we cannot know the scope of the current CSS by looking at HTML. CSS performance is not clear enough
  • If I want to override the CSS style, I may need to override the original CSS using the CSS priority rules, which will lead to CSS priority competition
  • CSS is not written with high reusability. When multiple styles are consistent, we may choose to reduce the namespace to increase the scope of the current CSS, but this may lead to CSS style conflicts

BEM

  • B-block: indicates one block
  • E-element: indicates one element
  • M-modifier, a modifier for a block or element

The following is the division of navBar components:

The entire navbar component consists of a block named. Navbar, with the left and right sides and middle headings of element, and the class names of.navbar__left,.navbar__right,.navbar__title, If navbar can be set to dark, add a. Navbar –dark to the. Navbar class named Modifier.

The class name for BEM is

  • .b
  • .b__e
  • B__e – m
  • B – m

These four ways to write it.

BEM writing benefits

  • Class has only one level of style hierarchy, making it easy to override the original style with higher-priority styles
  • Define a block by block, element, modifier, similar to component disassembly design, easy to know where a class name is scoped

SCSS automatically generates BEM class names

By using SCSS’s mixin syntax, you can make it automatically generate BEM class names.

_config.scss

/** * SCSS configuration items: namespace and BEM */
$namespace: 'wd'; // The prefix namespace can be modified to suit your needs. $elementSeparator:'__';
$modifierSeparator: The '-';
$state-prefix: 'is-';
Copy the code

_function.scss

/** ** auxiliary function */
@import 'config';

/* converts to the string */
@function selectorToString($selector) {
  $selector: inspect($selector);
  $selector: str-slice($selector, 2, -2);
 
  @return $selector;
}
 
/* Check whether there is any Modifier */
@function containsModifier($selector) {
  $selector: selectorToString($selector);
 
  @if str-index($selector, $modifierSeparator) {
    @return true;
  } @else {
    @returnfalse; }}/* Check whether there are pseudo classes */
@function containsPseudo($selector) {
  $selector: selectorToString($selector);
 
  @if str-index($selector, ':') {
    @return true;
  } @else {
    @returnfalse; }}Copy the code

_mixin.scss

/** ** blend macro */
@import 'config';
@import 'function';
 
 
/** * BEM */
@mixin b($block) {
  $B: $namespace + The '-'+ $block ! global; . # {$B} {
    @content; }}/* For pseudo-classes, e is automatically nested under the pseudo-class */
@mixin e($element...) {
  $selector: &;
  $selectors: ' ';
 
  @if containsPseudo($selector) {
    @each $item in $element {
      $selectors: #{$selectors + '. ' + $B + $elementSeparator + $item + ', '};
    }
    @at-root {
      #{$selector} {
        #{$selectors} {
          @content; }}}}@else {
    @each $item in $element {
      $selectors: #{$selectors + $selector + $elementSeparator + $item + ', '};
    }
    @at-root {
      #{$selectors} {
        @content; }}}}@mixin m($modifier...) {
  $selectors: ' ';
  @each $item in $modifier {
    $selectors: #{$selectors + & + $modifierSeparator + $item + ', '};
  }
 
  @at-root {
    #{$selectors} {
      @content; }}}/* For e that needs to be nested under m, call this blend macro, usually when switching the state of the entire component, such as switching colors */
@mixin me($element...) {
  $selector: &;
  $selectors: ' ';
 
  @if containsModifier($selector) {
    @each $item in $element {
      $selectors: #{$selectors + '. ' + $B + $elementSeparator + $item + ', '};
    }
    @at-root {
      #{$selector} {
        #{$selectors} {
          @content; }}}}@else {
    @each $item in $element {
      $selectors: #{$selectors + $selector + $elementSeparator + $item + ', '};
    }
    @at-root {
      #{$selectors} {
        @content; }}}}/ * * /
@mixin when($state) {
  @at-root {
    &.#{$state-prefix + $state} {
      @content; }}}/** ** ** /
 
/* Single line beyond hidden */
@mixin lineEllipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
 
/* Multiple lines beyond hidden */
@mixin multiEllipsis($lineNumber: 3) {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: $lineNumber;
  overflow: hidden;
}
 
/* Clear float */
@mixin clearFloat {
  &::after {
    display: block;
    content: ' ';
    height: 0;
    clear: both;
    overflow: hidden;
    visibility: hidden; }}/* 0.5px border */
@mixin halfPixelBorder($direction: 'bottom', $left: 0) {&::after {
    position: absolute;
    display: block;
    content: ' ';
    width: 100%;
    height: 1px;
    left: $left;
    @if ($direction == 'bottom') {
      bottom: 0;
    }
    @else {
      top: 0;
    }
    transform: scaleY(0.5);
    background: $-color-border-light; }}@mixin buttonClear {
  outline: none;
  -webkit-appearance: none;
  -webkit-tap-highlight-color: transparent;
  background: transparent;
}
Copy the code

SCSS import supports ignoring the _ and suffix of the file name

Use:

@include b(navbar) {
  / * * /
 
 
  @include m(dark) {
    / * * /
 
 
    Wd-navbar__left {}. Wd-navbar__right {}} @include e(left) {/* Style */
 
 
    &::before {
      /* Support writing pseudo-elements and pseudo-classes directly */}}@include e(right) {
    / * * /
 
 
    Wd-navbar__right. Is-icon */
    @include when(icon) {
      / * * /}}}Copy the code

The code above ends up generating CSS like this:

.wd-navbar {}
.wd-navbar--dark {}
.wd-navbar--dark .wd-navbar__left {}
.wd-navbar--dark .wd-navbar__right {}
.wd-navbar__left {}
.wd-navbar__left::before {}
.wd-navbar__right {}
.wd-navbar__right.is-icon {}

Copy the code

Praise support, hand left lingering fragrance, with rongyan, move your rich little hands yo, thank you big guy can leave your footprints.

Past wonderful recommendation

How does the front end internationalize

React Development specification

Vue development specification

Mobile end horizontal and vertical screen adaptation and bangs adaptation

Mobile frequently asked Questions

Front-end common encryption methods

Don’t know SEO optimization? An article helps you understand how to do SEO optimization

Wechat small program development guide and optimization practice

Talk about mobile adaptation

Front-end performance optimization for actual combat

Talk about annoying regular expressions

Obtain file BLOB stream address to achieve the download function

Vue virtual DOM confused? This article will get you through the virtual DOM once and for all

Git Git

Easy to understand Git introduction

Git implements automatic push

Interview Recommendations

Front ten thousand literal classics – the foundation

Front swastika area – advanced section

More exciting details: personal homepage