Если вы хотите применить границу к треугольнику, прочитайте это: Создать треугольник с помощью CSS?
Почти все ответы сосредоточены на треугольнике, построенном с использованием рамки, поэтому я собираюсь разработать linear-gradient
метод (как и началось в ответе @lima_fil ).
Использование значения степени как 45°
заставит нас уважать определенное соотношение height/width
, чтобы получить желаемый треугольник, и это не будет отзывчивым:
.tri {
width:100px;
height:100px;
background:linear-gradient(45deg, transparent 49.5%,red 50%);
/*To illustrate*/
border:1px solid;
}
Good one
<div class="tri"></div>
bad one
<div class="tri" style="width:150px"></div>
bad one
<div class="tri" style="height:30px"></div>
Вместо того, чтобы делать это, мы должны рассмотреть предопределенные значения направления, такие как to bottom
, to top
и т. Д. В этом случае мы можем получить любую форму треугольника, сохраняя его отзывчивость.
1) Прямоугольный треугольник
Для получения такого треугольника , нам нужно один линейного градиент и-диагональное направление , как to bottom right
, to top left
, to bottom left
, и т.д.
.tri-1,.tri-2 {
display:inline-block;
width:100px;
height:100px;
background:linear-gradient(to bottom left, transparent 49.5%,red 50%);
border:1px solid;
animation:change 2s linear infinite alternate;
}
.tri-2 {
background:linear-gradient(to top right, transparent 49.5%,red 50%);
border:none;
}
@keyframes change {
from {
width:100px;
height:100px;
}
to {
height:50px;
width:180px;
}
}
<div class="tri-1"></div>
<div class="tri-2"></div>
2) равнобедренный треугольник
Для этого нам понадобятся 2 линейных градиента, как указано выше, и каждый из них займет половину ширины (или высоты). Как будто мы создаем зеркальное отражение первого треугольника.
.tri {
display:inline-block;
width:100px;
height:100px;
background-image:
linear-gradient(to bottom right, transparent 49.5%,red 50%),
linear-gradient(to bottom left, transparent 49.5%,red 50%);
background-size:50.3% 100%; /* I use a value slightly bigger than 50% to avoid having a small gap between both gradient*/
background-position:left,right;
background-repeat:no-repeat;
animation:change 2s linear infinite alternate;
}
@keyframes change {
from {
width:100px;
height:100px;
}
to {
height:50px;
width:180px;
}
}
<div class="tri"></div>
3) равносторонний треугольник
С этим немного сложно справиться, так как нам нужно поддерживать соотношение между высотой и шириной градиента. У нас будет тот же треугольник, что и выше, но мы усложним вычисление, чтобы преобразовать равнобедренный треугольник в равносторонний.
Чтобы упростить это, мы будем считать, что ширина нашего div известна, а высота достаточно велика, чтобы можно было нарисовать наш треугольник внутри ( height >= width
).
У нас есть два градиента, g1
а g2
синяя линия - это ширина, div
w
и каждый градиент будет иметь 50% ( w/2
), и каждая сторона треугольника должна быть равна w
. Зеленая линия - высота обоих градиентов, hg
и мы можем легко получить формулу ниже:
(w/2)² + hg² = w²
---> hg = (sqrt(3)/2) * w
--->hg = 0.866 * w
Мы можем положиться на то calc()
, чтобы сделать наш расчет и получить нужный результат:
.tri {
--w:100px;
width:var(--w);
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 49.5%,red 50%),
linear-gradient(to bottom left, transparent 49.5%,red 50%);
background-size:calc(var(--w)/2 + 0.5px) calc(0.866 * var(--w));
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>
Другой способ - контролировать высоту div и сохранять синтаксис градиента легким:
.tri {
--w:100px;
width:var(--w);
height:calc(0.866 * var(--w));
display:inline-block;
background:
linear-gradient(to bottom right, transparent 49.8%,red 50%) left,
linear-gradient(to bottom left, transparent 49.8%,red 50%) right;
background-size:50.2% 100%;
background-repeat:no-repeat;
}
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>
4) Случайный треугольник
Чтобы получить случайный треугольник, это легко, так как нам просто нужно удалить условие 50% каждого из них, НО мы должны сохранить два условия (оба должны иметь одинаковую высоту, а сумма ширины должна составлять 100%).
.tri-1 {
width:100px;
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 50%,red 0),
linear-gradient(to bottom left, transparent 50%,red 0);
background-size:20% 60%,80% 60%;
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri-1"></div>
Но что, если мы хотим определить значение для каждой стороны? Нам просто нужно сделать расчет еще раз!
Давайте определим hg1
и hg2
как высоту нашего градиента (оба равны красной линии) тогда wg1
и wg2
как ширину нашего градиента ( wg1 + wg2 = a
). Я не буду вдаваться в подробности расчетов, но в конце мы получим:
wg2 = (a²+c²-b²)/(2a)
wg1 = a - wg2
hg1 = hg2 = sqrt(b² - wg1²) = sqrt(c² - wg2²)
Теперь мы достигли предела CSS, так как даже с этим calc()
мы не сможем реализовать это, поэтому нам просто нужно собрать конечный результат вручную и использовать его как фиксированный размер:
.tri {
--wg1: 20px;
--wg2: 60px;
--hg:30px;
width:calc(var(--wg1) + var(--wg2));
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 49.5%,red 50%),
linear-gradient(to bottom left, transparent 49.5%,red 50%);
background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri" ></div>
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>
бонус
Мы не должны забывать, что мы также можем применять вращение и / или наклон, и у нас есть больше возможностей, чтобы получить больше треугольника:
.tri {
--wg1: 20px;
--wg2: 60px;
--hg:30px;
width:calc(var(--wg1) + var(--wg2) - 0.5px);
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 49%,red 50%),
linear-gradient(to bottom left, transparent 49%,red 50%);
background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri" ></div>
<div class="tri" style="transform:skewY(25deg)"></div>
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;transform:rotate(20deg)" ></div>
И, конечно, мы должны иметь в виду решение SVG, которое может быть более подходящим в некоторых ситуациях:
svg {
width:100px;
height:100px;
}
polygon {
fill:red;
}
<svg viewBox="0 0 100 100"><polygon points="0,100 0,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,23 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="20,60 50,43 80,100" /></svg>