Странный эффект границы градиента


при применении прозрачной границы над элементом linear-gradient в качестве фона, я получаю странный эффект.

обратите внимание, что левая и правая стороны элемента не имеют правильных цветов (они каким-то образом переключены) и странно квартира.

HTML

<div class="colors">
</div>

CSS

.colors {
    width: 100px;
    border: 10px solid rgba(0,0,0,0.2);
    height: 50px;
    background: linear-gradient(to right, 
        #78C5D6,
        #459BA8,
        #79C267,
        #C5D647,
        #F5D63D,
        #F08B33,
        #E868A2,
        #BE61A5);
}

почему это показывает странный эффект на левой и правой стороне элемент, и что могу ли я сделать это?

вот скрипка:http://jsfiddle.net/fzndodgx/3/

8 69

8 ответов:

это потому, что начальная и конечная точки gradient находятся на краях padding-box и border отображается вне padding-box. Итак, границы выглядят смешно, потому что background повторяется с каждой стороны вне padding-box покрытия border-box.

The box-shadow:inset оказывается внутри padding-box (так же, как фон) и дает визуально тот же эффект, что и border, Так что вы можете попробовать использовать это вместо border:

box-shadow: inset 0 0 0 10px rgba(0,0,0,0.2);
padding: 10px;

потому что a box-shadow не занимает никакого места, вам нужно увеличить вашу прокладку соответственно.

Иллюстрация padding-box и border-box: enter image description here

демо http://jsfiddle.net/ilpo/fzndodgx/5/

решение

самый простой способ исправить эту проблему будут путем установки значения background-origin имущество в виде border-box .

.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-origin: border-box;
}
<div class="colors"></div>

причина поведения, упомянутого в вопросе

ниже приведены соответствующие background свойства, определяющие способ отображения градиента фона для этого случая:

  • background-origin - значение по умолчанию padding-box. Это означает, что фон на самом деле расположен относительно поля заполнения и поэтому начинается после border.
  • background-repeat - значение по умолчанию для этого есть repeat. Это означает, что изображение должно повторяться столько, сколько необходимо, чтобы покрыть всю область фоновой живописи.
  • background-clip - значение по умолчанию для этого есть border-box. Это означает, что изображение должно присутствовать под областью, занимаемой границы коробки также.

теперь, объединив все три, мы видим, что граница должна быть повторена как можно больше, чтобы она присутствовала даже под границами, и что ее исходное положение находится после границы коробки. Это означает, что фон должен повторяться циклически, чтобы заполнить область под границей с левой стороны. Из-за этого левая граница имеет цвет как правый конец градиента и наоборот.

By изменение его на border-box, мы делаем фон позиционироваться по отношению к границе окна. Этот параметр также влияет на размер фонового изображения и причина этого подробно описана ниже.


почему box-sizing: border-box не работает?

установка box-sizing как border-box не влечет за собой никаких изменений, потому что это свойство влияет только на размер коробки. Оно не имеет совершенно никакое влияние на следующее:

  • размер градиентного изображения (фактическая логика расчета описана ниже)
  • начальная точка (или положение) градиентного изображения
  • повторение фонового изображения

как рассчитывается размер градиента?

по состоянию на W3C spec, ниже показано, как вычисляются размеры изображения, когда не указан явный размер (по умолчанию значение auto).

если изображения не имеет ни внутренней ширины, ни внутренней высоты, его размер определяется как для ‘contain’

обратите внимание, как он говорит о размере изображения, а не о коробке. По сути, независимо от размера окна, размер фонового изображения будет рассчитываться на основе определения ключевых слов contain когда само изображение не имеет собственной высоты (какой CSS градиенты не имеют непохожих изображений).

The определение contain следующим образом:

масштабируйте изображение, сохраняя его внутреннее соотношение сторон (если оно есть), до самого большого размера, чтобы его ширина и высота могли поместиться внутри область позиционирования фона.

область позиционирования фона определяется следующим образом (при background-origin собственность определение):

для элементов, отображаемых как одно поле, указывает область позиционирования фона

