首页 > 解决方案 > 具有 BEM 命名便利的修饰符

问题描述

我现在喜欢在我的一些项目中使用 BEM 命名便利,我正在研究设计系统,我停止使用我的修改器。

我创建了我们在应用程序中使用的所有版本的 Input,我有这种情况:

我修改了几次输入:--is-invalid, --is -disabled--has-status并且我对 has-status 有问题。对于这种状态,我有更多的颜色,我不知道如何处理它。

我希望我的状态修改器像 .Input--has-status-load、.Input--has-status-warning 等。但问题是,我不想重复声明这个修改器 X 次,对于每个状态。这就是为什么我只为颜色添加类(.success 和 .warning),但这一点点破坏了我不想拆除的 BEM 命名便利。

你有什么主意吗?或者您对该代码有任何注释吗?

感谢您分享您的知识!

CodePen 演示

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  font-family: 'Source Sans Pro', sans-serif;
}

::placeholder {
  color: #ccc;
  opacity: 1;
  /* Firefox */
}

:-ms-input-placeholder {
  /* Internet Explorer 10-11 */
  color: #ccc;
}

::-ms-input-placeholder {
  color: #ccc;
}

.container {
  max-width: 1080px;
  margin: 0 auto;
}

.row {
  margin: 1em;
}

h2 {
  margin-top: 2em;
}


/* ============================================================================
   05 - COMPONENTS - Input.scss
   ========================================================================= */


/* Component structure: 
  .Input {}
  .Input__container {}
  .Input__fake-input {}
  .Input__field {}
  .Input__prefix {}
  .Input__suffix {}
  .Input__icon {}
  .Input--has-status {}
  .Input--is-invalid {}
  .Input--is-disabled {}
 */

// Component local variables
$input-border-color: #D8DADC;
$input-text-gray: #979797;
$input-text-color: #457CCC;
$input-border-radius: 8px;
$input-font-size: 16px;
// Base structure
.Input {
  position: relative;
}

// Input container for all elements
.Input__container {
  display: flex;
  position: relative;
  flex-direction: row;
  -webkit-box-align: center;
  align-items: center;
  -webkit-box-pack: justify;
  justify-content: space-between;
  height: 40px;
  font-size: $input-font-size;
}

// Input fake input, who replaces real input
.Input__fake-input {
  width: 100%;
  position: absolute;
  z-index: 1;
  top: 0px;
  left: 0px;
  height: 40px;
  font-size: $input-font-size;
  border-radius: $input-border-radius;
  transition: all 0.15s ease-in-out 0s;
  border-width: 1px;
  border-style: solid;
  border-color: $input-border-color;
  border-image: none;
}

// Input text field for add text
.Input__field {
  border: 0;
  -webkit-appearance: none;
  color: $input-text-color;
  font-size: inherit;
  background-color: transparent;
  width: 100%;
  height: 100%;
  z-index: 2;
  padding: 0px 12px;
  flex: 1 1 20%;
  border-radius: $input-border-radius;
  &:focus {
    outline: none;
    &~.Input__fake-input {
      outline: none;
      border: 1px solid #0284FF;
    }
  }
}

// Input type PREFIX
.Input__prefix {
  height: 100%;
  color: $input-text-gray;
  display: flex;
  -webkit-box-align: center;
  align-items: center;
  pointer-events: none;
  -webkit-box-pack: center;
  justify-content: center;
  z-index: 3;
  padding: 0px 0px 0px 10px;
}

// Input type SUFFIX
.Input__suffix {
  height: 100%;
  color: $input-text-gray;
  display: flex;
  flex-shrink: 0;
  -webkit-box-align: center;
  align-items: center;
  -webkit-box-pack: center;
  justify-content: center;
  z-index: 3;
  padding: 0px 10px 0px 0;
}

// Input type ICON
.Input__icon {
  height: calc(100% - 2px);
  color: $input-text-gray;
  display: flex;
  flex-shrink: 0;
  -webkit-box-align: center;
  align-items: center;
  -webkit-box-pack: center;
  justify-content: center;
  z-index: 3;
  padding: 0px 10px;
  position: relative;
  width: 48px;
  border-left: 1px solid $input-border-color;
  cursor: pointer;
  & img,
  svg {
    width: 25px;
  }
}

