【问题标题】:Box arrow to take background colour of respective box框箭头采用相应框的背景颜色
【发布时间】:2019-08-01 02:34:00
【问题描述】:

我会尽量简单地解释这一点:

对于这个example,我希望每个框的箭头通过仅向框添加红色、黑色、灰色类来自动获取其各自框的背景颜色。 我可以轻松做到:

    .box.red {
      &:before {
        ...
        border-bottom: 1px solid $red;

      }
    }
   .box.black {
      &:before {
        ...
        border-bottom: 1px solid $black;

      }
    }
   .box.grey {
      &:before {
        ...
        border-bottom: 1px solid $grey;

      }
    }

但这意味着对于我创建的每种不同颜色,我都必须手动更改箭头颜色。例如,如果将来我想添加一个绿色框,我必须在 CSS 中将其箭头颜色更改为绿色。 Sass 中有没有办法做到这一点,所以我不必担心每次框背景颜色更改时都会更改箭头颜色?

谢谢。

See DEMO

【问题讨论】:

    标签: html css sass mixins


    【解决方案1】:

    由于您的元素将具有纯色,您可以在应用旋转的位置创建带有矩形的箭头以实现布局,然后您可以使用 inherit 作为背景

    .box {
      position: relative;
      width: 100px;
      height: 100px;
      margin-bottom: 40px;
      background:red;
    }
    .box::before {
      content:"";
      position:absolute;
      width:30px;
      height:30px;
      top:100%;
      left:20px;
      transform:translateY(-50%) rotateX(40deg) rotate(45deg);
      background:inherit;
    }
    
    .blue {
      background:blue;
    }
    .green {
      background:green;
    }
    <div class="box">
    
    </div>
    
    <div class="box blue">
    
    </div>
    <div class="box green">
    
    </div>

    您也可以依赖 CSS 变量,即使在很多地方使用,您也只能更改一次颜色。

    这是另一种创建形状的方法,您可以轻松控制箭头的颜色、大小和位置:

    .box {
      position: relative;
      width: 100px;
      height: 100px;
      padding-bottom: var(--s,20px);
      margin-bottom:10px;
      background:
        linear-gradient(to top right,transparent 49.8%,var(--c,red) 50%) var(--p,20px) 100%,
        linear-gradient(to top left, transparent 49.8%,var(--c,red) 50%) calc(var(--p,20px) + var(--s,20px)) 100%,
        var(--c,red) content-box;
      background-size:var(--s,20px) var(--s,20px);
      background-repeat:no-repeat;
    }
    
    .blue {
      --c:blue;
      --s:15px;
      --p:40px;
    }
    .green {
      --c:green;
      --s:10px;
      --p:60px;
    }
    <div class="box"></div>
    
    <div class="box blue"></div>
    
    <div class="box green"></div>

    您可以轻松地为您的代码实现相同的逻辑:

    .box {
      position: relative;
      width: 100px;
      height: 100px;
      margin-bottom: 40px;
      background:var(--c,green);
    }
    .box:before {
      content: ' ';
      border: solid transparent;
      border-bottom: 1px solid var(--c,green);
      border-width: 15px;
      height: 0;
      position: absolute;
      transform: rotate(180deg);
      width: 0;
      bottom: -30px;
      left: 20px;
    }
    
    .red {
      --c: #f00;
    }
    
    .black {
      --c: #000;
    }
    
    .grey {
      --c: #aaa;
    }
    <div class="box red"></div>
    <div class="box black"></div>
    <div class="box grey"></div>
    <div class="box "></div>

    【讨论】:

      【解决方案2】:

      要获得这种效果,最好的方法是使用 css 继承。由于父框设置了背景,那么我们只能继承:after伪元素background属性上的值——我们不能在边框颜色上使用它。幸运的是,我们可以在不使用边框的情况下获得“三角箭头”效果,而是使用常规背景和clip-path 规则。完整示例如下面的 sn-p 所示:

      .box {
        position: relative;
        width: 100px;
        height: 100px;
        margin-bottom: 40px;
      }
      .box:before {
        content: '';
        position: absolute;
        background: inherit;
        clip-path: polygon(0 0, 30px 0, 15px 15px);
        width: 30px;
        height: 15px;
        bottom: -16px;
        left: 20px;
      }
      
      .red {
        background: #f00;
      }
      
      .black {
        background: #000;
      }
      
      .grey {
        background: #aaa;
      }
      <div class="box red"></div>
      <div class="box black"></div>
      <div class="box grey"></div>

      IE 和 Edge 更新

      如果所有这些都是真的:

      1. 您关心的是与 IE 和 Edge 的兼容性
      2. 您可以在 CSS 规则中处理一些微重复
      3. 您不打算在 .box 元素上设置边框

      那么您可以将border-bottom-color 应用到.box 类中,并在:after 伪元素定义中继承它,如下所示:

      .box {
        position: relative;
        width: 100px;
        height: 100px;
        margin-bottom: 40px;
      }
      .box:before {
        content: ' ';
        border-bottom: 1px solid;
        border-bottom-color: inherit;
        border-left: 1px solid transparent;
        border-right: 1px solid transparent;
        border-top: 1px solid transparent;
        border-width: 15px;
        height: 0;
        position: absolute;
        transform: rotate(180deg);
        width: 0;
        bottom: -30px;
        left: 20px;
      }
      
      .red {
        background: #f00;
        border-bottom-color: #f00;
      }
      
      .black {
        background: #000;
        border-bottom-color: #000;
      }
      
      .grey {
        background: #aaa;
        border-bottom-color: #aaa;
      }
      <div class="box red"></div>
      <div class="box black"></div>
      <div class="box grey"></div>

      【讨论】:

      • 感谢您的回答。这是一个很好的解决方案,但是 clip-path 的问题是它不受最新版本的 IE 和 Edge 的支持。
      • 用 IE 和 Edge 的第二种解决方案更新了答案
      【解决方案3】:

      这可以使用 SCSS mixin 来实现。 See codepen here

      在链接的 codepen 中,有一个变量可以定义你的颜色:

      $color-list: (
        "red": #f00,
        "black": #000,
        "grey": #aaa,
      );
      

      这个变量是唯一需要定义颜色的地方。如果需要更多框,您可以轻松添加更多颜色。

      然后有一个@mixin,它添加了background-color 和彩色边框:

      @mixin box-color() {
        @each $color in map-keys($color-list) {
          &.#{$color} {
            background: map-get($color-list, $color);
            &:before {
              content: ' ';
              border: solid transparent;
              border-bottom: 1px solid map-get($color-list, $color);
              border-width: 15px;
              height: 0;
              position: absolute;
              transform: rotate(180deg);
              width: 0;
              bottom: -30px;
              left: 20px;
            }
          }
        }
      }
      

      mixin 基本上为$color-list 中的每种颜色添加了一个新类,并为该类填充了适合背景和伪元素的颜色。

      mixin 必须包含在 .box 类中:

      .box {
        @include box-color();
        position: relative;
        width: 100px;
        height: 100px;
        margin-bottom: 40px;
      }
      

      【讨论】:

        猜你喜欢
        • 2019-05-03
        • 2014-10-13
        • 1970-01-01
        • 2013-10-30
        • 2021-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多