таким образом, когда изображение не имеет собственной высоты (и в этом случае нет background-size также), размер изображения будет равен background-origin's значение (которое в нашем случае padding-box).

вот почему даже установка box-sizing как border-box не имеет никакого эффекта.

Примечание: акцент в цитируемые тексты все мои


если вы явно указать background-size как размер коробки, вы бы заметили, как проблема решается на правой стороне, но не на левой стороне. Это связано с тем, что теперь изображение достаточно большое, чтобы не повторяться под правой границей, но его начальная точка все еще находится после левой границы.

.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-size: 110px 60px;
}
.colors-2 {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  box-sizing: border-box;
  background-size: 100px 50px;
}
<div class="colors">
</div>
<div class="colors-2">
</div>

фон повторяется под границей. Фон работает только в "теле" элемента, под границей происходит расширение и начинается повторение.

посмотреть этой пример no-repeat на границе.

обновление

игра с фоном position & size может помочь, расширяя фон, а затем регулируя его местоположение.

Регистрация эта скрипка из.

или увидеть фрагмент:

.colors {
  padding: 10px;
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-size: 117%;
  background-position-x: 130px;
}
<div class="colors"></div>

градиент начинается в поле заполнения в соответствии с поведением модели CSS по умолчанию, поэтому имеет смысл, что самые начальные и самые конечные цвета появляются до бесконечности по обе стороны градиента, где будет граница.

то же самое верно для этого градиента (NSFW):

A GOD AWFUL EYE SORE

Он продолжается бесконечно в начальном значении (фиолетовый) слева и продолжается бесконечно с конечным значением (оранжевый) справа. Это может продолжаться бесконечно вверх с этим градиентом, и так оно и есть.

Это мое понимание того, почему это появляется, поэтому, решение использовать другую модель.

значение по умолчанию background-origin недвижимость padding-box что означает, что фон расположен и размер относительно поля заполнения.

фон также выходит ниже границы с background-clip по умолчанию свойство border-box, оно просто повторяется ниже границы. Вот почему вы видите правую сторону фона ниже левой границы и наоборот.

Итак, просто измените происхождение:

.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-origin: border-box;
}
<div class="colors"></div>

поочередно вы можете играть с размером и положением фона: добавьте 20px к размеру фона и расположите его на -10px-10px:

.colors {
  width: 100px;
  border: 10px solid rgba(0, 0, 0, 0.2);
  height: 50px;
  background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
  background-position: -10px -10px;
  background-size: calc(100% + 20px) calc(100% + 20px);
}
<div class="colors"></div>

другие ответы уже показали, как исправить проблему, но я подумал, что должен просто указать, что если вы увеличите border-width становится очевидным, что фон на самом деле повторяется.

.colors {
    width: 100px;
    border: 100px solid rgba(0,0,0,0.2);
    height: 50px;
    background: linear-gradient(to right, 
        #78C5D6,
        #459BA8,
        #79C267,
        #C5D647,
        #F5D63D,
        #F08B33,
        #E868A2,
        #BE61A5);
}

будет

enter image description here

если вы не хотите использовать box-shadow, вы могли бы использовать border-image и настроить цвета градиента:http://jsfiddle.net/9pcuj8bw/5/

.colors {
    width:100px;
    height: 50px;
    background: linear-gradient(to right, 
        #78C5D6,
        #459BA8,
        #79C267,
        #C5D647,
        #F5D63D,
        #F08B33,
        #E868A2,
        #BE61A5) no-repeat;
    border: 10px solid;
    border-image: linear-gradient(to right, 
        #0bc3b8,
        #068e8c,
        #f8c617,
        #ea5f24,
        #b2492c) 1;
}
<div class="colors"></div>

осторожно это работает не на IE10 или ниже: http://caniuse.com/#feat=border-image

его работа должным образом. Вы должны были использовать прозрачную границу на блоке так bg-цвет видя. Его линейный градиент, так что его сплошной цвет на левой и правой стороне. Если вы используете сплошную границу, вы можете увидеть правильный эффект. http://prntscr.com/7mo5jm