углами - Как работают треугольники CSS?




треугольник с обводкой css (12)

CSS Треугольники: трагедия в пяти действиях

Как сказал alex , границы одинаковой ширины торчат друг против друга под углом 45 градусов:

Когда у вас нет верхней границы, это выглядит так:

Затем вы даете ему ширину 0 ...

... и высотой 0 ...

... и, наконец, вы делаете две стороны прозрачными:

Это приводит к треугольнику.

В CSS Tricks есть множество различных форм CSS - Формы CSS, и я особенно озадачен треугольником:

#triangle-up {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
<div id="triangle-up"></div>

Как и почему это работает?


Треугольный смеситель SASS (SCSS)

Я написал это, чтобы упростить (и DRY) автоматическое создание треугольника CSS:

// Triangle helper mixin (by Yair Even-Or)
// @param {Direction} $direction - either `top`, `right`, `bottom` or `left`
// @param {Color} $color [currentcolor] - Triangle color
// @param {Length} $size [1em] - Triangle size
@mixin triangle($direction, $color: currentcolor, $size: 1em) {
  $size: $size/2;
  $transparent: rgba($color, 0);
  $opposite: (top:bottom, right:left, left:right, bottom:top);

  content: '';
  display: inline-block;
  width: 0;
  height: 0;
  border: $size solid $transparent;
  border-#{map-get($opposite, $direction)}-color: $color;
  margin-#{$direction}: -$size;
}

пример использования:

span {
  @include triangle(bottom, red, 10px);
}

Игровая площадка

Важная заметка:
если треугольник кажется пиксельным в некоторых браузерах, попробуйте один из способов, описанных here .



Вот анимация в JSFiddle, которую я создал для демонстрации.

Также см. Ниже фрагмент.

Это Анимированный GIF, сделанный из Screencast

transforms = [
         {'border-left-width'   :'30', 'margin-left': '70'},
         {'border-bottom-width' :'80'},
         {'border-right-width'  :'30'},
         {'border-top-width'    :'0', 'margin-top': '70'},
         {'width'               :'0'},
         {'height'              :'0', 'margin-top': '120'},
         {'borderLeftColor'     :'transparent'},
         {'borderRightColor'    :'transparent'}
];


$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
		  for ( var i=0; i < transforms.length; i++ ) {
        $(this)
         .animate(transforms[i], duration)
		  }
    }).end()
}(jQuery))
.border {
    margin: 20px 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>

Случайная статья

/**
 * Randomize array element order in-place.
 * Using Durstenfeld shuffle algorithm.
 */
function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}

transforms = [
         {'border-left-width'   :'30', 'margin-left': '70'},
         {'border-bottom-width' :'80'},
         {'border-right-width'  :'30'},
         {'border-top-width'    :'0', 'margin-top': '70'},
         {'width'               :'0'},
         {'height'              :'0'},
         {'borderLeftColor'     :'transparent'},
         {'borderRightColor'    :'transparent'}
];
transforms = shuffleArray(transforms)



$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
		  for ( var i=0; i < transforms.length; i++ ) {
        $(this)
         .animate(transforms[i], duration)
		  }
    }).end()
}(jQuery))
.border {
    margin: 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>

Все сразу версия

$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
        $(this)
         .animate({'border-top-width': 0            ,
         					 'border-left-width': 30          ,
         					 'border-right-width': 30         ,
         					 'border-bottom-width': 80        ,
         					 'width': 0                       ,
         					 'height': 0                      ,
                   'margin-left': 100,
                   'margin-top': 150,
         					 'borderTopColor': 'transparent',
         					 'borderRightColor': 'transparent',
         					 'borderLeftColor':  'transparent'}, duration)
    }).end()
}(jQuery))
.border {
    margin: 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>


Допустим, у нас есть следующий div:

<div id="triangle" />

Теперь отредактируйте CSS шаг за шагом, чтобы вы поняли, что происходит вокруг

ШАГ 1: JSfiddle Ссылка:

 #triangle {
        background: purple;
        width :150px;
        height:150PX;
        border-left: 50px solid black ;
        border-right: 50px solid black;
        border-bottom: 50px solid black;
        border-top: 50px solid black;
    }

Это простой div. С очень простым CSS. Так что непрофессионал может понять. Div имеет размеры 150 x 150 пикселей с границей 50 пикселей. Изображение прилагается:

ШАГ 2: JSfiddle Ссылка:

#triangle {
    background: purple;
    width :150px;
    height:150PX;
    border-left: 50px solid yellow ;
    border-right: 50px solid green;
    border-bottom: 50px solid red;
    border-top: 50px solid blue;
}

Теперь я только что изменил пограничный цвет всех четырех сторон. Изображение прилагается.

ШАГ: 3 JSfiddle Ссылка:

#triangle {
    background: purple;
    width :0;
    height:0;
    border-left: 50px solid yellow ;
    border-right: 50px solid green;
    border-bottom: 50px solid red;
    border-top: 50px solid blue;
}

Теперь я просто изменил высоту и ширину div от 150 пикселей до нуля. Изображение прикреплено

ШАГ 4: JSfiddle:

#triangle {
    background: purple;
    width :0px;
    height:0px;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid red;
    border-top: 50px solid transparent;
}

Теперь я сделал все границы прозрачными, кроме нижней границы. Изображение приведено ниже.

ШАГ 5: JSfiddle Ссылка:

#triangle {
    background: white;
    width :0px;
    height:0px;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid red;
    border-top: 50px solid transparent;
}

Теперь я просто изменил цвет фона на белый. Изображение прилагается.

Следовательно, мы получили необходимый нам треугольник.


