[组件库] Button

18 阅读1分钟

源码实现

  1. 按钮的状态变化: normal、hover、active、disabled

    • 因此在没有此四种状态的时候,按钮应该有一些基本的属性。

      • padding
      • font-size
      • border
    • 有状态的时候

      • color
      • background-color 亮度: normal < hover < click
      • border: color 与背景色保持一致
  2. theme-colors bg-color 产生预定义样式的按钮状态,包含:border、color

  3. 各种状态的color、bg-color、border

    • 背景色和文字颜色的函数关系, 比如:背景暗色、文字颜色应该是亮色

      // 相关讨论和链接
      // http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx
      // 参照 https://baike.baidu.com/item/YIQ/1977357?fr=aladdin
      @function color-yiq($color) {
        $r: red($color);
        $g: green($color);
        $b: blue($color); // $yiq 指颜色的明视度(Luminance),即亮度(Brightness)
        $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000; // 150
        @if ($yiq >=$yiq-contrasted-threshold) {
          // $yiq-text-dark: #212529 (gray-900);
          @return $yiq-text-dark;
        }
        @else {
          // white
          @return $yiq-text-light;
        }
      }
      
  4. 按钮大小

    1. TODO 疑惑🤔 这边的 Size 大中小,怎么定义,怎么定义呢?

    2. TODO 以目前来看,现在的有些大,没有太多的场景需要使用到这么大的 button

      // button size 构成函数
      @mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
        padding: $padding-y $padding-x;
        font-size: $font-size;
        line-height: $line-height;
        @if $enable-rounded {
            border-radius: $border-radius;
        }
        @else {
            border-radius: 0;
        }
      }
      
  5. loading 状态使用css animation实现, 而非 Icon

难点

  • css 优先级, css 优先级可视化工具:specificity.keegan.st/

    • &:not(:disabled):not(.disabled)&:not(:disabled)
    <!-- 33 行 -->
    .xx-btn:not(:disabled):not(.disabled) {
      cursor: pointer;
    }
    <!-- 37 行, 结果37行的被覆盖,说明下面的优先级更低 -->
    .xx-btn-primary.is-loading {
      cursor: default;
    }
    
    
  • 盒模型 状态:normal、hover、click、disabled 颜色:背景色、文字颜色、边框颜色 间距:padding、margin、border、line-height、height 状态:primary、success、info、warning、error、default、link 大小:large、normal、small 其他:圆角

  1. border: 1px slid transparent
  2. 按钮的文字颜色(color) 和 background-color 的自动关联函数-bootstrap

// 参照 https://baike.baidu.com/item/YIQ/1977357?fr=aladdin
// $color 一般为背景色 ( hover、click、nornal 时候的背景色)
@function color-yiq($color) {
    $r: red($color);
    $g: green($color);
    $b: blue($color); // $yiq 指颜色的明视度(Luminance),即亮度(Brightness)
    $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000; // 150
    @if ($yiq >=$yiq-contrasted-threshold) {
        // $yiq-text-dark: #212529 (gray-900);
        @return $yiq-text-dark;
    }
    @else {
        // white
        @return $yiq-text-light;
    }
}
// 会覆盖如下样式
//  1. 在鼠标点击的时候,激活 active 伪类;
input[type="button" i]:active, input[type="submit" i]:active, input[type="reset" i]:active, input[type="file" i]:active::-webkit-file-upload-button, button:active {
    border-style: inset;
}

// 2. 默认的border-color
border-color: rgb(216, 216, 216) rgb(209, 209, 209) rgb(186, 186, 186);

// 浏览器会给 button 默认上如下样式
border-style: solid;
border-width: 1px;
padding: 1px 7px 2px;
text-rendering: auto;
color: initial;
letter-spacing: normal;
word-spacing: normal;
text-transform: none;
text-indent: 0px;
text-shadow: none;
display: inline-block;
text-align: start;
margin: 0em;
font: 400 11px system-ui;
align-items: flex-start;
text-align: center;
cursor: default;
color: buttontext;
background-color: buttonface;
box-sizing: border-box;
padding: 2px 6px 3px;
border-width: 2px;
border-style: outset;
border-color: buttonface;
border-image: initial;