Заставить рамку-изображение работать с градиентами

Я работаю над веб-приложением, в котором в качестве стилей используются response.js и sass (поэтому все мои файлы стилей -.scss). У меня есть текстовое поле с текущим стилем:

input[type=text] {
  text-align: center;
  font: inherit;
  border: 6px solid #999999;
  padding: 5px 5px;
  font-size: 15px;
  box-shadow: 0 1px 1px #DDD;
  width: 223px;
  outline: none;
  display: block;
  color: #7B8585;
  margin: 0 auto 20px;
}

В какой-то момент мое приложение хочет изменить цвет границы. Вот что у меня есть для этого:

var borderStyle;
if (gradient) {
  borderStyle = {
    'borderImage': '-webkit-linear-gradient(left, #0083c5 0%, #0083c5 33%, #ec4a26 66%, #ec4a26 100%)',
  };
}

Позже, компонент ввода:

<input type="text" style={borderStyle} onChange={this.handleChange} />

В настоящее время я вижу белую рамку с крошечным изображением красно-синего градиента в каждом углу рамки. Я пытался использовать borderColor, который не работает с градиентами вообще, по-видимому. Я что-то упускаю из виду или невозможно сделать простой градиент границы?

Желаемый результат - градиент слева направо (поэтому левая граница полностью синяя, правая полностью красная, а верхняя и нижняя границы имеют переход с синего на красный).


В ответ на ответ Гарри я изменил следующий код:

if (gradient) {
  borderStyle = {
    borderImage: 'linear-gradient(to right, #0083c5 0%, #0083c5 33%, #ec4a26 66%, #ec4a26 100%)',
    borderImageSlice: 1
  };
}

как указано в документе для реагирования для встроенных стилей. Однако, когда я проверяю элемент, borderImageSlice определенное мной свойство отсутствует; только borderImage один там, и у меня все еще есть только крошечные градиенты в углах границы.

2 ответа

Решение

Вам нужно добавить border-image-slice собственность также при применении границы. Делая это, вы получите точный результат, который вам нужен.

Я добавил его через сам CSS в следующем фрагменте (без JS), но вы должны быть в состоянии адаптировать его:)

input[type=text] {
  text-align: center;
  font: inherit;
  border: 6px solid #999999;
  padding: 5px 5px;
  font-size: 15px;
  box-shadow: 0 1px 1px #DDD;
  width: 223px;
  outline: none;
  display: block;
  color: #7B8585;
  margin: 0 auto 20px;
  border-image: linear-gradient(to right, #0083c5 0%, #0083c5 33%, #ec4a26 66%, #ec4a26 100%);
  border-image-slice: 1;
}
<input type="text" />

Примечание: я также изменил синтаксис градиента, чтобы использовать стандартный синтаксис, чтобы он работал во всех браузерах, которые поддерживают border-image имущество.


Ниже приведен фрагмент, который применяет изображение границы, когда текст в поле ввода изменяется.

var ip = document.getElementById("inp");

ip.addEventListener("change", function() {
  this.style.borderImage = 'linear-gradient(to right, #0083c5 0%, #0083c5 33%, #ec4a26 66%, #ec4a26 100%)';
  this.style.borderImageSlice = '1';
});
input[type=text] {
  text-align: center;
  font: inherit;
  border: 6px solid #999999;
  padding: 5px 5px;
  font-size: 15px;
  box-shadow: 0 1px 1px #DDD;
  width: 223px;
  outline: none;
  display: block;
  color: #7B8585;
  margin: 0 auto 20px;
}
<input type="text" id="inp" />


Похоже, ReactJS по умолчанию добавляет px в качестве единиц для всех чисел, которые передаются для встроенных стилей и из-за этого border-image-slice: 1 ошибочно устанавливается как border-image-slice: 1px, Поскольку в CSS это свойство является модульным свойством, оно не применяется должным образом. Решение состоит в том, чтобы заключить это значение в кавычки, а также добавить точку с запятой в кавычки (как в приведенном ниже примере кода):

var borderStyle = {
    borderImage: 'linear-gradient(to right, #0083c5 0%, #0083c5 33%, #ec4a26 66%, #ec4a26 100%)',
      borderImageSlice: '1;' // note the quotes and the semi-colon.
  };

Большие заслуги в выяснении этой проблемы достаются Henrik Andersson.

JSBin Demo с ReactJS

Мне удалось решить эту проблему, добавив 1 / 1 / 0 stretch самостоятельно к встроенному стилю, чтобы он выглядел так:

      var borderImage = `linear-gradient(to right, #1A80AC 0%, #1A80AC ${position.x / 3}%,
#8798AD ${ position.x / 3 }%, #8798AD 100%) 1 / 1 / 0 stretch`
Другие вопросы по тегам