Стрелка прямоугольника для выбора цвета фона соответствующего прямоугольника. - PullRequest
0 голосов
/ 10 марта 2019

Я постараюсь объяснить это как можно проще:

Для этого пример Я хочу, чтобы стрелка каждого блока автоматически выбирала цвет фона соответствующего блока, добавляя в него только красные, черные, серые классы. Я мог бы легко сделать:

    .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, чтобы мне не пришлось беспокоиться об изменении цвета стрелки каждый раз, когда меняется цвет фона поля?

Спасибо.

См. ДЕМО

Ответы [ 3 ]

1 голос
/ 10 марта 2019

Так как ваш элемент будет иметь сплошной цвет, вы можете создать стрелку с прямоугольником, в котором вы применяете вращение для достижения макета, тогда вы можете использовать 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>
1 голос
/ 11 марта 2019

Этого можно достичь с помощью миксина SCSS. См. Кодовое поле здесь

В связанном кодовом элементе есть переменная, которая определяет ваши цвета:

$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;
      }
    }
  }
}

Миксин в основном добавляетновый класс для каждого цвета в $color-list и заполняет класс соответствующим цветом для фона и псевдоэлемента.

Миксин просто должен быть включен в класс .box:

.box {
  @include box-color();
  position: relative;
  width: 100px;
  height: 100px;
  margin-bottom: 40px;
}
1 голос
/ 10 марта 2019

Чтобы получить этот эффект, лучшим подходом будет использование наследования CSS.Поскольку родительский блок имеет заданный фон, то мы можем наследовать только значение свойства :after псевдоэлемента background - мы не можем использовать его для цвета границы.К счастью, мы можем получить эффект «треугольной стрелки», не используя рамку, а с обычным фоном и правилом clip-path.Полный пример показан во фрагменте ниже:

.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>
...