// Modificator --has-status
.Input--has-status {
  position: relative;
}

.Input--has-status::after {
  content: '';
  position: absolute;
  top: -4px;
  right: -4px;
  z-index: 3;
  width: 10px;
  height: 10px;
  border-radius: 100%;
  background: #1A73E8;
}

// --has-status types
.Input--has-status.success::after {
  background: #37C9AD;
}

.Input--has-status.warning::after {
  background: #FFB000;
}

// Modificator --is-invalid
.Input--is-invalid {
  & .Input__fake-input {
    border: 1px solid #FF0054;
  }
  & .Input__field {
    color: #FF0054;
    &:focus~.Input__fake-input {
      border-color: #FF0054;
    }
  }
}

// Modificator --is-disabled
.Input--is-disabled {
  & .Input__fake-input {
    background-color: #E8EAEC;
    border-color: #E8EAEC;
    color: #868C92;
    ursor: not-allowed;
    border: 1px solid #E8EAEC;
  }
  & .Input__field {
    color: #868C92;
    cursor: not-allowed;
  }
}
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,900&display=swap" rel="stylesheet">

<div class="container">
  <form>
    <div class="row">
<h1> Types</h1>
      <h2>Input - default</h2>
      <div class="Input">
        <div class="Input__container">
          <input class="Input__field" type="text" placeholder="Placeholder">
          <div class="Input__fake-input"></div>
        </div>
      </div>

      <h2>Input - prefix</h2>
      <div class="Input">
        <div class="Input__container">
          <div class="Input__prefix">
            <span class="Prefix">Prefix</span>
          </div>
          <input class="Input__field" type="text" placeholder="Placeholder" value="Lorem ipsum dolor">
          <div class="Input__fake-input"></div>
        </div>
      </div>

      <h2>Input - suffix</h2>
      <div class="Input">
        <div class="Input__container">
          <input class="Input__field" type="text" placeholder="Placeholder" value="Lorem ipsum dolor">
          <div class="Input__suffix">
            Suffix
          </div>
          <div class="Input__fake-input"></div>
        </div>
      </div>

     
      <h2>Input - icon</h2>
      <div class="Input">
        <div class="Input__container">
          <input class="Input__field" type="text" placeholder="Placeholder">
            <div class="Input__icon">
              <img src="https://image.flaticon.com/icons/svg/331/331383.svg">
            </div>
          <div class="Input__fake-input"></div>
        </div>
      </div>

      <br><br>
      <h1>Modificators</h1>
      <h2>Input - Load Success</h2>
      <div class="Input Input--has-status success">
        <div class="Input__container">
          <input class="Input__field" type="text" placeholder="Placeholder">
          <div class="Input__fake-input"></div>
        </div>
      </div>

      <h2>Input - Load Warning</h2>
      <div class="Input Input--has-status warning">
        <div class="Input__container">
          <input class="Input__field" type="text" placeholder="Placeholder">
          <div class="Input__fake-input"></div>
        </div>
      </div>


      <h2>Input - Invalid</h2>
      <div class="Input Input--is-invalid">
        <div class="Input__container">
          <input class="Input__field" type="text" placeholder="Placeholder" value="Lorem ipsum dolor">
          <div class="Input__fake-input"></div>
        </div>
      </div>

      <h2>Input - Disabled</h2>
      <div class="Input Input--is-disabled">
        <div class="Input__container">
          <input class="Input__field" type="text" placeholder="Placeholder" value="Lorem ipsum" disabled>
                      <div class="Input__icon">
              <img src="https://image.flaticon.com/icons/svg/331/331383.svg">
            </div>
          <div class="Input__fake-input"></div>
        </div>
      </div>
    </div>
  </form>
</div>

标签: csssyntaxnaming-conventionsnamingbem

解决方案


推荐阅读