TL; DR
При использовании градиента размер изображения равен размеру элемента.border-width-image
определит 9 областей, в которые мы поместим срезы (если не определено, используется border-width
).border-image-slice
рассмотрит исходное изображение для создания срезов.Значение без единиц измерения рассматривается как значение в пикселях, а процентное значение разрешается в зависимости от размера элемента.
Чтобы получить идеальный результат, мы должны иметь срезов, равных областям , и для этого мыдолжен иметь border-slice-image
равный border-width-image
(или border-width
) при использовании без юнита.Используя процент, вычисленное значение должно быть таким же.
В вашем случае 80
в срезе означает 80px
, и у вас есть граница 5em
, которая равна 5x16px = 80px
Давайте рассмотрим простой пример.
div {
width: 100px;
height: 100px;
display: inline-block;
border: 10px solid transparent;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 50 fill;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
Выше я попытался создать два div с одинаковым выводом, используя разные методы (фон и граница).Обратите внимание, что во втором примере я использую ключевое слово fill
, и я указал border-width-image
, отличный от ширины границы, и использовал срез, равный ширине этой границы.
Обратите внимание, что 50
в срезездесь рассматривается как пиксель, поскольку мы имеем дело с не векторным изображением (градиент).
Числа представляют пиксели в изображении (если изображение является растровым изображением) или векторные координаты (если изображение является векторнымобраз). ref
Давайте удалим свойство fill:
div {
width: 100px;
height: 100px;
display: inline-block;
border: 10px solid transparent;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 50;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
Ключевое слово fill, если присутствует, обеспечивает сохранение средней части изображения границы.(По умолчанию оно отбрасывается, т. Е. Обрабатывается как пустое.) ref
По умолчанию изображение границы не отображается в середине, а толькона границе.Из примера видно, что на каждой стороне есть 50px
с нашей настраиваемой рамкой, как определено border-image-width
. И если мы не укажем border-image-width
, то значением по умолчанию будет 1
, котороеозначает
Числа представляют собой кратные числа соответствующих вычисленных border-width
.
Так что либо мы явно указываем border-image-width
, либо просто используем border-width
в качестве ссылки.В большинстве случаев требуется только border-width
, поскольку в большинстве случаев мы хотим покрыть только область границы, но не более.
Теперь фрагмент будет разделять изображение на 9 частей
Это свойство определяет смещение внутрь от верхнего, правого, нижнего и левого краев изображения, разделяя его на девять областей: четыре угла , четыре края и a middle
ref
Вот шаги, которые будут лучшепокажите, как это делается для нашего примера:
div {
width: 100px;
height: 100px;
border: solid 10px transparent;
display: inline-block;
position: relative;
}
div:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(green,green) left 0 top 50px/100% 1px no-repeat,
linear-gradient(green,green) left 0 bottom 50px/100% 1px no-repeat,
linear-gradient(green,green) top 0 left 50px/1px 100% no-repeat,
linear-gradient(green,green) top 0 right 50px/1px 100% no-repeat;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 50;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
Левое изображение - это оригинальное изображение, которое мы делим на 9 частей, а затем помещаем каждое в 9 областей правого.Средний пустой, потому что мы не использовали заливку.В этом примере мы ничего не заметим, потому что срезы соответствуют областям.
Теперь давайте уменьшим срез до 25
:
div {
width: 100px;
height: 100px;
border: solid 10px transparent;
display: inline-block;
position: relative;
}
div.box:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(blue,blue) left 0 top 25px/100% 1px no-repeat,
linear-gradient(blue,blue) left 0 bottom 25px/100% 1px no-repeat,
linear-gradient(blue,blue) top 0 left 25px/1px 100% no-repeat,
linear-gradient(blue,blue) top 0 right 25px/1px 100% no-repeat;
}
div.border:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat,
linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat,
linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat,
linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 25;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
Это немного сложно, но применима та же логика.С левого изображения мы вырезали, используя 25px
, формируем каждую сторону, чтобы получить нашу 9-ю часть, которую мы поместим в правую часть, где ширина границы все еще такая же (50px
).Вы можете четко заметить, как детали в углах просто масштабируются, а края искривляются.
В каждом углу мы используем изображение 25px 25px
внутри области 50px 50px
и в верхнем крае, например, мы используем изображение 60px 25px
внутри области 10px 50px
.
Вы также можете определить разные значения для каждой стороны, чтобы иметь что-то вроде ниже:
div {
width: 100px;
height: 100px;
border: solid 10px transparent;
display: inline-block;
position: relative;
}
div.box:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(blue, blue) left 0 top 20px/100% 1px no-repeat,
linear-gradient(blue, blue) left 0 bottom 30px/100% 1px no-repeat,
linear-gradient(blue, blue) top 0 left 20px/1px 100% no-repeat,
linear-gradient(blue, blue) top 0 right 60px/1px 100% no-repeat;
}
div.border:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat,
linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat,
linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat,
linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px);
border-image-slice: 20 60 20 30;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
Теперь стало более понятно, как мы разрезаем изображение, а затем помещаем их в другую область, масштабируя их растягивая.Также ясно, что наилучшим значением является наличие срезов во всех сторонах, равных ширине границы, что имеет место в вашем примере, поскольку 5em
равно 5x16px = 80px
, таким образом, срез 80
Из спецификации мы также можем прочитать:
Области, заданные значениями border-image-slice, могут перекрываться.Однако если сумма правой и левой ширины равна или больше ширины изображения, изображения для верхнего и нижнего края и средней части будут пустыми, что будет иметь тот же эффект, как если бы непустое прозрачное изображение былоуказано для тех частей.Аналогично для верхнего и нижнего значений.
Если вы укажете левый и правый срез больше ширины изображения, то по логике вы не получите ничего для верхней / нижней / средней части:
div {
width: 100px;
height: 100px;
border: solid 10px transparent;
display: inline-block;
position: relative;
}
div.box:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(blue, blue) left 0 top 20px/100% 1px no-repeat,
linear-gradient(blue, blue) left 0 bottom 30px/100% 1px no-repeat,
linear-gradient(blue, blue) top 0 left 60px/1px 100% no-repeat,
linear-gradient(blue, blue) top 0 right 60px/1px 100% no-repeat;
}
div.border:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat,
linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat,
linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat,
linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px);
border-image-slice: 20 60 20 60;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
Та же логика применима и к верху / низу.
Вот пример, где у нас будут только углы
div {
width: 100px;
height: 100px;
border: solid 10px transparent;
display: inline-block;
position: relative;
}
div.box:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(blue, blue) left 0 top 20px/100% 1px no-repeat,
linear-gradient(blue, blue) left 0 bottom 100px/100% 1px no-repeat,
linear-gradient(blue, blue) top 0 left 60px/1px 100% no-repeat,
linear-gradient(blue, blue) top 0 right 60px/1px 100% no-repeat;
}
div.border:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(green, green) left 0 top 50px/100% 1px no-repeat,
linear-gradient(green, green) left 0 bottom 50px/100% 1px no-repeat,
linear-gradient(green, green) top 0 left 50px/1px 100% no-repeat,
linear-gradient(green, green) top 0 right 50px/1px 100% no-repeat;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px);
border-image-slice: 20 60 100 60;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>
Использование процентного значения также даст тот же результат.Нам просто нужно найти ссылку, и поскольку мы имеем дело с градиентом, размер градиента - это просто размер элемента.Срез 50
в нашем примере равен 41.666%
, поскольку ширина / высота равна 100px 2 * 10px = 120px
div {
width: 100px;
height: 100px;
border: solid 10px transparent;
display: inline-block;
position: relative;
}
div:before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background:
linear-gradient(blue, blue) left 0 top 50px/100% 1px no-repeat,
linear-gradient(blue, blue) left 0 bottom 50px/100% 1px no-repeat,
linear-gradient(blue, blue) top 0 left 50px/1px 100% no-repeat,
linear-gradient(blue, blue) top 0 right 50px/1px 100% no-repeat;
}
div.box {
background: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) border-box, red;
}
div.border {
border-image: repeating-linear-gradient(45deg, #000, #000 5px, transparent 5px, transparent 10px) 41.666%;
border-image-width: 50px;
background: red;
}
<div class="box"></div>
<div class="border"></div>