Другие уже объяснили это хорошо. Позвольте мне дать вам анимацию, которая будет объяснять это быстро: http://codepen.io/chriscoyier/pen/lotjh

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

HTML:

<html>
  <body>
    <div id="border-demo">
    </div>
  </body>
</html>

CSS:

/*border-width is border thickness*/
#border-demo {
    background: gray;
    border-color: yellow blue red green;/*top right bottom left*/
    border-style: solid;
    border-width: 25px 25px 25px 25px;/*top right bottom left*/
    height: 50px;
    width: 50px;
}

Играйте с этим и посмотрите, что произойдет. Установите высоту и ширину в ноль. Затем удалите верхнюю границу и сделайте левую и правую прозрачными или просто посмотрите на код ниже, чтобы создать треугольник css:

#border-demo {
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 100px solid blue;
}

Почти все ответы сосредоточены на треугольнике, построенном с использованием рамки, поэтому я собираюсь разработать метод linear-gradient (как было начато в ответ @lima_fil ).

Использование значения градуса, такого как 45° , заставит нас соблюдать конкретное соотношение height/width , чтобы получить желаемый треугольник, и это не будет реагировать:

.tri {
  width:100px;
  height:100px;
  background:linear-gradient(45deg, transparent 50%,red 0);
  
  /*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.8%,red 50%);
  border:1px solid;
  animation:change 2s linear infinite alternate;
}
.tri-2 {
  background:linear-gradient(to top right, transparent 49.8%,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.8%,red 50%),
  linear-gradient(to bottom left, transparent 49.8%,red 50%);
  background-size:50.5% 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.8%,red 50%),
  linear-gradient(to bottom left, transparent 49.8%,red 50%);
  background-size:calc(var(--w)/2 + 0.5%)  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 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);

  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));
  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: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>


Разный подход. С линейным градиентом (для IE, только IE 10+). Вы можете использовать любой угол:

.triangle {
    margin: 50px auto;
    width: 100px;
    height: 100px;
/* linear gradient */
    background: -moz-linear-gradient(-45deg,  rgba(255,0,0,0) 0%, rgba(255,0,0,0) 50%, rgba(255,0,0,1) 50%, rgba(255,0,0,1) 100%);
 /* FF3.6+ */
    background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,1)), color-stop(100%,rgba(255,0,0,1)));
 /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* Opera 11.10+ */
    background: -ms-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* IE10+ */
    background: linear-gradient(135deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* W3C */;
}
<div class="triangle"></div>

Вот jsfiddle


Рассмотрим ниже треугольник

.triangle {
    border-bottom:15px solid #000;
    border-left:10px solid transparent;
    border-right:10px solid transparent;
    width:0;
    height:0;
}

Это то, что нам дано:

Почему это получилось в такой форме? На приведенной ниже диаграмме объясняются размеры, обратите внимание, что 15px использовался для нижней границы, а 10px использовался для левого и правого.

Очень легко сделать прямоугольный треугольник, также удалив правильную границу.


Сделав еще один шаг, используя css на основе этого, я добавил стрелки в свою спину и следующие кнопки (да, я знаю, что это не 100% кросс-браузер, но, тем не менее, пятно).

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
  margin:20px auto;
}

.triangle-down {
  border-bottom:none;
  border-top: 100px solid red;
}

.triangle-left {
  border-left:none;
  border-right: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-right {
  border-right:none;
  border-left: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-after:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid red;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-after-right:after {
  border-right:none;
  border-left: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}

.triangle-before:before {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid blue;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-before-left:before {
  border-left:none;
  border-right: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}
<div class="triangle"></div>
<div class="triangle triangle-down"></div>
<div class="triangle triangle-left"></div>
<div class="triangle triangle-right"></div>

<a class="triangle-before triangle-before-left" href="#">Back</a>
<a class="triangle-after triangle-after-right" href="#">Next</a>


вот еще одна скрипка:

.container:after {
    position: absolute;
    right: 0;
    content: "";
    margin-right:-50px;
    margin-bottom: -8px;
    border-width: 25px;
    border-style: solid;
    border-color: transparent transparent transparent #000;
    width: 0;
    height: 0;
    z-index: 10;
    -webkit-transition: visibility 50ms ease-in-out,opacity 50ms ease-in-out;
    transition: visibility 50ms ease-in-out,opacity 50ms ease-in-out;
    bottom: 21px;
}
.container {
    float: left;
    margin-top: 100px;
    position: relative;
    width: 150px;
    height: 80px;
    background-color: #000;
}

.containerRed {
    float: left;
    margin-top: 100px;
    position: relative;
    width: 100px;
    height: 80px;
    background-color: red;
}

https://jsfiddle.net/qdhvdb17/


ОК, этот треугольник будет создан из-за того, как границы элементов работают вместе в HTML и CSS ...

Поскольку мы обычно используем границы 1 или 2px, мы никогда не замечаем, что границы имеют угол 45 ° друг к другу с одинаковой шириной, и если ширина изменяется, степень угла также изменяется, запустите код CSS, который я создал ниже:

.triangle {
  width: 100px;
  height: 100px;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
<div class="triangle">
</div>

Затем на следующем шаге у нас нет ширины и высоты, что-то вроде этого:

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
<div class="triangle">
</div>

И теперь мы делаем левую и правую границы невидимыми, чтобы сделать наш желательный треугольник, как показано ниже:

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
<div class="triangle"></div>

Если вы не хотите запускать фрагмент, чтобы увидеть шаги, я создал последовательность изображений, чтобы посмотреть все шаги на одном изображении:







css-shapes