Если вы хотите применить границу к треугольнику, прочитайте это: Создать треугольник с помощью 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>